summaryrefslogtreecommitdiffstats
path: root/khotkeys/shared/sound.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'khotkeys/shared/sound.cpp')
-rw-r--r--khotkeys/shared/sound.cpp343
1 files changed, 343 insertions, 0 deletions
diff --git a/khotkeys/shared/sound.cpp b/khotkeys/shared/sound.cpp
new file mode 100644
index 000000000..393b02f46
--- /dev/null
+++ b/khotkeys/shared/sound.cpp
@@ -0,0 +1,343 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Olivier Goffart *
+ * *
+ * 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 <tqfile.h>
+#include <tqdatastream.h>
+#include <kdebug.h>
+
+
+
+
+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<TQ_INT32>();
+ TQFile file(filename);
+ if(!file.open(IO_ReadOnly))
+ {
+ kdWarning() << k_funcinfo <<"unable to open file" << endl;
+ return;
+ }
+ TQDataStream stream(&file);
+ stream.setByteOrder( TQDataStream::LittleEndian );
+ TQ_INT32 magic;
+
+ MAGIC("RIFF");
+ READ_FROM_STREAM(TQ_UINT32,ChunkSize);
+ MAGIC("WAVE");
+ MAGIC("fmt ");
+ READ_FROM_STREAM(TQ_UINT32,ChunkSize2);
+ READ_FROM_STREAM(TQ_INT16,AudioFormat);
+ READ_FROM_STREAM(TQ_UINT16,NumberOfChannels);
+ READ_FROM_STREAM(TQ_UINT32,SampleRate);
+ _fs=SampleRate;
+ READ_FROM_STREAM(TQ_UINT32,ByteRate);
+ READ_FROM_STREAM(TQ_UINT16,BlockAlign);
+ READ_FROM_STREAM(TQ_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;f<NumberOfSamples;f++)
+ {
+ TQ_INT32 nb=0;
+ for(uint k=0;k<BytePS;k++)
+ {
+ nb |= (SoundData.at(f*BytePS+k)&0x000000FF) << (k*8);
+ }
+ if(nb & (1 << (BytePS*8 -1)) )
+ nb = nb-(1<<BytePS*8);
+ data[f]=nb;
+ if(ABS(nb)>max)
+ {
+ max=ABS(nb);
+ }
+ }
+
+/* static int q=0;
+ TQString name="test" + TQString::number(q++) + ".wav";
+ save(name);*/
+
+}
+
+#define SMAGIC(CH) { stream << ( TQ_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<data.size();f++)
+ {
+ TQ_UINT16 val= (signed short int) ( (data.at(f) * ((double)(1<<13)/(signed)max) ) );
+ SoundData.at( 2*f )= val & 0x00FF;
+ SoundData.at(2*f+1)= (val & 0xFF00) >> 8;
+
+// kdDebug( 1217 ) << k_funcinfo << data.at(f) << " / " << max << " = " << val << " | " << SoundData[ 2*f ] << " "<< SoundData[ 2*f+1 ] << endl;
+ }
+
+ TQ_UINT16 NumberOfChannels=2;
+ TQ_UINT32 SampleRate=_fs;
+
+ SMAGIC("RIFF");
+ //READ_FROM_STREAM(TQ_UINT32,ChunkSize);
+ stream << (TQ_UINT32)(36+ SoundData.size());
+ SMAGIC("WAVE");
+ SMAGIC("fmt ");
+ //READ_FROM_STREAM(TQ_UINT32,ChunkSize2);
+ stream << (TQ_UINT32)(16);
+ //READ_FROM_STREAM(TQ_INT16,AudioFormat);
+ stream << (TQ_INT16)(1);
+ //READ_FROM_STREAM(TQ_UINT16,NumberOfChannels);
+ stream << (TQ_UINT16)(NumberOfChannels);
+ //READ_FROM_STREAM(TQ_UINT32,SampleRate);
+ stream << (TQ_UINT32)(SampleRate);
+ //READ_FROM_STREAM(TQ_UINT32,ByteRate);
+ stream << (TQ_UINT32)(NumberOfChannels*SampleRate*16/8);
+ //READ_FROM_STREAM(TQ_UINT16,BlockAlign);
+ stream << (TQ_UINT16)(16/8 *NumberOfChannels);
+ //READ_FROM_STREAM(TQ_UINT16,BitsPerSample);
+ stream << (TQ_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<long unsigned int>();
+ 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<bytes;f+=4)
+ {
+ data[pos]=(((unsigned long*)copyBuffer)[f/4]);
+ pos++;
+ }
+
+ waveSize -= toRead;
+ }
+ free(copyBuffer);
+ fclose(source);
+
+ return ;
+}
+
+#endif