~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to khotkeys/libkhotkeysprivate/sound.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright (C) 2005 by Olivier Goffart   *
 
3
 *   ogoffart@kde.org   *
 
4
 *                                                                         *
 
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.                                   *
 
9
 *                                                                         *
 
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.                          *
 
14
 *                                                                         *
 
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
 ***************************************************************************/
 
20
 
 
21
#include "sound.h"
 
22
#include <QtCore/QFile>
 
23
#include <QtCore/QDataStream>
 
24
#include <kdebug.h>
 
25
 
 
26
 
 
27
 
 
28
 
 
29
Sound::Sound()
 
30
{
 
31
}
 
32
 
 
33
 
 
34
Sound::~Sound()
 
35
{
 
36
}
 
37
 
 
38
 
 
39
#define READ_FROM_STREAM(FORMAT,NAME)  FORMAT NAME; stream >> NAME;
 
40
#define MAGIC(CH) { \
 
41
   stream >> magic;  \
 
42
   if( magic != ( (CH)[0] | (CH)[1]<<8 | (CH)[2]<< 16 | (CH)[3] << 24 ) ) \
 
43
   {  \
 
44
      kWarning() << "bad format " << magic << " != " << CH "\n";\
 
45
      return;\
 
46
   } }   
 
47
 
 
48
#define ABS(X)  ( (X>0) ? X : -X )
 
49
 
 
50
void Sound::load(const QString& filename)
 
51
{
 
52
        kDebug() << filename;
 
53
        data=QVector<Q_INT32>();
 
54
        QFile file(filename);
 
55
        if(!file.open(IO_ReadOnly))
 
56
        {
 
57
                kWarning() <<"unable to open file" ;
 
58
                return;
 
59
        }
 
60
        QDataStream stream(&file);
 
61
        stream.setByteOrder( QDataStream::LittleEndian );
 
62
        Q_INT32 magic;
 
63
        
 
64
        MAGIC("RIFF");
 
65
        READ_FROM_STREAM(quint32,ChunkSize);
 
66
        MAGIC("WAVE");
 
67
        MAGIC("fmt ");
 
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);
 
72
        _fs=SampleRate;
 
73
        READ_FROM_STREAM(quint32,ByteRate);
 
74
        READ_FROM_STREAM(Q_UINT16,BlockAlign);
 
75
        READ_FROM_STREAM(Q_UINT16,BitsPerSample);
 
76
        MAGIC("data");
 
77
        READ_FROM_STREAM(QByteArray,SoundData);
 
78
        NumberOfChannels=1; //Wav i play are broken
 
79
 
 
80
        file.close();
 
81
 
 
82
        uint BytePS=BitsPerSample/8;
 
83
        uint NumberOfSamples = (SoundData.size())/(NumberOfChannels*BytePS);
 
84
        
 
85
 
 
86
        data.resize(NumberOfSamples);
 
87
 
 
88
//      kDebug() << NumberOfSamples << " samples";
 
89
 
 
90
        max=0;
 
91
        for(unsigned long int f=0;f<NumberOfSamples;f++)
 
92
        {
 
93
                Q_INT32 nb=0;
 
94
                for(uint k=0;k<BytePS;k++)
 
95
                {
 
96
            nb |= (SoundData[(unsigned int)(f*BytePS+k)]&0x000000FF) << (k*8);
 
97
                }
 
98
                if(nb & (1 << (BytePS*8 -1)) )
 
99
                        nb = nb-(1<<BytePS*8);
 
100
                data[f]=nb;
 
101
                if(ABS(nb)>max)
 
102
                {
 
103
                        max=ABS(nb);
 
104
                }
 
105
        }
 
106
 
 
107
/*      static int q=0;
 
108
        QString name="test" + QString::number(q++) + ".wav";
 
109
        save(name);*/
 
110
 
 
111
}
 
112
 
 
113
#define SMAGIC(CH) { stream << ( Q_INT32) ( (CH)[0] | (CH)[1]<<8 | (CH)[2]<< 16 | (CH)[3] << 24 ) ; }
 
