Advertisement
Guest User

wavwrite.c

a guest
Jun 18th, 2018
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.77 KB | None | 0 0
  1. #include "wavreader.h"
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <math.h>
  5.  
  6. #define WAV_PCM 1
  7. #define WAV_FMTLEN 16
  8.  
  9. //#define DEBUG
  10.  
  11. struct WavHeader * readWaveHeader(FILE *fh)
  12. {
  13.     struct WavHeader * header;
  14.     header = malloc(sizeof(struct WavHeader));
  15.     fread(header, sizeof(struct WavHeader), 1, fh);
  16.     return header;
  17. }
  18.  
  19. struct WavHeader * createWaveHeader (uint16_t channels, uint32_t samplerate, uint16_t bits)
  20. {
  21.     struct WavHeader * header;
  22.     header = malloc(sizeof(struct WavHeader));
  23.     header->iChannels = channels;
  24.     header->iSampleRate = samplerate;
  25.     header->iBitsPerSample = bits;
  26.     strncpy(header->cData, "data", 4);
  27.     strncpy(header->cRiff, "RIFF", 4);
  28.     strncpy(header->cFmtMarker, "fmt ", 4);
  29.     strncpy(header->cWaveMark, "WAVE", 4);
  30.     header->uiFileSize = 36;
  31.     header->iFmtLen = WAV_FMTLEN;
  32.     header->iFmtType = WAV_PCM;
  33.     header->iDataSize = 0;
  34.     header->iByteRate = samplerate * (bits/8) * channels;
  35.     header->iAlignment = (bits/8) * channels;
  36.     return header;
  37. }
  38.  
  39. void printWaveHeader (struct WavHeader * header)
  40. {
  41.     char tempStr[20];
  42.     strncpy(tempStr, header->cRiff, sizeof(header->cRiff));
  43.     printf("RIFF = %s\n", tempStr);
  44.     printf("Size of File = %d Bytes\n", header->uiFileSize);
  45.     strncpy(tempStr, header->cWaveMark, sizeof(header->cWaveMark));
  46.     printf("WAVE = %s\n", tempStr);
  47.     strncpy(tempStr, header->cFmtMarker, sizeof(header->cFmtMarker));
  48.     printf("FormatMark = %s\n", tempStr);
  49.     printf("Rest Data in Format = %d Bytes\n", header->iFmtLen );
  50.     printf("Format Type = %d \n", header->iFmtType);
  51.     printf("Number of Channels = %d \n", header->iChannels);
  52.     printf("Samplerate = %d Hz \n", header->iSampleRate);
  53.     printf("Byterate = %d Bps \n", header->iByteRate);
  54.     printf("Framesize = %d Bytes pro Frame \n", header->iAlignment);
  55.     printf("Bits per Sample = %d bits \n", header->iBitsPerSample);
  56.     strncpy(tempStr, header->cData, sizeof(header->cData));
  57.     printf("DATA = %s \n", tempStr);
  58.     printf("Data Segment Size = %d Bytes \n", header->iDataSize);
  59. }
  60.  
  61. void _int8ToDouble(char * buffer, int buflen, double *output)
  62. {
  63.     int i;
  64.     for (i = 0; i < buflen; ++i)
  65.     {
  66.         output[i] = 1.0 * buffer[i] / ((1 << 7) - 1); // convert to double, int8 means 2^-7 ~ (2^7-1)
  67.     }
  68.  
  69. }
  70.  
  71. void _int16ToDouble(char * buffer, int buflen, double *output)
  72. {
  73.     int i;
  74.     int16_t temp;
  75.     int16_t iMax;
  76.  
  77.     iMax = (1 << (16-1)) - 1; // maximun for int16
  78.  
  79.     for (i = 0; i < buflen/2; ++i) // because buflen is byte number buflen/2 = length in int16
  80.     {
  81.         temp = (buffer[i*2+1] << 8) | (buffer[i*2]); // its little endian
  82.         output[i] = 1.0 * temp / iMax;
  83. #ifdef DEBUG
  84.  
  85.         printf("%02x %02x\t%04x\t%.5f\n",buffer[i*2+1],buffer[i*2], temp,output[i]);
  86.  
  87. #endif // DEBUG
  88.  
  89.     }
  90.  
  91. }
  92.  
  93. void _int32ToDouble(char *buffer, int buflen, double *output)
  94. {
  95.     int i;
  96.     int32_t temp;
  97.     int32_t iMax;
  98.  
  99.     iMax = (1 << (32 - 1)) - 1; // Max Int32
  100.  
  101.     for (i = 0; i < buflen/4; ++i) //buflen in int32 = buflen in byte / 4
  102.     {
  103.         temp = (buffer[i*4+3] << 24) | (buffer[i*4+2] << 16)
  104.                | (buffer[i*4+1] << 8) | (buffer[i*4]); // little endian
  105.         output[i] = 1.0 * temp / iMax;
  106.     }
  107.  
  108. }
  109.  
  110. int WaveReadFrame(FILE *fh, struct WavHeader * header,int iFrameSize, double *output)
  111. {
  112.     char buffer[iFrameSize * header->iChannels * (header->iBitsPerSample / 8)]; // buffer of raw data
  113.     int i,j;
  114.     int iBytesRead;
  115.     int64_t temp;
  116.     int byteLen = header->iBitsPerSample / 8;
  117.  
  118.  
  119.     if (!feof(fh))
  120.     {
  121.         iBytesRead = fread(buffer, sizeof(buffer[0]), sizeof(buffer), fh);
  122.         switch (byteLen)
  123.         {
  124.             case 1:
  125.                 {
  126.                     _int8ToDouble(buffer, iBytesRead, output);
  127.                     break;
  128.                 }
  129.             case 2:
  130.                 {
  131.                     _int16ToDouble(buffer, iBytesRead, output);
  132.                     break;
  133.                 }
  134.             case 4:
  135.                 {
  136.                     _int32ToDouble(buffer, iBytesRead, output);
  137.                     break;
  138.                 }
  139.         }
  140.         return iBytesRead;
  141.     }
  142.     else
  143.     {
  144.         return -1;
  145.     }
  146. }
  147.  
  148.  
  149. int _WaveWriteFrame8b(FILE *fh, struct WavHeader * header, int iFrameSize, double * frame)
  150. {
  151.     int i, iTotalLen;
  152.     int8_t *iFrame;
  153.     int8_t iMax;
  154.  
  155.     iMax = (1 << (sizeof(int8_t)*8-1)) - 1;
  156.     iTotalLen = iFrameSize * header->iChannels;
  157.     iFrame = malloc(sizeof(int8_t) * iFrameSize * header->iChannels);
  158.  
  159.     for (i = 0; i < iTotalLen; ++i)
  160.     {
  161.         iFrame[i] = (int8_t)trunc(frame[i] * iMax);
  162.     }
  163.  
  164.     return fwrite(iFrame, sizeof(iFrame[0]), iTotalLen, fh);
  165.  
  166. }
  167.  
  168. int _WaveWriteFrame16b(FILE *fh, struct WavHeader * header, int iFrameSize, double * frame)
  169. {
  170.     int i, iTotalLen;
  171.     int16_t *iFrame;
  172.     int16_t iMax;
  173.  
  174.     iMax = (1 << (sizeof(int16_t)*8-1)) - 1;
  175.     iTotalLen = iFrameSize * header->iChannels;
  176.     iFrame = malloc(sizeof(int16_t) * iFrameSize * header->iChannels);
  177.  
  178.     for (i = 0; i < iTotalLen; ++i)
  179.     {
  180.         iFrame[i] = (frame[i] * iMax);
  181.     }
  182.  
  183.     return fwrite(iFrame, sizeof(iFrame[0]), iTotalLen, fh);
  184.  
  185. }
  186.  
  187. int _WaveWriteFrame32b(FILE *fh, struct WavHeader * header, int iFrameSize, double * frame)
  188. {
  189.     int i, iTotalLen;
  190.     int32_t *iFrame;
  191.     int32_t iMax;
  192.  
  193.     iMax = (1 << (sizeof(int32_t)*8-1)) - 1;
  194.     iTotalLen = iFrameSize * header->iChannels;
  195.     iFrame = malloc(sizeof(int32_t) * iFrameSize * header->iChannels);
  196.  
  197.     for (i = 0; i < iTotalLen; ++i)
  198.     {
  199.         iFrame[i] = (int32_t)trunc(frame[i] * iMax);
  200.     }
  201.  
  202.     return fwrite(iFrame, sizeof(iFrame[0]), iTotalLen, fh);
  203.  
  204. }
  205.  
  206. int WaveWriteFrame(FILE *fh, struct WavHeader * header, int iFrameSize, double *frame)
  207. {
  208.     int iBytesWritten;
  209.     int iByteLen = header->iBitsPerSample / 8;
  210.     switch (iByteLen)
  211.     {
  212.         case 1:
  213.             {
  214.                 iBytesWritten = _WaveWriteFrame8b(fh, header, iFrameSize, frame);
  215.                 break;
  216.             }
  217.         case 2:
  218.             {
  219.                 iBytesWritten = _WaveWriteFrame16b(fh, header, iFrameSize, frame);
  220.                 break;
  221.             }
  222.         case 4:
  223.             {
  224.                 iBytesWritten = _WaveWriteFrame32b(fh, header, iFrameSize, frame);
  225.                 break;
  226.             }
  227.         default:
  228.             return -1;
  229.     }
  230.  
  231.     header->iDataSize = header->iDataSize + iBytesWritten*iByteLen;
  232.     header->uiFileSize = header->uiFileSize + iBytesWritten*iByteLen;
  233.  
  234.     return iBytesWritten;
  235.  
  236. }
  237.  
  238. void WaveWriteHeader(FILE *fh, struct WavHeader * header)
  239. {
  240.     int currentPos;
  241.  
  242.     currentPos = ftell(fh);
  243.     rewind(fh);
  244.  
  245.     fwrite(header, sizeof(struct WavHeader), 1, fh);
  246.  
  247.     fseek(fh, 0, currentPos);
  248. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement