summaryrefslogtreecommitdiff
path: root/utils/wavfile.c
diff options
context:
space:
mode:
authorYuval Adam <yuv.adm@gmail.com>2014-03-16 14:41:11 +0200
committerYuval Adam <yuv.adm@gmail.com>2014-03-16 14:41:11 +0200
commit990090a4cc9070837d31e66b58d40f0c3d038741 (patch)
treecf1b905082c364e9b223e0c5058566103138dae5 /utils/wavfile.c
parent7f4da522479c0f00126219f0c23b804c3a93d7a6 (diff)
Add usblib and utils
Diffstat (limited to 'utils/wavfile.c')
-rw-r--r--utils/wavfile.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/utils/wavfile.c b/utils/wavfile.c
new file mode 100644
index 0000000..b2ce150
--- /dev/null
+++ b/utils/wavfile.c
@@ -0,0 +1,291 @@
+//******************************************************************************
+//
+// wavfile.c - This file supports reading audio data from a .wav file and
+// reading the file format.
+//
+// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Utility Library.
+//
+//******************************************************************************
+
+#include <stdint.h>
+#include "inc/hw_types.h"
+#include "third_party/fatfs/src/ff.h"
+#include "third_party/fatfs/src/diskio.h"
+#include "wavfile.h"
+
+//******************************************************************************
+//
+// The flag values for the ui32Flags member of the tWavFile structure.
+//
+//******************************************************************************
+#define WAV_FLAG_FILEOPEN 0x00000001
+
+//******************************************************************************
+//
+// Basic wav file RIFF header information used to open and read a wav file.
+//
+//******************************************************************************
+#define RIFF_CHUNK_ID_RIFF 0x46464952
+#define RIFF_CHUNK_ID_FMT 0x20746d66
+#define RIFF_CHUNK_ID_DATA 0x61746164
+#define RIFF_TAG_WAVE 0x45564157
+#define RIFF_FORMAT_UNKNOWN 0x0000
+#define RIFF_FORMAT_PCM 0x0001
+#define RIFF_FORMAT_MSADPCM 0x0002
+#define RIFF_FORMAT_IMAADPCM 0x0011
+
+//******************************************************************************
+//
+// This function returns the format of a wav file that has been opened with
+// the WavOpen() function.
+//
+// \param psWavData is the structure that was passed to the WavOpen() function.
+// \param psWavHeader is the structure to fill with the format of the wav file.
+//
+// This function is used to get the audio format of a file that was opened
+// with the WavOpen() function. The \e psWavData parameter should be the
+// same structure that was passed to the WavOpen() function. The
+// \e psWavHeader function will be filled with the format of the open file if
+// the \e psWavData is a valid open file. If this function is called with
+// an invalid \e psWavData then the results will be undetermined.
+//
+// \return None.
+//
+//******************************************************************************
+void
+WavGetFormat(tWavFile *psWavData, tWavHeader *psWavHeader)
+{
+ //
+ // Only return data if the file is open.
+ //
+ psWavHeader->ui32DataSize = psWavData->sWavHeader.ui32DataSize;
+ psWavHeader->ui16NumChannels = psWavData->sWavHeader.ui16NumChannels;
+ psWavHeader->ui32SampleRate = psWavData->sWavHeader.ui32SampleRate;
+ psWavHeader->ui32AvgByteRate = psWavData->sWavHeader.ui32AvgByteRate;
+ psWavHeader->ui16BitsPerSample = psWavData->sWavHeader.ui16BitsPerSample;
+}
+
+//******************************************************************************
+//
+// This function is called to open and determine if a file is a valid .wav
+// file.
+//
+// \param pcFileName is the null terminated string for the file to open.
+// \param psWavData is the structure used to hold the file state information.
+//
+// This function is used to open a file and determine if it is a valid .wav
+// file. The \e pcFileName will be opened and read to look for a valid .wav
+// file header and prepared for calling the WavRead() or WavGetFormat()
+// functions. When an application is done with the .wav file it should call
+// the WavClose() function to free up the file. The function will return
+// zero if the function successfully opened a .wav file and a non-zero value
+// indicates that the file was a valid .wav file or the file could not be
+// opened.
+//
+// \return A value of zero indicates that the file was successfully opened and
+// any other value indicates that the file was not opened.
+//
+//******************************************************************************
+int
+WavOpen(const char *pcFileName, tWavFile *psWavData)
+{
+ unsigned char pucBuffer[16];
+ uint32_t *pui32Buffer;
+ uint16_t *pui16Buffer;
+ uint32_t ui32ChunkSize;
+ uint32_t ui32Count;
+
+ //
+ // Create some local pointers using in parsing values.
+ //
+ pui32Buffer = (uint32_t *)pucBuffer;
+ pui16Buffer = (uint16_t *)pucBuffer;
+
+ //
+ // Open the file as read only.
+ //
+ if(f_open(&psWavData->i16File, pcFileName, FA_READ) != FR_OK)
+ {
+ return(-1);
+ }
+
+ //
+ // File is open.
+ //
+ psWavData->ui32Flags = WAV_FLAG_FILEOPEN;
+
+ //
+ // Read the first 12 bytes.
+ //
+ if(f_read(&psWavData->i16File, pucBuffer, 12, (UINT *)&ui32Count) != FR_OK)
+ {
+ return(-1);
+ }
+
+ //
+ // Look for RIFF tag.
+ //
+ if((pui32Buffer[0] != RIFF_CHUNK_ID_RIFF) ||
+ (pui32Buffer[2] != RIFF_TAG_WAVE))
+ {
+ return(-1);
+ }
+
+ //
+ // Read the next chunk header.
+ //
+ if(f_read(&psWavData->i16File, pucBuffer, 8, (UINT *)&ui32Count) != FR_OK)
+ {
+ return(-1);
+ }
+
+ //
+ // Now look for the RIFF ID format tag.
+ //
+ if(pui32Buffer[0] != RIFF_CHUNK_ID_FMT)
+ {
+ return(-1);
+ }
+
+ //
+ // Read the format chunk size and insure that it is 16.
+ //
+ ui32ChunkSize = pui32Buffer[1];
+
+ if(ui32ChunkSize > 16)
+ {
+ return(-1);
+ }
+
+ //
+ // Read the next chunk header.
+ //
+ if(f_read(&psWavData->i16File, pucBuffer, ui32ChunkSize,
+ (UINT *)&ui32Count) != FR_OK)
+ {
+ return(-1);
+ }
+
+ //
+ // Save the audio format data so that it can be returned later if
+ // requested.
+ //
+ psWavData->sWavHeader.ui16Format = pui16Buffer[0];
+ psWavData->sWavHeader.ui16NumChannels = pui16Buffer[1];
+ psWavData->sWavHeader.ui32SampleRate = pui32Buffer[1];
+ psWavData->sWavHeader.ui32AvgByteRate = pui32Buffer[2];
+ psWavData->sWavHeader.ui16BitsPerSample = pui16Buffer[7];
+
+ //
+ // Only mono and stereo supported.
+ //
+ if(psWavData->sWavHeader.ui16NumChannels > 2)
+ {
+ return(-1);
+ }
+
+ //
+ // Read the next chunk header.
+ //
+ if(f_read(&psWavData->i16File, pucBuffer, 8, (UINT *)&ui32Count) != FR_OK)
+ {
+ return(-1);
+ }
+
+ //
+ // Now make sure that the file has a data chunk.
+ //
+ if(pui32Buffer[0] != RIFF_CHUNK_ID_DATA)
+ {
+ return(-1);
+ }
+
+ //
+ // Save the size of the data.
+ //
+ psWavData->sWavHeader.ui32DataSize = pui32Buffer[1];
+
+ return(0);
+}
+
+//******************************************************************************
+//
+// This is used to close a .wav file that was opened with WavOpen().
+//
+// \param psWavData is the file structure that was passed into the WavOpen()
+// function.
+//
+// This function should be called when a function has completed using a .wav
+// file that was opened with the WavOpen() function. This will free up any
+// file system data that is held while the file is open.
+//
+// \return None.
+//
+//******************************************************************************
+void
+WavClose(tWavFile *psWavData)
+{
+ if(psWavData->ui32Flags & WAV_FLAG_FILEOPEN)
+ {
+ //
+ // Close out the file.
+ //
+ f_close(&psWavData->i16File);
+
+ //
+ // Mark file as no longer open.
+ //
+ psWavData->ui32Flags &= ~WAV_FLAG_FILEOPEN;
+ }
+}
+
+//******************************************************************************
+//
+// This function is used to read audio data from a file that was opened with
+// the WavOpen() function.
+//
+// \param psWavData is the file structure that was passed into the WavOpen()
+// function.
+// \param pucBuffer is the buffer to read data into.
+// \param ui32Size is the amount of data to read in bytes.
+//
+//
+// This function handles reading data from a .wav file that was opened with
+// the WavOpen() function. The function will return the actual number of
+// of bytes read from the file.
+//
+// \return This function returns the number of bytes read from the file.
+//
+//******************************************************************************
+uint16_t
+WavRead(tWavFile *psWavData, unsigned char *pucBuffer, uint32_t ui32Size)
+{
+ uint32_t ui32Count;
+
+ //
+ // Read in another buffer from the file.
+ //
+ if(f_read(&psWavData->i16File, pucBuffer, ui32Size,
+ (UINT *)&ui32Count) != FR_OK)
+ {
+ return(0);
+ }
+
+ return(ui32Count);
+}