commit b0d1ac60574bb5979205d289596ebfca0865d1f3 Author: Jens Ahrensfeld Date: Sat Jul 19 07:44:42 2014 +0000 Initial import git-svn-id: http://moon:8086/svn/software/trunk/libsrc/wav@1 b431acfa-c32f-4a4a-93f1-934dc6c82436 diff --git a/Wav.h b/Wav.h new file mode 100755 index 0000000..60c0505 --- /dev/null +++ b/Wav.h @@ -0,0 +1,83 @@ +/*************************************************************************/ +/* Speicher, Laden und Erzeugen von WAV und PCM Dateien +/* +/* Datum : 27.03.2002 +/* Autor : Jens Ahrensfeld +/* Datei : wav.h +/* +/*************************************************************************/ +#ifndef AVWAV_H +#define AVWAV_H + +#include +#define INT8 char +#define INT16 short +#define INT32 long +#define UINT8 unsigned char +#define UINT16 unsigned short +#define UINT32 unsigned long + +#define bs 18 +#define WAVE_FORMAT_PCM 1 +#define FILETYPE_RAW 0 +#define FILETYPE_WAV 1 + +/******************************************************************************/ +typedef struct _sWAVEHEADER +{ + UINT16 wFormatTag; + UINT16 nChannels; + UINT32 nSamplesPerSec; + UINT32 nAvgBytesPerSec; + UINT16 nBlockAlign; + UINT16 wBitsPerSample; + UINT16 cbSize; + +} WAVEHEADER; + + +/******************************************************************************/ +typedef struct _sWAV +{ + char m_Name[257]; + WAVEHEADER m_Format; + UINT32 m_DataSize, m_FileSize, m_HeaderSize, m_FileType, m_numSamples; + FILE *pHndWavFile; + UINT32 WREAD; + UINT16 m_nChannels; + UINT32 m_SampleRate; + UINT16 m_nBits; + +} WAV; +/******************************************************************************/ +/* Global Functions +/******************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +void WavInit(struct _sWAV*, UINT32 nSamplesPerSec, UINT16 nBits, UINT16 nChannels, UINT16 format); +UINT32 WavSetFormat(struct _sWAV*, UINT32, UINT16, UINT16, UINT16 format); +UINT32 WavOpen (struct _sWAV*, char*); +UINT32 WavCreate(struct _sWAV*, char*, UINT32); +UINT32 WavClose(struct _sWAV*); +UINT32 WavRead(struct _sWAV*, void*, UINT32); +UINT32 WavWrite(struct _sWAV*, void*, UINT32); +UINT32 ReadHeader(struct _sWAV*); +UINT32 WriteHeader(struct _sWAV*); +UINT16 WavGetnBits(struct _sWAV *pObj); +UINT32 WavGetRate(struct _sWAV *pObj); +UINT16 WavGetnChannels(struct _sWAV *pObj); +char* WavGetFileName(struct _sWAV *pObj); + +void WavDeIlvd(struct _sWAV *pObj, INT16 *pIn, INT16 **ppOut, UINT32 len); +void WavDeIlvdDouble(struct _sWAV *pObj, INT16 *pIn, double **ppOut, UINT32 len); +void WavDeIlvdFloat(struct _sWAV *pObj, INT16 *pIn, float **ppOut, UINT32 len); +void WavIlvd(struct _sWAV *pObj, INT16 **ppIn, INT16 *pOut, UINT32 len); +void WavIlvdDouble(struct _sWAV *pObj, double **ppIn, INT16 *pOut, UINT32 len); +void WavIlvdFloat(struct _sWAV *pObj, float **ppIn, INT16 *pOut, UINT32 len); + +#ifdef __cplusplus +} +#endif +#endif /* AVWAV_H */ diff --git a/wav.c b/wav.c new file mode 100755 index 0000000..bb2ea1c --- /dev/null +++ b/wav.c @@ -0,0 +1,348 @@ +/******************************************************************************/ +/* Speicher, Laden und Erzeugen von WAV und PCM Dateien +/* +/* Datum : 27.03.2002 +/* Autor : Jens Ahrensfeld +/* Datei : wav.c +/* +/******************************************************************************/ +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "wav.h" + +/******************************************************************************/ +/* C definitions +/******************************************************************************/ +void WavInit(struct _sWAV *pObj, UINT32 nSamplesPerSec, UINT16 nBits, UINT16 nChannels, UINT16 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 WavSetFormat(struct _sWAV *pObj, UINT32 nSamplesPerSec, UINT16 nBits, UINT16 nChannels, UINT16 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)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 WavOpen (struct _sWAV *pObj, char* FileName) +{ + UINT32 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 WavClose(struct _sWAV *pObj) +{ + if (!pObj->WREAD && (pObj->m_FileType == FILETYPE_WAV)) + WriteHeader(pObj); + + fclose(pObj->pHndWavFile); + return 0; +} + +/******************************************************************************/ +UINT32 WavCreate (struct _sWAV *pObj, char *fileName, UINT32 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 WavRead(struct _sWAV *pObj, void *data, UINT32 nSamples) +{ + INT32 count; + count = fread(data, pObj->m_Format.nBlockAlign, nSamples, pObj->pHndWavFile); + + return count; +} + +/******************************************************************************/ +UINT32 WavWrite(struct _sWAV *pObj, void *data, UINT32 nSamples) +{ + + UINT32 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 ReadHeader (struct _sWAV *pObj) +{ + char buf[80]; + INT32 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), 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)(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)(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 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)(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 WavGetnBits(struct _sWAV *pObj) +{ + return pObj->m_Format.wBitsPerSample; +} + +UINT32 WavGetRate(struct _sWAV *pObj) +{ + return pObj->m_Format.nSamplesPerSec; +} + +UINT16 WavGetnChannels(struct _sWAV *pObj) +{ + return pObj->m_Format.nChannels; +} + +char* WavGetFileName(struct _sWAV *pObj) +{ + return pObj->m_Name; +} + +void WavDeIlvd(struct _sWAV *pObj, INT16 *pIn, INT16 **ppOut, UINT32 len) +{ + int j, nChannels; + UINT32 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 *pIn, double **ppOut, UINT32 len) +{ + int j, nChannels, nBits; + UINT32 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 *pIn, float **ppOut, UINT32 len) +{ + int j, nChannels, nBits; + UINT32 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 **ppIn, INT16 *pOut, UINT32 len) +{ + int j, nChannels; + UINT32 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 *pOut, UINT32 len) +{ + int j, nChannels, nBits; + double kNorm; + UINT32 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)(ppIn[j][i] * kNorm); + } + } +} + +void WavIlvdFloat(struct _sWAV *pObj, float **ppIn, INT16 *pOut, UINT32 len) +{ + int j, nChannels, nBits; + float kNorm; + UINT32 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)(ppIn[j][i] * kNorm); + } + } +}