/*************************************************************************** * Copyright (C) 2005 by Olivier Goffart * * ogoffart@kde.org * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "sound.h" #include #include #include Sound::Sound() { } Sound::~Sound() { } #define READ_FROM_STREAM(FORMAT,NAME) FORMAT NAME; stream >> NAME; #define MAGIC(CH) { \ stream >> magic; \ if( magic != ( (CH)[0] | (CH)[1]<<8 | (CH)[2]<< 16 | (CH)[3] << 24 ) ) \ { \ kdWarning() << k_funcinfo << "bad format " << magic << " != " << CH "\n";\ return;\ } } #define ABS(X) ( (X>0) ? X : -X ) void Sound::load(const TQString& filename) { kdDebug() << k_funcinfo << filename << endl; data=TQMemArray(); TQFile file(filename); if(!file.open(IO_ReadOnly)) { kdWarning() << k_funcinfo <<"unable to open file" << endl; return; } TQDataStream stream(&file); stream.setByteOrder( TQDataStream::LittleEndian ); Q_INT32 magic; MAGIC("RIFF"); READ_FROM_STREAM(Q_UINT32,ChunkSize); MAGIC("WAVE"); MAGIC("fmt "); READ_FROM_STREAM(Q_UINT32,ChunkSize2); READ_FROM_STREAM(Q_INT16,AudioFormat); READ_FROM_STREAM(Q_UINT16,NumberOfChannels); READ_FROM_STREAM(Q_UINT32,SampleRate); _fs=SampleRate; READ_FROM_STREAM(Q_UINT32,ByteRate); READ_FROM_STREAM(Q_UINT16,BlockAlign); READ_FROM_STREAM(Q_UINT16,BitsPerSample); MAGIC("data"); READ_FROM_STREAM(TQByteArray,SoundData); NumberOfChannels=1; //Wav i play are broken file.close(); uint BytePS=BitsPerSample/8; uint NumberOfSamples = (SoundData.size())/(NumberOfChannels*BytePS); data.resize(NumberOfSamples); // kdDebug() << k_funcinfo << NumberOfSamples << " samples" << endl; max=0; for(unsigned long int f=0;fmax) { max=ABS(nb); } } /* static int q=0; TQString name="test" + TQString::number(q++) + ".wav"; save(name);*/ } #define SMAGIC(CH) { stream << ( Q_INT32) ( (CH)[0] | (CH)[1]<<8 | (CH)[2]<< 16 | (CH)[3] << 24 ) ; } void Sound::save(const TQString& filename) const { kdDebug( 1217 ) << k_funcinfo << filename << " - " << data.size() << endl; TQFile file(filename); if(!file.open(IO_WriteOnly)) { kdWarning() << k_funcinfo <<"unable to open file" << endl; return; } TQDataStream stream(&file); stream.setByteOrder( TQDataStream::LittleEndian ); TQByteArray SoundData(data.size()*2); for(unsigned long int f=0;f> 8; // kdDebug( 1217 ) << k_funcinfo << data.at(f) << " / " << max << " = " << val << " | " << SoundData[ 2*f ] << " "<< SoundData[ 2*f+1 ] << endl; } Q_UINT16 NumberOfChannels=2; Q_UINT32 SampleRate=_fs; SMAGIC("RIFF"); //READ_FROM_STREAM(Q_UINT32,ChunkSize); stream << (Q_UINT32)(36+ SoundData.size()); SMAGIC("WAVE"); SMAGIC("fmt "); //READ_FROM_STREAM(Q_UINT32,ChunkSize2); stream << (Q_UINT32)(16); //READ_FROM_STREAM(Q_INT16,AudioFormat); stream << (Q_INT16)(1); //READ_FROM_STREAM(Q_UINT16,NumberOfChannels); stream << (Q_UINT16)(NumberOfChannels); //READ_FROM_STREAM(Q_UINT32,SampleRate); stream << (Q_UINT32)(SampleRate); //READ_FROM_STREAM(Q_UINT32,ByteRate); stream << (Q_UINT32)(NumberOfChannels*SampleRate*16/8); //READ_FROM_STREAM(Q_UINT16,BlockAlign); stream << (Q_UINT16)(16/8 *NumberOfChannels); //READ_FROM_STREAM(Q_UINT16,BitsPerSample); stream << (Q_UINT16)(16); SMAGIC("data"); //READ_FROM_STREAM(TQByteArray,SoundData); stream << SoundData; file.close(); } #if 0 void Sound::load(const TQString& filename) { cout << "saout \n"; data=TQMemArray(); static const int BUFFER_LEN = 4096; //code from libtunepimp //(wav_trm.cpp) FILE *source; unsigned char buffer[100], *copyBuffer; unsigned int bytes; unsigned long ulRIFF; unsigned long ulLength; unsigned long ulWAVE; unsigned long ulType; unsigned long ulCount; unsigned long ulLimit; bool haveWaveHeader = false; unsigned long waveSize = 0; WAVEFORMAT waveFormat; int toRead; mb_int64_t fileLen = 0; source = fopen(filename.ascii(), "rb"); if (source == NULL) { // errorString = string("File not found"); // fclose(source); cout << "File not found \n"; return; } fseek(source, 0, SEEK_END); fileLen = ftell(source); fseek(source, 0, SEEK_SET); if (fread(buffer, 1, 12, source) != 12) { // errorString = string("File is too short"); cout << "File is to short \n"; fclose(source); return ; } ulRIFF = (unsigned long)(((unsigned long *)buffer)[0]); ulLength = (unsigned long)(((unsigned long *)buffer)[1]); ulWAVE = (unsigned long)(((unsigned long *)buffer)[2]); if(ulRIFF != MAKEFOURCC('R', 'I', 'F', 'F') || ulWAVE != MAKEFOURCC('W', 'A', 'V', 'E')) { // errorString = strdup("File is not in WAVE format"); cout << "File is not WAVE \n"; fclose(source); return ; } // Run through the bytes looking for the tags ulCount = 0; ulLimit = ulLength - 4; while (ulCount < ulLimit && waveSize == 0) { if (fread(buffer, 1, 8, source) != 8) { // errorString = strdup("File is too short"); cout << "File is to short \n"; fclose(source); return; } ulType = (unsigned long)(((unsigned long *)buffer)[0]); ulLength = (unsigned long)(((unsigned long *)buffer)[1]); switch (ulType) { // format case MAKEFOURCC('f', 'm', 't', ' '): if (ulLength < sizeof(WAVEFORMAT)) { // errorString = strdup("File is too short"); cout << "File is to short \n"; fclose(source); return ; } if (fread(&waveFormat, 1, ulLength, source) != ulLength) { // errorString = strdup("File is too short"); cout << "File is to short \n"; fclose(source); return ; } if (waveFormat.wFormatTag != WAVE_FORMAT_PCM) { // errorString = strdup("Unsupported WAV format"); cout << "Unsupported WAVE \n"; fclose(source); return ; } haveWaveHeader = true; ulCount += ulLength; break; // data case MAKEFOURCC('d', 'a', 't', 'a'): waveSize = ulLength; break; default: fseek(source, ulLength, SEEK_CUR); break; } } if (!haveWaveHeader) { // errorString = strdup("Could not find WAV header"); cout << "Header nbot found \n"; fclose(source); return ; } fileLen -= (mb_int64_t)ftell(source); fileLen /= waveFormat.nChannels; fileLen /= (waveFormat.nBlockAlign / waveFormat.nChannels); fileLen /= waveFormat.nSamplesPerSec; //on ne lit qu'un channel //waveSize=fileLen; data.resize(waveSize); unsigned long pos=0; cout << "Weeee "<< waveSize <<"\n"; copyBuffer = (unsigned char*)malloc(BUFFER_LEN); if (copyBuffer == NULL) { // errorString = strdup("Cannot allocate buffer space."); return ; } for(;;) { toRead = min(waveSize, (unsigned long)BUFFER_LEN); if (toRead <= 0) break; bytes = fread(copyBuffer, 1, toRead, source); if (bytes <= 0) break; for(uint f=0;f