~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to noatun/noatun/library/equalizer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "equalizer.h"
 
2
#include "engine.h"
 
3
#include <common.h>
 
4
#include <dynamicrequest.h>
 
5
#include <artsflow.h>
 
6
#include <noatunapp.h>
 
7
#include <player.h>
 
8
#include <soundserver.h>
 
9
#include <noatunarts.h>
 
10
#include <ktempfile.h>
 
11
#include <qdom.h>
 
12
#include <netaccess.h>
 
13
#include <kstddirs.h>
 
14
#include <qtextstream.h>
 
15
#include <kstddirs.h>
 
16
#include <math.h>
 
17
#include <kconfig.h>
 
18
#include <klocale.h>
 
19
 
 
20
#define EQ napp->equalizer()
 
21
#define EQBACK napp->player()->engine()->equalizer()
 
22
 
 
23
using std::vector;
 
24
 
 
25
static QString makePresetFile()
 
26
{
 
27
        QString basedir=kapp->dirs()->localkdedir()+"/share/apps/noatun/eq.preset/";
 
28
        // now append a filename that doens't exist
 
29
        KStandardDirs::makeDir(basedir);
 
30
        QString fullpath;
 
31
        int num=0;
 
32
        do
 
33
        {
 
34
                if (num)
 
35
                        fullpath=basedir+"preset."+QString::number(num);
 
36
                else
 
37
                        fullpath=basedir+"preset";
 
38
                num++;
 
39
        }                       
 
40
        while (QFile(fullpath).exists());
 
41
        return fullpath;
 
42
}
 
43
 
 
44
Preset::Preset(const QString &file) : mFile(file)
 
45
{ }
 
46
 
 
47
Preset::Preset() : mFile(makePresetFile())
 
48
{ }
 
49
 
 
50
QString Preset::name() const
 
51
{
 
52
        QFile file(mFile);
 
53
        if (!file.open(IO_ReadOnly)) return 0;
 
54
 
 
55
        QDomDocument doc("noatunequalizer");
 
56
        if (!doc.setContent(&file)) return 0;
 
57
 
 
58
        QDomElement docElem = doc.documentElement();
 
59
        if (docElem.tagName()!="noatunequalizer") return 0;
 
60
        bool standard=docElem.attribute("default", "0")=="0";
 
61
        QString n=docElem.attribute("name", 0);
 
62
        
 
63
#if 0
 
64
        { // All the translations for the presets
 
65
                i18n("Trance");
 
66
                i18n("Dance");
 
67
                i18n("Metal");
 
68
                i18n("Jazz");
 
69
                i18n("Zero");
 
70
        }
 
71
#endif
 
72
        
 
73
        if (standard)
 
74
                n=i18n(n.local8Bit());
 
75
        
 
76
        return n;
 
77
}
 
78
 
 
79
bool Preset::setName(const QString &name)
 
80
{
 
81
        QList<Preset> presets=EQ->presets();
 
82
        for (Preset *i=presets.first(); i!=0; i=presets.next())
 
83
        {
 
84
                if (i==this) continue;
 
85
                if (i->name()==name)
 
86
                        return false;
 
87
        }
 
88
        
 
89
        QFile file(mFile);
 
90
        if (!file.open(IO_ReadOnly)) return 0;
 
91
 
 
92
        QDomDocument doc("noatunequalizer");
 
93
        if (!doc.setContent(&file)) return 0;
 
94
 
 
95
        QDomElement docElem = doc.documentElement();
 
96
        if (docElem.tagName()!="noatunequalizer") return 0;
 
97
 
 
98
        docElem.setAttribute("name", name);
 
99
 
 
100
        emit EQ->renamed(this);
 
101
        file.close();
 
102
        file.open(IO_ReadWrite | IO_Truncate);
 
103
        QTextStream s(&file);
 
104
        s << doc.toString();
 
105
        file.close();
 
106
 
 
107
        return true;
 
108
}
 
109
 
 
110
bool Preset::save() const
 
111
{
 
112
        return EQ->save(mFile, name());
 
113
}
 
114
 
 
115
bool Preset::load()
 
116
{
 
117
        bool b=EQ->load(mFile);
 
118
        if (b) emit EQ->changed(this);
 
119
        return b;
 
120
}
 
121
 
 
122
void Preset::remove()
 
