--- a
+++ b/mpd2src/wavreader.cpp
@@ -0,0 +1,222 @@
+/*
+Copyright 2012, OpenHome. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY OPENHOME ''AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation
+are those of the authors and should not be interpreted as representing
+official policies, either expressed or implied, of OpenHome.
+*/
+
+#include "wavreader.h"
+
+#include <iostream>
+#include <string.h>
+
+#include "audioutil.h"
+#include "log.h"
+
+using namespace std;
+
+bool WavReader::open()
+{
+ if (!readHeader()) {
+ cerr << "Can't open file: " << m_fn << endl;
+ return false;
+ }
+ if (!readData()) {
+ cerr << "Can't read file: " << m_fn << endl;
+ return false;
+ }
+ return true;
+}
+
+const unsigned char *WavReader::data(size_t packetbytes)
+{
+ if (m_index + packetbytes <= totalBytes()) {
+ m_index += packetbytes;
+ //cerr << "WavReader::data: " << packetbytes << " at " <<
+ //m_index - packetbytes << endl;
+ return m_data + m_index - packetbytes;
+ } else if (totalBytes() == m_index) {
+ m_index = packetbytes;
+ return m_data;
+ } else {
+ unsigned int remaining = packetbytes - (totalBytes() - m_index);
+ if (m_tmpbufsize < packetbytes) {
+ m_tmpbuf = (unsigned char *)realloc(m_tmpbuf, packetbytes);
+ m_tmpbufsize = packetbytes;
+ }
+ memcpy(m_tmpbuf, m_data + m_index, remaining);
+ memcpy(m_tmpbuf + remaining, m_data, packetbytes - remaining);
+ m_index = packetbytes - remaining;
+ return m_tmpbuf;
+ }
+}
+
+// Read WAV file
+bool WavReader::readHeader()
+{
+ m_fp = fopen(m_fn.c_str(), "rb");
+
+ if (m_fp == 0) {
+ LOGDEB("Unable to open specified wav file\n");
+ return false;
+ }
+
+ unsigned char header[44];
+
+ size_t count = fread((void*)header, 1, 44, m_fp);
+
+ if (count != 44) {
+ LOGDEB("Unable to read the specified wav file\n");
+ return false;
+ }
+
+ if (header[0] != 'R' || header[1] != 'I' || header[2] != 'F' ||
+ header[3] != 'F') {
+ LOGDEB("Invalid wav file\n");
+ return false;
+ }
+
+ unsigned int header0, header1, header2, header3;
+
+ header0 = header[4];
+ header1 = header[5];
+ header2 = header[6];
+ header3 = header[7];
+
+ // unsigned int chunkSize = header0 | (header1 << 8) | (header2 << 16) | (header3 << 24);
+
+ if (header[8] != 'W' || header[9] != 'A' || header[10] != 'V' ||
+ header[11] != 'E') {
+ LOGDEB("Invalid wav file\n");
+ return false;
+ }
+
+ if (header[12] != 'f' || header[13] != 'm' || header[14] != 't' ||
+ header[15] != ' ') {
+ LOGDEB("Invalid wav file\n");
+ return false;
+ }
+
+ header0 = header[16];
+ header1 = header[17];
+ header2 = header[18];
+ header3 = header[19];
+
+ unsigned int subChunk1Size =
+ header0 | (header1 << 8) | (header2 << 16) | (header3 << 24);
+
+ if (subChunk1Size != 16) {
+ LOGDEB("Unsupported wav file\n");
+ return false;
+ }
+
+ header0 = header[20];
+ header1 = header[21];
+
+ unsigned int audioFormat = header0 | (header1 << 8);
+
+ if (audioFormat != 1) {
+ LOGDEB("Unsupported wav file\n");
+ return false;
+ }
+
+ header0 = header[22];
+ header1 = header[23];
+
+ m_numChannels = header0 | (header1 << 8);
+
+ header0 = header[24];
+ header1 = header[25];
+ header2 = header[26];
+ header3 = header[27];
+
+ m_sampleRate = header0 | (header1 << 8) | (header2 << 16) | (header3 << 24);
+
+ header0 = header[28];
+ header1 = header[29];
+ header2 = header[30];
+ header3 = header[31];
+
+ m_byteRate = header0 | (header1 << 8) | (header2 << 16) | (header3 << 24);
+
+ //header0 = header[32];
+ //header1 = header[33];
+
+ //unsigned int blockAlign = header0 | (header1 << 8);
+
+ header0 = header[34];
+ header1 = header[35];
+
+ m_bitsPerSample = header0 | (header1 << 8);
+
+ if (header[36] != 'd' || header[37] != 'a' || header[38] != 't' ||
+ header[39] != 'a') {
+ LOGDEB("Invalid wav file\n");
+ return false;
+ }
+
+ header0 = header[40];
+ header1 = header[41];
+ header2 = header[42];
+ header3 = header[43];
+
+ m_subChunk2Size = header0 | (header1 << 8) | (header2 << 16) |
+ (header3 << 24);
+
+ m_dataoffs = ftello(m_fp);
+ return true;
+}
+
+bool WavReader::readData()
+{
+ //LOGDEB("WavReader::readData: m_dataoffs " << m_dataoffs << endl);
+ if (m_fp == 0) {
+ LOGERR("WavReader::readData: not open\n");
+ return false;
+ }
+
+ if (m_data)
+ free(m_data);
+ m_data = (unsigned char *)malloc(m_subChunk2Size);
+ if (m_data == 0) {
+ LOGERR("Malloc " << m_subChunk2Size / (1024*1024) << " Mb failed\n");
+ return false;
+ }
+ fseeko(m_fp, m_dataoffs, SEEK_SET);
+
+ ssize_t count = fread((void*)m_data, 1, m_subChunk2Size, m_fp);
+
+ if (count != m_subChunk2Size) {
+ LOGDEB("Unable to read wav file asked " << m_subChunk2Size << " got " <<
+ count << endl);
+ return false;
+ }
+ swapSamples(m_data, bytesPerSample(), sampleCount());
+
+ return true;
+}