diff options
Diffstat (limited to 'arm-fm-22k/host_src/eas_wave.c')
-rw-r--r-- | arm-fm-22k/host_src/eas_wave.c | 423 |
1 files changed, 423 insertions, 0 deletions
diff --git a/arm-fm-22k/host_src/eas_wave.c b/arm-fm-22k/host_src/eas_wave.c new file mode 100644 index 0000000..02fed6e --- /dev/null +++ b/arm-fm-22k/host_src/eas_wave.c @@ -0,0 +1,423 @@ +/*----------------------------------------------------------------------------
+ *
+ * File:
+ * eas_wave.c
+ *
+ * Contents and purpose:
+ * This module contains .WAV file functions for the EAS synthesizer
+ * test harness.
+ *
+ * Copyright Sonic Network Inc. 2005
+ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *----------------------------------------------------------------------------
+ * Revision Control:
+ * $Revision: 658 $
+ * $Date: 2007-04-24 13:35:49 -0700 (Tue, 24 Apr 2007) $
+ *----------------------------------------------------------------------------
+*/
+
+/* lint complaints about most C library headers, so we use our own during lint step */
+#ifdef _lint
+#include "lint_stdlib.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#endif
+
+#include "eas_wave.h"
+
+/* .WAV file format tags */
+const EAS_U32 riffTag = 0x46464952;
+const EAS_U32 waveTag = 0x45564157;
+const EAS_U32 fmtTag = 0x20746d66;
+const EAS_U32 dataTag = 0x61746164;
+
+#ifdef _BIG_ENDIAN
+/*----------------------------------------------------------------------------
+ * FlipDWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a DWORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipDWord (EAS_U32 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U32 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (((((p[3] << 8) | p[2]) << 8) | p[1]) << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWord()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip a WORD for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWord (EAS_U16 *pValue)
+{
+ EAS_U8 *p;
+ EAS_U16 temp;
+
+ p = (EAS_U8*) pValue;
+ temp = (p[1] << 8) | p[0];
+ *pValue = temp;
+}
+
+/*----------------------------------------------------------------------------
+ * FlipWaveHeader()
+ *----------------------------------------------------------------------------
+ * Purpose: Endian flip the wave header for big-endian processors
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+static void FlipWaveHeader (WAVE_HEADER *p)
+{
+
+ FlipDWord(&p->nRiffTag);
+ FlipDWord(&p->nRiffSize);
+ FlipDWord(&p->nWaveTag);
+ FlipDWord(&p->nFmtTag);
+ FlipDWord(&p->nFmtSize);
+ FlipDWord(&p->nDataTag);
+ FlipDWord(&p->nDataSize);
+ FlipWord(&p->fc.wFormatTag);
+ FlipWord(&p->fc.nChannels);
+ FlipDWord(&p->fc.nSamplesPerSec);
+ FlipDWord(&p->fc.nAvgBytesPerSec);
+ FlipWord(&p->fc.nBlockAlign);
+ FlipWord(&p->fc.wBitsPerSample);
+
+}
+#endif
+
+/*----------------------------------------------------------------------------
+ * WaveFileCreate()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileCreate (const char *filename, EAS_I32 nChannels, EAS_I32 nSamplesPerSec, EAS_I32 wBitsPerSample)
+{
+ WAVE_FILE *wFile;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+ wFile->write = EAS_TRUE;
+
+ /* create the file */
+ wFile->file = fopen(filename,"wb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* initialize PCM format .WAV file header */
+ wFile->wh.nRiffTag = riffTag;
+ wFile->wh.nRiffSize = sizeof(WAVE_HEADER) - 8;
+ wFile->wh.nWaveTag = waveTag;
+ wFile->wh.nFmtTag = fmtTag;
+ wFile->wh.nFmtSize = sizeof(FMT_CHUNK);
+
+ /* initalize 'fmt' chunk */
+ wFile->wh.fc.wFormatTag = 1;
+ wFile->wh.fc.nChannels = (EAS_U16) nChannels;
+ wFile->wh.fc.nSamplesPerSec = (EAS_U32) nSamplesPerSec;
+ wFile->wh.fc.wBitsPerSample = (EAS_U16) wBitsPerSample;
+ wFile->wh.fc.nBlockAlign = (EAS_U16) (nChannels * (EAS_U16) (wBitsPerSample / 8));
+ wFile->wh.fc.nAvgBytesPerSec = wFile->wh.fc.nBlockAlign * (EAS_U32) nSamplesPerSec;
+
+ /* initialize 'data' chunk */
+ wFile->wh.nDataTag = dataTag;
+ wFile->wh.nDataSize = 0;
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* write the header */
+ if (fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file) != 1)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileCreate */
+
+/*----------------------------------------------------------------------------
+ * WaveFileWrite()
+ *----------------------------------------------------------------------------
+ * Purpose: Writes data to the wave file
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+EAS_I32 WaveFileWrite (WAVE_FILE *wFile, void *buffer, EAS_I32 n)
+{
+ EAS_I32 count;
+
+ /* make sure we have an open file */
+ if (wFile == NULL)
+ {
+ return 0;
+ }
+
+#ifdef _BIG_ENDIAN
+ {
+ EAS_I32 i;
+ EAS_U16 *p;
+ p = buffer;
+ i = n >> 1;
+ while (i--)
+ FlipWord(p++);
+ }
+#endif
+
+ /* write the data */
+ count = (EAS_I32) fwrite(buffer, 1, (size_t) n, wFile->file);
+
+ /* add the number of bytes written */
+ wFile->wh.nRiffSize += (EAS_U32) count;
+ wFile->wh.nDataSize += (EAS_U32) count;
+
+ /* return the count of bytes written */
+ return count;
+} /* end WriteWaveHeader */
+
+/*----------------------------------------------------------------------------
+ * WaveFileClose()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for writing and writes the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+EAS_BOOL WaveFileClose (WAVE_FILE *wFile)
+{
+ EAS_I32 count = 1;
+
+ /* return to beginning of file and write the header */
+ if (wFile->write)
+ {
+ if (fseek(wFile->file, 0L, SEEK_SET) == 0)
+ {
+
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ count = (EAS_I32) fwrite(&wFile->wh, sizeof(WAVE_HEADER), 1, wFile->file);
+#ifdef _BIG_ENDIAN
+ FlipWaveHeader(&wFile->wh);
+#endif
+ }
+ }
+
+ /* close the file */
+ if (fclose(wFile->file) != 0)
+ count = 0;
+
+ /* free the memory */
+ free(wFile);
+
+ /* return the file handle */
+ return (count == 1 ? EAS_TRUE : EAS_FALSE);
+} /* end WaveFileClose */
+
+#ifdef _WAVE_FILE_READ
+#ifdef _BIG_ENDIAN
+#error "WaveFileOpen not currently supported on big-endian processors"
+#endif
+/*----------------------------------------------------------------------------
+ * WaveFileOpen()
+ *----------------------------------------------------------------------------
+ * Purpose: Opens a wave file for reading and reads the header
+ *
+ * Inputs:
+ *
+ * Outputs:
+ *
+ *----------------------------------------------------------------------------
+*/
+
+WAVE_FILE *WaveFileOpen (const char *filename)
+{
+ WAVE_FILE *wFile;
+ struct
+ {
+ EAS_U32 tag;
+ EAS_U32 size;
+ } chunk;
+ EAS_U32 tag;
+ EAS_I32 startChunkPos;
+ EAS_INT state;
+ EAS_BOOL done;
+
+ /* allocate memory */
+ wFile = malloc(sizeof(WAVE_FILE));
+ if (!wFile)
+ return NULL;
+
+ /* open the file */
+ wFile->write = EAS_FALSE;
+ wFile->file = fopen(filename,"rb");
+ if (!wFile->file)
+ {
+ free(wFile);
+ return NULL;
+ }
+
+ /* make lint happy */
+ chunk.tag = chunk.size = 0;
+ startChunkPos = 0;
+
+ /* read the RIFF tag and file size */
+ state = 0;
+ done = EAS_FALSE;
+ while (!done)
+ {
+
+ switch(state)
+ {
+ /* read the RIFF tag */
+ case 0:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (chunk.tag != riffTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* read the WAVE tag */
+ case 1:
+ if (fread(&tag, sizeof(tag), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ if (tag != waveTag)
+ done = EAS_TRUE;
+ else
+ state++;
+ }
+ break;
+
+ /* looking for fmt chunk */
+ case 2:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not fmt tag, skip it */
+ if (chunk.tag != fmtTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ state++;
+ }
+ break;
+
+ /* read fmt chunk */
+ case 3:
+ if (fread(&wFile->wh.fc, sizeof(FMT_CHUNK), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ state++;
+ }
+ break;
+
+ /* looking for data chunk */
+ case 4:
+ if (fread(&chunk, sizeof(chunk), 1, wFile->file) != 1)
+ done = EAS_TRUE;
+ else
+ {
+ startChunkPos = ftell(wFile->file);
+
+ /* not data tag, skip it */
+ if (chunk.tag != dataTag)
+ fseek(wFile->file, startChunkPos + (EAS_I32) chunk.size, SEEK_SET);
+ else
+ {
+ wFile->dataSize = chunk.size;
+ state++;
+ done = EAS_TRUE;
+ }
+ }
+ break;
+
+ default:
+ done = EAS_TRUE;
+ break;
+ }
+ }
+
+ /* if not final state, an error occurred */
+ if (state != 5)
+ {
+ fclose(wFile->file);
+ free(wFile);
+ return NULL;
+ }
+
+ /* return the file handle */
+ return wFile;
+} /* end WaveFileOpen */
+#endif
+
+
+
|