123
{
 
124
        KConfig *config=kapp->config();
 
125
        config->setGroup("Equalizer");
 
126
        QStringList items=config->readListEntry("presets");
 
127
        items.remove(mFile);
 
128
        config->sync();
 
129
 
 
130
        emit EQ->removed(this);
 
131
 
 
132
        if (mFile.find(kapp->dirs()->localkdedir())==0)
 
133
        {
 
134
                QFile(mFile).remove();
 
135
        }
 
136
}
 
137
 
 
138
QString Preset::file() const
 
139
{
 
140
        return mFile;
 
141
}
 
142
 
 
143
 
 
144
Band::Band(int start, int end) : mLevel(0), mStart(start), mEnd(end)
 
145
{
 
146
        EQ->add(this);
 
147
        EQ->update();
 
148
        emit EQ->changed();
 
149
        emit EQ->changed(this);
 
150
}
 
151
 
 
152
Band::~Band()
 
153
{
 
154
        EQ->remove(this);
 
155
}
 
156
 
 
157
int Band::level()
 
158
{
 
159
        return mLevel;
 
160
}
 
161
 
 
162
void Band::setLevel(int l)
 
163
{
 
164
        mLevel=l;
 
165
        EQ->update();
 
166
        emit EQ->changed();
 
167
        emit EQ->changed(this);
 
168
}
 
169
 
 
170
int Band::start() const
 
171
{
 
172
        return mStart;
 
173
}
 
174
 
 
175
int Band::end() const
 
176
{
 
177
        return mEnd;
 
178
}
 
179
 
 
180
int Band::center() const
 
181
{
 
182
        return (mStart+mEnd)/2;
 
183
}
 
184
 
 
185
static QString formatFreq(int f, bool withHz)
 
186
{
 
187
        QString format;
 
188
        if (f<991)
 
189
                format=QString::number(f);
 
190
        else
 
191
                format=QString::number((int)((f+500)/1000.0))+"k";
 
192
 
 
193
        if (withHz)
 
194
                format+="Hz";
 
195
 
 
196
        return format;
 
197
}
 
198
 
 
199
QString Band::formatStart(bool withHz) const
 
200
{
 
201
        return formatFreq(mStart, withHz);
 
202
}
 
203
 
 
204
QString Band::formatEnd(bool withHz) const
 
205
{
 
206
        return formatFreq(mEnd, withHz);
 
207
}
 
208
 
 
209
QString Band::format(bool withHz) const
 
210
{
 
211
        return formatFreq(center(), withHz);
 
212
}
 
213
 
 
214
/* rate 4
 
215
27       54     0-108      108
 
216
81       163    109-217    108
 
217
243      514    218-810    269
 
218
729      1621   811-2431  1620
 
219
2187     4661   2432-7290 4858
 
220
6561     13645  7291+     12708
 
221
 
 
222
*/
 
223
Equalizer::Equalizer() : mUpdates(true)
 
224
{
 
225
}
 
226
 
 
227
void Equalizer::init()
 
228
{
 
229
        for (Band *i=mBands.first(); i!=0; i=mBands.next())
 
230
                delete i;
 
231
 
 
232
        {
 
233
                enableUpdates(false);
 
234
                new Band(0, 108);
 
235
                new Band(109, 217);
 
236
                new Band(218, 810);
 
237
                new Band(811, 2431);
 
238
                new Band(2432, 7290);
 
239
                new Band(7291, 19999);
 
240
 
 
241
                enableUpdates();
 
242
                setPreamp(0);
 
243
                update(true);
 
244
        }
 
245
        
 
246
        load(napp->dirs()->saveLocation("data", "noatun/") + "equalizer");
 
247
 
 
248
        KConfig *config=kapp->config();
 
249
        config->setGroup("Equalizer");
 
250
        setEnabled(config->readBoolEntry("enabled", false));
 
251
}
 
252
        
 
253
QList<Preset> Equalizer::presets() const
 
