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]);