1
/***************************************************************************
2
* Copyright (C) 2005 by Olivier Goffart *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License as published by *
7
* the Free Software Foundation; either version 2 of the License, or *
8
* (at your option) any later version. *
10
* This program is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
* GNU General Public License for more details. *
15
* You should have received a copy of the GNU General Public License *
16
* along with this program; if not, write to the *
17
* Free Software Foundation, Inc., *
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19
***************************************************************************/
22
#include <QtCore/QFile>
23
#include <QtCore/QDataStream>
39
#define READ_FROM_STREAM(FORMAT,NAME) FORMAT NAME; stream >> NAME;
42
if( magic != ( (CH)[0] | (CH)[1]<<8 | (CH)[2]<< 16 | (CH)[3] << 24 ) ) \
44
kWarning() << "bad format " << magic << " != " << CH "\n";\
48
#define ABS(X) ( (X>0) ? X : -X )
50
void Sound::load(const QString& filename)
53
data=QVector<Q_INT32>();
55
if(!file.open(IO_ReadOnly))
57
kWarning() <<"unable to open file" ;
60
QDataStream stream(&file);
61
stream.setByteOrder( QDataStream::LittleEndian );
65
READ_FROM_STREAM(quint32,ChunkSize);
68
READ_FROM_STREAM(quint32,ChunkSize2);
69
READ_FROM_STREAM(Q_INT16,AudioFormat);
70
READ_FROM_STREAM(Q_UINT16,NumberOfChannels);
71
READ_FROM_STREAM(quint32,SampleRate);
73
READ_FROM_STREAM(quint32,ByteRate);
74
READ_FROM_STREAM(Q_UINT16,BlockAlign);
75
READ_FROM_STREAM(Q_UINT16,BitsPerSample);
77
READ_FROM_STREAM(QByteArray,SoundData);
78
NumberOfChannels=1; //Wav i play are broken
82
uint BytePS=BitsPerSample/8;
83
uint NumberOfSamples = (SoundData.size())/(NumberOfChannels*BytePS);
86
data.resize(NumberOfSamples);
88
// kDebug() << NumberOfSamples << " samples";
91
for(unsigned long int f=0;f<NumberOfSamples;f++)
94
for(uint k=0;k<BytePS;k++)
96
nb |= (SoundData[(unsigned int)(f*BytePS+k)]&0x000000FF) << (k*8);
98
if(nb & (1 << (BytePS*8 -1)) )
99
nb = nb-(1<<BytePS*8);
108
QString name="test" + QString::number(q++) + ".wav";
113
#define SMAGIC(CH) { stream << ( Q_INT32) ( (CH)[0] | (CH)[1]<<8 | (CH)[2]<< 16 | (CH)[3] << 24 ) ; }
115
void Sound::save(const QString& filename) const
117
kDebug() << filename << " - " << data.size() << endl;
118
QFile file(filename);
119
if(!file.open(IO_WriteOnly))
121
kWarning() <<"unable to open file" ;
124
QDataStream stream(&file);
125
stream.setByteOrder( QDataStream::LittleEndian );
128
QByteArray SoundData(data.size()*2, '\0');
130
for(long int f=0;f<data.size();f++)
132
Q_UINT16 val= (signed short int) ( (data.at(f) * ((double)(1<<13)/(signed)max) ) );
133
SoundData[ (uint)(2*f) ]= val & 0x00FF;
134
SoundData[(uint)(2*f+1)]= (val & 0xFF00) >> 8;
136
// kDebug() << data.at(f) << " / " << max << " = " << val << " | " << SoundData[ 2*f ] << " "<< SoundData[ 2*f+1 ] << endl;
139
Q_UINT16 NumberOfChannels=2;
140
quint32 SampleRate=_fs;
143
//READ_FROM_STREAM(quint32,ChunkSize);
144
stream << (quint32)(36+ SoundData.size());
147
//READ_FROM_STREAM(quint32,ChunkSize2);
148
stream << (quint32)(16);
149
//READ_FROM_STREAM(Q_INT16,AudioFormat);
150
stream << (Q_INT16)(1);
151
//READ_FROM_STREAM(Q_UINT16,NumberOfChannels);
152
stream << (Q_UINT16)(NumberOfChannels);
153
//READ_FROM_STREAM(quint32,SampleRate);
154
stream << (quint32)(SampleRate);
155
//READ_FROM_STREAM(quint32,ByteRate);
156
stream << (quint32)(NumberOfChannels*SampleRate*16/8);
157
//READ_FROM_STREAM(Q_UINT16,BlockAlign);
158
stream << (Q_UINT16)(16/8 *NumberOfChannels);
159
//READ_FROM_STREAM(Q_UINT16,BitsPerSample);
160
stream << (Q_UINT16)(16);
162
//READ_FROM_STREAM(QByteArray,SoundData);
173
void Sound::load(const QString& filename)
176
data=QMemArray<long unsigned int>();
177
static const int BUFFER_LEN = 4096;
179
//code from libtunepimp
183
unsigned char buffer[100], *copyBuffer;
185
unsigned long ulRIFF;
186
unsigned long ulLength;
187
unsigned long ulWAVE;
188
unsigned long ulType;
189
unsigned long ulCount;
190
unsigned long ulLimit;
191
bool haveWaveHeader = false;
192
unsigned long waveSize = 0;
193
WAVEFORMAT waveFormat;
195
mb_int64_t fileLen = 0;
197
source = fopen(filename.ascii(), "rb");
200
// errorString = string("File not found");
202
cout << "File not found \n";
206
fseek(source, 0, SEEK_END);
207
fileLen = ftell(source);
208
fseek(source, 0, SEEK_SET);
210
if (fread(buffer, 1, 12, source) != 12)
212
// errorString = string("File is too short");
213
cout << "File is to short \n";
218
ulRIFF = (unsigned long)(((unsigned long *)buffer)[0]);
219
ulLength = (unsigned long)(((unsigned long *)buffer)[1]);
220
ulWAVE = (unsigned long)(((unsigned long *)buffer)[2]);
222
if(ulRIFF != MAKEFOURCC('R', 'I', 'F', 'F') ||
223
ulWAVE != MAKEFOURCC('W', 'A', 'V', 'E'))
225
// errorString = strdup("File is not in WAVE format");
226
cout << "File is not WAVE \n";
231
// Run through the bytes looking for the tags
233
ulLimit = ulLength - 4;
234
while (ulCount < ulLimit && waveSize == 0)
236
if (fread(buffer, 1, 8, source) != 8)
238
// errorString = strdup("File is too short");
239
cout << "File is to short \n";
244
ulType = (unsigned long)(((unsigned long *)buffer)[0]);
245
ulLength = (unsigned long)(((unsigned long *)buffer)[1]);
249
case MAKEFOURCC('f', 'm', 't', ' '):
250
if (ulLength < sizeof(WAVEFORMAT))
252
// errorString = strdup("File is too short");
253
cout << "File is to short \n";
258
if (fread(&waveFormat, 1, ulLength, source) != ulLength)
260
// errorString = strdup("File is too short");
261
cout << "File is to short \n";
266
if (waveFormat.wFormatTag != WAVE_FORMAT_PCM)
268
// errorString = strdup("Unsupported WAV format");
269
cout << "Unsupported WAVE \n";
273
haveWaveHeader = true;
279
case MAKEFOURCC('d', 'a', 't', 'a'):
284
fseek(source, ulLength, SEEK_CUR);
293
// errorString = strdup("Could not find WAV header");
294
cout << "Header nbot found \n";
299
fileLen -= (mb_int64_t)ftell(source);
300
fileLen /= waveFormat.nChannels;
301
fileLen /= (waveFormat.nBlockAlign / waveFormat.nChannels);
303
fileLen /= waveFormat.nSamplesPerSec;
305
//on ne lit qu'un channel
307
data.resize(waveSize);
310
cout << "Weeee "<< waveSize <<"\n";
312
copyBuffer = (unsigned char*)malloc(BUFFER_LEN);
313
if (copyBuffer == NULL)
315
// errorString = strdup("Cannot allocate buffer space.");
321
toRead = min(waveSize, (unsigned long)BUFFER_LEN);
325
bytes = fread(copyBuffer, 1, toRead, source);
329
for(uint f=0;f<bytes;f+=4)
331
data[pos]=(((unsigned long*)copyBuffer)[f/4]);