254
{
 
255
        KConfig *conf=KGlobal::config();
 
256
        conf->setGroup("Equalizer");
 
257
        
 
258
        QStringList list;
 
259
        if (conf->hasKey("presets"))
 
260
        {
 
261
                list=conf->readListEntry("presets");
 
262
        }
 
263
        else
 
264
        {
 
265
                list=kapp->dirs()->findAllResources("data", "noatun/eq.preset/*");
 
266
                conf->writeEntry("presets", list);
 
267
                conf->sync();
 
268
        }
 
269
        
 
270
        QList<Preset> presets;
 
271
 
 
272
        for (QStringList::Iterator i = list.begin(); i!=list.end(); ++i)
 
273
        {
 
274
                QFile file(*i);
 
275
                if (!file.open(IO_ReadOnly)) continue;
 
276
 
 
277
                QDomDocument doc("noatunequalizer");
 
278
                if (!doc.setContent(&file)) continue;
 
279
 
 
280
                QDomElement docElem = doc.documentElement();
 
281
                if (docElem.tagName()!="noatunequalizer") continue;
 
282
 
 
283
                presets.append(new Preset(*i));
 
284
        }
 
285
        return presets;
 
286
}
 
287
 
 
288
Preset *Equalizer::preset(const QString &file)
 
289
{
 
290
        KConfig *conf=KGlobal::config();
 
291
        conf->setGroup("Equalizer");
 
292
        QStringList list=kapp->config()->readListEntry("presets");
 
293
        if (list.contains(file))
 
294
                return new Preset(file);
 
295
        return 0;
 
296
}
 
297
 
 
298
bool Equalizer::presetExists(const QString &name) const
 
299
{
 
300
        QList<Preset> list=presets();
 
301
        for (Preset *i=list.first(); i!=0; i=list.next())
 
302
        {
 
303
                if (i->name()==name)
 
304
                        return true;
 
305
        }
 
306
        return false;
 
307
}
 
308
 
 
309
Preset *Equalizer::createPreset(const QString &name, bool smart)
 
310
{
 
311
        if (presetExists(name) && !smart) return 0;
 
312
        QString nameReal=name;
 
313
        {
 
314
                int number=1;
 
315
                while (presetExists(nameReal))
 
316
                {
 
317
                        nameReal=name+" ("+QString::number(number)+')';
 
318
                        number++;
 
319
                }
 
320
        }
 
321
        
 
322
        Preset *preset=new Preset;
 
323
        
 
324
        {
 
325
                save(preset->file(), nameReal);
 
326
                KConfig *config=kapp->config();
 
327
                config->setGroup("Equalizer");
 
328
                QStringList list=config->readListEntry("presets");
 
329
                list+=preset->file();
 
330
                config->writeEntry("presets", list);
 
331
                config->sync();
 
332
                
 
333
                emit created(preset);
 
334
                return preset;
 
335
        }
 
336
}
 
337
 
 
338
Equalizer::~Equalizer()
 
339
{
 
340
        save(napp->dirs()->saveLocation("data", "noatun/") + "equalizer", "auto");
 
341
        for (Band *i=mBands.first(); i!=0; i=mBands.next())
 
342
                delete i;
 
343
}
 
344
 
 
345
const QList<Band> &Equalizer::bands() const
 
346
{
 
347
        return mBands;
 
348
}
 
349
 
 
350
Band *Equalizer::band(int num) const
 
351
{
 
352
        // can't use QList::at since it sets current
 
353
 
 
354
        QListIterator<Band> item(mBands);
 
355
        item+=(unsigned int)num;
 
356
        return *item;
 
357
}
 
358
 
 
359
int Equalizer::bandCount() const
 
360
{
 
361
        return (int)mBands.count();
 
362
}
 
363
 
 
364
int Equalizer::preamp() const
 
365
{
 
366
        return mPreamp;
 
367
}
 
368
 
 
369
bool Equalizer::isEnabled() const
 
370
{
 
371
        return (bool)EQBACK->enabled();
 
372
 
 
373
}
 
374
 
 
375
void Equalizer::setPreamp(int p)
 
376
{
 
377
        mPreamp=p;
 
378
        EQBACK->preamp(pow(2,(float)p/100.0));
 
379
        emit changed();
 
380
        emit preampChanged();
 
381
        emit preampChanged(p);
 
382
}
 
383
 
 
384
void Equalizer::enable()
 
385
{
 
386
        setEnabled(true);
 
387
}
 
388
 
 
389
void Equalizer::disable()
 
390
{
 
391
        setEnabled(false);
 
392
}
 
393
 
 
394
void Equalizer::setEnabled(bool e)
 
395
{
 
396
        EQBACK->enabled((long)e);
 
397
        KConfig *config=kapp->config();
 
398
        config->setGroup("Equalizer");
 
399
        config->writeEntry("enabled", e);
 
400
        config->sync();
 
401
 
 
402
        emit enabled(e);
 
403
        if (e)
 
404
                emit enabled();
 
405
        else
 
406
                emit disabled();
 
407
}
 
