/******************************************************************************/ /* Speicher, Laden und Erzeugen von WAV und PCM Dateien /* /* Datum : 27.03.2002 /* Autor : Jens Ahrensfeld /* Datei : wav.c /* /******************************************************************************/ #include #include #include #include "wav.h" /******************************************************************************/ /* C definitions /******************************************************************************/ void WavInit(struct _sWAV *pObj, uint32_t nSamplesPerSec, uint16_t nBits, uint16_t nChannels, uint16_t format) { WavSetFormat(pObj, nSamplesPerSec, nBits, nChannels, format); pObj->m_FileType = FILETYPE_RAW; pObj->m_FileSize = 0; pObj->m_HeaderSize = 0; pObj->m_DataSize = 0; pObj->pHndWavFile = 0; pObj->m_numSamples = 0; } /******************************************************************************/ uint32_t WavSetFormat(struct _sWAV *pObj, uint32_t nSamplesPerSec, uint16_t nBits, uint16_t nChannels, uint16_t format) { pObj->m_Format.wFormatTag = format; pObj->m_Format.nChannels = nChannels; pObj->m_Format.wBitsPerSample = nBits; pObj->m_Format.nBlockAlign = (nChannels * nBits)/ 8; pObj->m_Format.nSamplesPerSec = nSamplesPerSec; pObj->m_Format.nAvgBytesPerSec = (uint32_t)pObj->m_Format.nBlockAlign * nSamplesPerSec; pObj->m_Format.cbSize = 0; pObj->m_nChannels = pObj->m_Format.nChannels; pObj->m_SampleRate = pObj->m_Format.nSamplesPerSec; pObj->m_nBits = pObj->m_Format.wBitsPerSample; return 0; } /******************************************************************************/ uint32_t WavOpen (struct _sWAV *pObj, const char* FileName) { uint32_t stat; //Wav-File �ffnen strcpy(pObj->m_Name, FileName); if (strlen(FileName) < 1) return -1; pObj->pHndWavFile = fopen (pObj->m_Name,"rb"); if (pObj->pHndWavFile == 0) return -1; stat=ReadHeader(pObj); if (stat != 0) { pObj->m_FileType = FILETYPE_RAW; fseek(pObj->pHndWavFile, 0L, SEEK_END); pObj->m_DataSize = ftell(pObj->pHndWavFile); pObj->m_FileSize = pObj->m_DataSize; pObj->m_numSamples = pObj->m_DataSize/pObj->m_Format.nBlockAlign; fseek(pObj->pHndWavFile, 0L, SEEK_SET); pObj->WREAD = 1; return 0; } pObj->m_numSamples = pObj->m_DataSize /pObj->m_Format.nBlockAlign; pObj->m_FileType = FILETYPE_WAV; pObj->WREAD = 1; return 0; } /******************************************************************************/ uint32_t WavClose(struct _sWAV *pObj) { if (!pObj->WREAD && (pObj->m_FileType == FILETYPE_WAV)) WriteHeader(pObj); fclose(pObj->pHndWavFile); return 0; } /******************************************************************************/ uint32_t WavCreate (struct _sWAV *pObj, char *fileName, uint32_t fileType) { pObj->m_FileType = fileType; strcpy(pObj->m_Name, fileName); //Wav-File �ffnen pObj->pHndWavFile = fopen (pObj->m_Name,"wb"); if (pObj->pHndWavFile == 0) return -1; pObj->WREAD = 0; if (pObj->m_FileType == FILETYPE_WAV) WriteHeader(pObj); return 0; } /******************************************************************************/ uint32_t WavRead(struct _sWAV *pObj, void *data, uint32_t nSamples) { int32_t count; count = fread(data, pObj->m_Format.nBlockAlign, nSamples, pObj->pHndWavFile); return count; } /******************************************************************************/ uint32_t WavWrite(struct _sWAV *pObj, void *data, uint32_t nSamples) { uint32_t count; fseek(pObj->pHndWavFile, 0L, SEEK_END); count = fwrite(data, pObj->m_Format.nBlockAlign, nSamples, pObj->pHndWavFile); pObj->m_DataSize = pObj->m_DataSize + count*pObj->m_Format.nBlockAlign; pObj->m_numSamples = count; pObj->m_FileSize = pObj->m_DataSize; if (pObj->m_FileType == FILETYPE_WAV) pObj->m_FileSize += pObj->m_HeaderSize + 20; return count; } /******************************************************************************/ uint32_t ReadHeader (struct _sWAV *pObj) { char buf[80]; int32_t err; // 1. 'RIFF' abpr�fen fread(buf, sizeof(char), 4,pObj->pHndWavFile); buf[4]=0; if (strcmp (buf,"RIFF")) return -1; // 2. FILESIZE ermitteln fread(&pObj->m_FileSize, sizeof(uint32_t), 1,pObj->pHndWavFile); // 3. 'WAVEfmt' abpr�fen fread(buf, sizeof(char), 8,pObj->pHndWavFile); buf[8]=0; if (strcmp (buf,"WAVEfmt ")) return -1; // 3. HeaderSize ermitteln fread(&pObj->m_HeaderSize, sizeof(pObj->m_HeaderSize), 1,pObj->pHndWavFile); // 4. Den ganzen Infoblock einlesen fread(&pObj->m_Format, pObj->m_HeaderSize, 1,pObj->pHndWavFile); // 5. 'data' abpr�fen fseek(pObj->pHndWavFile,(int32_t)(pObj->m_HeaderSize+20), SEEK_SET); err = -1; do { fread(buf, sizeof(char), 4, pObj->pHndWavFile); buf[4]=0; // 6. Datenl�nge ermitteln fread(&pObj->m_DataSize, sizeof(pObj->m_DataSize), 1,pObj->pHndWavFile); if (!strcmp (buf,"data")) { err = 0; break; } fseek(pObj->pHndWavFile,(int32_t)(pObj->m_DataSize), SEEK_CUR); } while (!feof(pObj->pHndWavFile)); pObj->m_nChannels = pObj->m_Format.nChannels; pObj->m_SampleRate = pObj->m_Format.nSamplesPerSec; pObj->m_nBits = pObj->m_Format.wBitsPerSample; return err; } /******************************************************************************/ uint32_t WriteHeader (struct _sWAV *pObj) { pObj->m_HeaderSize = bs; pObj->m_FileSize = pObj->m_HeaderSize + pObj->m_DataSize + 20; fseek(pObj->pHndWavFile,0L, SEEK_SET); // 1. 'RIFF' schreiben fwrite("RIFF",sizeof(char), 4, pObj->pHndWavFile); // 2. FILESIZE schreiben fwrite(&pObj->m_FileSize, sizeof(pObj->m_FileSize), 1, pObj->pHndWavFile); // 3. 'WAVEfmt ' schreiben fwrite("WAVEfmt ", sizeof(char), 8, pObj->pHndWavFile); // 3. HeaderSize schreiben fwrite(&pObj->m_HeaderSize, sizeof(pObj->m_HeaderSize), 1, pObj->pHndWavFile); // 4. Infoblock schreiben fwrite(&pObj->m_Format, pObj->m_HeaderSize, 1, pObj->pHndWavFile); // 5. 'data' schreiben fseek(pObj->pHndWavFile, (int32_t)(pObj->m_HeaderSize+20), SEEK_SET); fwrite("data",sizeof(char), 4, pObj->pHndWavFile); // 6. Datenl�nge schreiben fwrite(&pObj->m_DataSize, sizeof(pObj->m_DataSize), 1, pObj->pHndWavFile); return 0; } /******************************************************************************/ uint16_t WavGetnBits(struct _sWAV *pObj) { return pObj->m_Format.wBitsPerSample; } uint32_t WavGetRate(struct _sWAV *pObj) { return pObj->m_Format.nSamplesPerSec; } uint16_t WavGetnChannels(struct _sWAV *pObj) { return pObj->m_Format.nChannels; } char* WavGetFileName(struct _sWAV *pObj) { return pObj->m_Name; } void WavDeIlvd(struct _sWAV *pObj, int16_t *pIn, int16_t **ppOut, uint32_t len) { int j, nChannels; uint32_t i; nChannels = pObj->m_Format.nChannels; for (i=0; i < len; i++) { for (j=0; j < nChannels; j++) { ppOut[j][i] = *(pIn++); } } } void WavDeIlvdDouble(struct _sWAV *pObj, int16_t *pIn, double **ppOut, uint32_t len) { int j, nChannels, nBits; uint32_t i; double kNorm; nChannels = pObj->m_Format.nChannels; nBits = pObj->m_Format.wBitsPerSample; kNorm = 1.0/((1 << (nBits-1))-1); for (i=0; i < len; i++) { for (j=0; j < nChannels; j++) { ppOut[j][i] = (double)(*(pIn++) * kNorm); } } } void WavDeIlvdFloat(struct _sWAV *pObj, int16_t *pIn, float **ppOut, uint32_t len) { int j, nChannels, nBits; uint32_t i; float kNorm; nChannels = pObj->m_Format.nChannels; nBits = pObj->m_Format.wBitsPerSample; kNorm = 1.0f/((1 << (nBits-1))-1); for (i=0; i < len; i++) { for (j=0; j < nChannels; j++) { ppOut[j][i] = (float)(*(pIn++) * kNorm); } } } void WavIlvd(struct _sWAV *pObj, int16_t **ppIn, int16_t *pOut, uint32_t len) { int j, nChannels; uint32_t i; nChannels = pObj->m_Format.nChannels; for (i=0; i < len; i++) { for (j=0; j < nChannels; j++) { *(pOut++) = ppIn[j][i]; } } } void WavIlvdDouble(struct _sWAV *pObj, double **ppIn, int16_t *pOut, uint32_t len) { int j, nChannels, nBits; double kNorm; uint32_t i; nChannels = pObj->m_Format.nChannels; nBits = pObj->m_Format.wBitsPerSample; kNorm = (1 << (nBits-1))-1; for (i=0; i < len; i++) { for (j=0; j < nChannels; j++) { *(pOut++) = (int16_t)(ppIn[j][i] * kNorm); } } } void WavIlvdFloat(struct _sWAV *pObj, float **ppIn, int16_t *pOut, uint32_t len) { int j, nChannels, nBits; float kNorm; uint32_t i; nChannels = pObj->m_Format.nChannels; nBits = pObj->m_Format.wBitsPerSample; kNorm = (float)(1 << (nBits-1))-1; for (i=0; i < len; i++) { for (j=0; j < nChannels; j++) { *(pOut++) = (int16_t)(ppIn[j][i] * kNorm); } } }