114
 
 
115
void Sound::save(const QString& filename) const
 
116
{
 
117
        kDebug() << filename << " - " << data.size() <<  endl;
 
118
        QFile file(filename);
 
119
        if(!file.open(IO_WriteOnly))
 
120
        {
 
121
                kWarning() <<"unable to open file" ;
 
122
                return;
 
123
        }
 
124
        QDataStream stream(&file);
 
125
        stream.setByteOrder( QDataStream::LittleEndian );
 
126
 
 
127
 
 
128
        QByteArray SoundData(data.size()*2, '\0');
 
129
        
 
130
        for(long int f=0;f<data.size();f++)
 
131
        {
 
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;
 
135
                
 
136
//              kDebug() << data.at(f) << " / " << max << " = " << val << "  |  " <<   SoundData[ 2*f ] << " "<< SoundData[ 2*f+1 ] <<  endl;
 
137
        }
 
138
 
 
139
        Q_UINT16 NumberOfChannels=2;
 
140
        quint32 SampleRate=_fs;
 
141
 
 
142
        SMAGIC("RIFF");
 
143
        //READ_FROM_STREAM(quint32,ChunkSize);
 
144
        stream <<  (quint32)(36+ SoundData.size());
 
145
        SMAGIC("WAVE");
 
146
        SMAGIC("fmt ");
 
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);
 
161
        SMAGIC("data");
 
162
        //READ_FROM_STREAM(QByteArray,SoundData);
 
163
        stream <<  SoundData;
 
164
 
 
165
        file.close();
 
166
        
 
167
}
 
168
 
 
169
 
 
170
 
 
171
 
 
172
#if 0
 
173
void Sound::load(const QString& filename)
 