408
 
 
409
bool Equalizer::save(const KURL &filename, const QString &name) const
 
410
{
 
411
        QDomDocument doc("noatunequalizer");
 
412
        doc.setContent(QString("<!DOCTYPE NoatunEqualizer><noatunequalizer/>"));
 
413
        QDomElement docElem = doc.documentElement();
 
414
 
 
415
        {
 
416
                docElem.setAttribute("level", preamp());
 
417
                docElem.setAttribute("name", name);
 
418
                docElem.setAttribute("version", napp->version());
 
419
        }
 
420
 
 
421
        for (QListIterator<Band> i(mBands); i.current(); ++i)
 
422
        {
 
423
                QDomElement elem = doc.createElement("band");
 
424
                elem.setAttribute("start", (*i)->start());
 
425
                elem.setAttribute("end", (*i)->end());
 
426
                elem.setAttribute("level", (*i)->level());
 
427
 
 
428
                docElem.appendChild(elem);
 
429
        }
 
430
 
 
431
        KTempFile file;
 
432
 
 
433
        *(file.textStream()) << doc.toString();
 
434
        file.close();
 
435
 
 
436
        return KIO::NetAccess::upload(file.name(), filename);
 
437
}
 
438
 
 
439
 
 
440
 
 
441
bool Equalizer::load(const KURL &filename)
 
442
{
 
443
        QString dest;
 
444
        if(KIO::NetAccess::download(filename, dest))
 
445
        {
 
446
                QFile file(dest);
 
447
                if (!file.open(IO_ReadOnly))
 
448
                        return false;
 
449
 
 
450
                QDomDocument doc("noatunequalizer");
 
451
                if (!doc.setContent(&file))
 
452
                        return false;
 
453
 
 
454
                QDomElement docElem = doc.documentElement();
 
455
                if (docElem.tagName()!="noatunequalizer")
 
456
                        return false;
 
457
 
 
458
                enableUpdates(false);
 
459
 
 
460
//              blockSignals(true);
 
461
                setPreamp(docElem.attribute("level", "0").toInt());
 
462
                Band *bandIter=mBands.first();
 
463
                for (QDomNode n = docElem.firstChild(); !n.isNull(); n = n.nextSibling())
 
464
                {
 
465
                        QDomElement e = n.toElement();
 
466
                        if(e.isNull()) continue;
 
467
                        if (e.tagName()!="band") continue;
 
468
 
 
469
//                      int start=e.attribute("start","0").toInt();
 
470
//                      int end=e.attribute("end", "108").toInt();
 
471
                        int level=e.attribute("level", "0").toInt();
 
472
                        bandIter->setLevel(level);
 
473
                        bandIter=mBands.next();
 
474
                }
 
475
                enableUpdates();
 
476
//              blockSignals(false);
 
477
                update(true);
 
478
//              emit changed();
 
479
                return true;
 
480
        }
 
481
        return false;
 
482
}
 
483
 
 
484
void Equalizer::add(Band *b)
 
485
{
 
486
        mBands.append(b);
 
487
}
 
488
 
 
489
void Equalizer::remove(Band *b)
 
490
{
 
491
        mBands.removeRef(b);
 
492
}
 
493
 
 
494
void Equalizer::update(bool full)
 
495
{
 
496
        if (!mUpdates)
 
497
                return;
 
498
 
 
499
        vector<float> levels;
 
500
        vector<float> mids;
 
501
        vector<float> widths;
 
502
 
 
503
        for (Band *i=mBands.first(); i!=0; i=mBands.next())
 
504
        {
 
505
                levels.push_back(pow(2, (float)i->mLevel/50.0));
 
506
                if (full)
 
507
                {
 
508
                        int mid=i->mStart+i->mEnd;
 
509
                        mids.push_back(((float)mid)*0.5);
 
510
                        widths.push_back((float)(i->mEnd-i->mStart));
 
511
                }
 
512
        }
 
513
        if (full)
 
514
                EQBACK->set(levels, mids, widths);
 
515
        else
 
516
                EQBACK->levels(levels);
 
517
}
 
518
 
 
519
void Equalizer::enableUpdates(bool on)
 
520
{
 
521
        mUpdates=on;
 
522
}
 
523
 
 
524
#undef EQ
 
525
#undef EQBACK
 
526
 
 
527
#include "equalizer.moc"
 
528