00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <qapplication.h>
00011 #include <qfile.h>
00012
00013 #include <stdlib.h>
00014 #include <stdio.h>
00015 #include <iostream>
00016
00017 using namespace std;
00018
00019 #include "wavfile.h"
00020
00021
00022 wavfile::wavfile()
00023 {
00024 loaded=false;
00025 audio = 0;
00026 }
00027
00028 wavfile::~wavfile()
00029 {
00030 if (loaded && audio)
00031 delete audio;
00032 }
00033
00034 bool wavfile::load(const char *Filename)
00035 {
00036 QFile f(Filename);
00037 if (!f.open(IO_ReadOnly))
00038 {
00039 cerr << "Cannot open for reading file " << Filename << endl;
00040 return false;
00041 }
00042
00043 w.ChunkSize = 36 + w.subChunk2Size;
00044 int result = f.readBlock((char *)&w, sizeof(w));
00045 if (result == -1)
00046 {
00047 f.close();
00048 return false;
00049 }
00050
00051 audio = new char[w.subChunk2Size];
00052 result = f.readBlock(audio, w.subChunk2Size);
00053 loaded=true;
00054 f.close();
00055
00056 return (result == -1 ? false : true);
00057 }
00058
00059 void wavfile::load(short *data, int samples, int bitsPerSample, int AudioFormat, int nChan, int SampleRate)
00060 {
00061 memcpy(w.ChunkId, "RIFF", 4);
00062 memcpy(w.Format, "WAVE", 4);
00063 memcpy(w.subChunk1Id, "fmt ", 4);
00064 w.subChunk1Size = 16;
00065 w.AudioFormat = AudioFormat;
00066 w.NumChannels = nChan;
00067 w.SampleRate = SampleRate;
00068 w.ByteRate = w.SampleRate * w.NumChannels * (bitsPerSample/8);
00069 w.BlockAlign = w.NumChannels * (bitsPerSample/8);
00070 w.BitsPerSample = bitsPerSample;
00071 memcpy(w.subChunk2Id, "data", 4);
00072 w.subChunk2Size = samples*(bitsPerSample/8);
00073
00074 if (audio)
00075 {
00076 delete audio;
00077 audio = 0;
00078 }
00079
00080 audio = new char[w.subChunk2Size];
00081 memcpy(audio, (const char *)data, w.subChunk2Size);
00082
00083 if (w.SampleRate != 8000)
00084 transcodeTo8K();
00085
00086 loaded=true;
00087 }
00088
00089 void wavfile::transcodeTo8K()
00090 {
00091 static bool firstTime = true;
00092
00093
00094
00095 if (audio)
00096 {
00097 if (w.SampleRate == 16000)
00098 {
00099 short *s = (short *)audio;
00100 short *d = (short *)audio;
00101 w.subChunk2Size /= 2;
00102 for (uint c=0; c<w.subChunk2Size/sizeof(short); c++,s++)
00103 *d++ = *s++;
00104 w.SampleRate = 8000;
00105 w.ByteRate = w.SampleRate * w.NumChannels * (w.BitsPerSample/8);
00106
00107 if (firstTime)
00108 {
00109 firstTime = false;
00110 cout << "The TTS library is encoding as 16k PCM, you should reconfigure it to 8k PCM\n";
00111 }
00112 }
00113 else
00114 cout << "MythPhone Unsupported sample-rate " << w.SampleRate << endl;
00115 }
00116 }
00117
00118 void wavfile::print()
00119 {
00120 if (loaded)
00121 {
00122 if (memcmp(w.ChunkId, "RIFF", 4) == 0)
00123 cout << "Filetype: RIFF\n";
00124 else
00125 cout << "Filetype: Unsupported\n";
00126
00127 if (memcmp(w.Format, "WAVE", 4) == 0)
00128 cout << "Format: WAVE\n";
00129 else
00130 cout << "Format: Unsupported\n";
00131
00132 if (memcmp(w.subChunk1Id, "fmt ", 4) == 0)
00133 cout << "SubFormat: fmt\n";
00134 else
00135 cout << "SubFormat: Unsupported\n";
00136
00137 cout << "ChunkSize: " << w.subChunk1Size << endl;
00138 cout << "Audio Format: " << (w.AudioFormat==1 ? "PCM" : "Unsupported") << endl;
00139 cout << "Channels: " << w.NumChannels << endl;
00140 cout << "Sample Rate: " << w.SampleRate << endl;
00141 cout << "Byte Rate: " << w.ByteRate << endl;
00142 cout << "Block Align: " << w.BlockAlign << endl;
00143 cout << "Bits per Sample: " << w.BitsPerSample << endl;
00144
00145 if (memcmp(w.subChunk2Id, "data", 4) == 0)
00146 cout << "SubFormat: data\n";
00147 else
00148 cout << "SubFormat: Unsupported\n";
00149
00150 cout << "DataSize: " << w.subChunk2Size << endl;
00151 }
00152 }
00153
00154 bool wavfile::saveToFile(const char *Filename)
00155 {
00156 QFile f(Filename);
00157 if (!f.open(IO_WriteOnly))
00158 {
00159 cerr << "Cannot open for writing file " << Filename << endl;
00160 return false;
00161 }
00162
00163 w.ChunkSize = 36 + w.subChunk2Size;
00164 int result = f.writeBlock((const char *)&w, sizeof(w));
00165 if ((result != -1) && audio)
00166 result = f.writeBlock(audio, w.subChunk2Size);
00167 f.close();
00168
00169 return (result == -1 ? false : true);
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185