174
{
 
175
        cout << "saout \n";
 
176
        data=QMemArray<long unsigned int>();
 
177
        static const int BUFFER_LEN = 4096;
 
178
 
 
179
        //code from libtunepimp
 
180
        //(wav_trm.cpp)
 
181
 
 
182
        FILE          *source;
 
183
        unsigned char  buffer[100], *copyBuffer;
 
184
        unsigned int   bytes;
 
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;
 
194
        int            toRead;
 
195
        mb_int64_t     fileLen = 0;
 
196
 
 
197
        source = fopen(filename.ascii(), "rb");
 
198
        if (source == NULL)
 
199
        {
 
200
//              errorString = string("File not found");
 
201
//              fclose(source);
 
202
                cout << "File not found \n";
 
203
                return;
 
204
        }
 
205
 
 
206
        fseek(source, 0, SEEK_END);
 
207
        fileLen = ftell(source);
 
208
        fseek(source, 0, SEEK_SET);
 
209
 
 
210
        if (fread(buffer, 1, 12, source) != 12)
 
211
        {
 
212
//              errorString = string("File is too short");
 
213
                cout << "File is to short \n";
 
214
                fclose(source);
 
215
                return ;
 
216
        }
 
217
 
 
218
        ulRIFF = (unsigned long)(((unsigned long *)buffer)[0]);
 
219
        ulLength = (unsigned long)(((unsigned long *)buffer)[1]);
 
220
        ulWAVE = (unsigned long)(((unsigned long *)buffer)[2]);
 
221
 
 
222
        if(ulRIFF != MAKEFOURCC('R', 'I', 'F', 'F') ||
 
223
                  ulWAVE != MAKEFOURCC('W', 'A', 'V', 'E'))
 
224
        {
 
225
//              errorString = strdup("File is not in WAVE format");
 
226
                cout << "File is not WAVE \n";
 
227
                fclose(source);
 
228
                return ;
 
229
        }
 
230
 
 
231
    // Run through the bytes looking for the tags
 
232
        ulCount = 0;
 
233
        ulLimit = ulLength - 4;
 
234
        while (ulCount < ulLimit && waveSize == 0)
 
235
        {
 
236
                if (fread(buffer, 1, 8, source) != 8)
 
237
                {
 
238
//                      errorString = strdup("File is too short");
 
239
                        cout << "File is to short \n";
 
240
                        fclose(source);
 
241
                        return;
 
242
                }
 
243
 
 
244
                ulType   = (unsigned long)(((unsigned long *)buffer)[0]);
 
245
                ulLength = (unsigned long)(((unsigned long *)buffer)[1]);
 
246
                switch (ulType)
 
247
                {
 
248
          // format
 
249
                        case MAKEFOURCC('f', 'm', 't', ' '):
 
250
                                if (ulLength < sizeof(WAVEFORMAT))
 
251
                                {
 
252
//                                      errorString = strdup("File is too short");
 
253
                                        cout << "File is to short \n";
 
254
                                        fclose(source);
 
255
                                        return ;
 
256
                                }
 
257
 
 
258
                                if (fread(&waveFormat, 1, ulLength, source) != ulLength)
 
259
                                {
 
260
//                                      errorString = strdup("File is too short");
 
261
                                        cout << "File is to short \n";
 
262
                                        fclose(source);
 
263
                                        return ;
 
264
                                }
 
265
 
 
266
                                if (waveFormat.wFormatTag != WAVE_FORMAT_PCM)
 
267
                                {
 
268
//                                      errorString = strdup("Unsupported WAV format");
 
269
                                        cout << "Unsupported WAVE \n";
 
270
                                        fclose(source);
 
271
                                        return ;
 
272
                                }
 
273
                                haveWaveHeader = true;
 
274
 
 
275
                                ulCount += ulLength;
 
276
                                break;
 
277
 
 
278
          // data
 
279
                        case MAKEFOURCC('d', 'a', 't', 'a'):
 
280
                                waveSize = ulLength;
 
281
                                break;
 
282
 
 
283
                        default:
 
284
                                fseek(source, ulLength, SEEK_CUR);
 
285
                                break;
 
286
 
 
287
                }
 
288
        }
 
289
 
 
290
 
 
291
        if (!haveWaveHeader)
 
292
        {
 
293
//              errorString = strdup("Could not find WAV header");
 
294
                cout << "Header nbot found \n";
 
295
                fclose(source);
 
296
                return ;
 
297
        }
 
298
 
 
299
        fileLen -= (mb_int64_t)ftell(source);
 
300
        fileLen /= waveFormat.nChannels;
 
301
        fileLen /= (waveFormat.nBlockAlign / waveFormat.nChannels);
 
302
 
 
303
        fileLen /= waveFormat.nSamplesPerSec;
 
304
 
 
305
        //on ne lit qu'un channel
 
306
        //waveSize=fileLen;
 
307
        data.resize(waveSize);
 
308
        unsigned long pos=0;
 
309
 
 
310
        cout << "Weeee "<< waveSize <<"\n";
 
311
 
 
312
        copyBuffer = (unsigned char*)malloc(BUFFER_LEN);
 
313
        if (copyBuffer == NULL)
 
314
        {
 
315
//              errorString = strdup("Cannot allocate buffer space.");
 
316
                return ;
 
317
        }
 
318
 
 
319
        for(;;)
 
320
        {
 
321
                toRead = min(waveSize, (unsigned long)BUFFER_LEN);
 
322
                if (toRead <= 0)
 
323
                        break;
 
324
 
 
325
                bytes = fread(copyBuffer, 1, toRead, source);
 
326
                if (bytes <= 0)
 
327
                        break;
 
328
 
 
329
                for(uint f=0;f<bytes;f+=4)
 
330
                {
 
331
                        data[pos]=(((unsigned long*)copyBuffer)[f/4]);
 
332
                        pos++;
 
333
                }
 
334
 
 
335
                waveSize -= toRead;
 
336
        }
 
337
        free(copyBuffer);
 
338
        fclose(source);
 
339
 
 
340
    return ;
 
341
}
 
342
 
 
343
#endif