aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
Commit message (Collapse)AuthorAgeFilesLines
* ladspa: removed RTLD_DEEPBIND usagetrialuser022016-01-021-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5956 90c681e8-e032-0410-971d-27865f9a5e38
* ladspa: fixed multiband eq (1197) support (#416)trialuser022016-01-011-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5949 90c681e8-e032-0410-971d-27865f9a5e38
* qsui: fixed analyzertrialuser022015-12-281-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5934 90c681e8-e032-0410-971d-27865f9a5e38
* mpc: using float outputtrialuser022015-12-272-38/+8
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5920 90c681e8-e032-0410-971d-27865f9a5e38
* opus: using float outputtrialuser022015-12-272-6/+5
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5919 90c681e8-e032-0410-971d-27865f9a5e38
* using float output in the mpeg and vorbis pluginstrialuser022015-12-274-195/+18
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5917 90c681e8-e032-0410-971d-27865f9a5e38
* enabled replay gain scannertrialuser022015-12-273-102/+41
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5913 90c681e8-e032-0410-971d-27865f9a5e38
* fixed regressiontrialuser022015-12-271-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5904 90c681e8-e032-0410-971d-27865f9a5e38
* enabled projectm plugintrialuser022015-12-274-42/+23
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5903 90c681e8-e032-0410-971d-27865f9a5e38
* ported analyzer plugintrialuser022015-12-277-42/+61
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5902 90c681e8-e032-0410-971d-27865f9a5e38
* ported all effect pluginstrialuser022015-12-2710-118/+74
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5899 90c681e8-e032-0410-971d-27865f9a5e38
* enabled src plugintrialuser022015-12-274-52/+19
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5898 90c681e8-e032-0410-971d-27865f9a5e38
* enabled bs2b plugintrialuser022015-12-274-24/+8
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5897 90c681e8-e032-0410-971d-27865f9a5e38
* disabled visual pluginstrialuser022015-12-261-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5893 90c681e8-e032-0410-971d-27865f9a5e38
* qsui: fixed buildtrialuser022015-12-268-60/+83
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5886 90c681e8-e032-0410-971d-27865f9a5e38
* changed visual api, disabled broken pluginstrialuser022015-12-269-76/+80
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5885 90c681e8-e032-0410-971d-27865f9a5e38
* removed Decoder::hasHeadroom functiontrialuser022015-12-245-6/+6
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5881 90c681e8-e032-0410-971d-27865f9a5e38
* changed buffer.h apitrialuser022015-12-222-9/+9
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5874 90c681e8-e032-0410-971d-27865f9a5e38
* mplayer engine: added error handlingtrialuser022015-12-142-14/+24
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5828 90c681e8-e032-0410-971d-27865f9a5e38
* fixed ffmpeg_legacy plugintrialuser022015-12-062-2/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5821 90c681e8-e032-0410-971d-27865f9a5e38
* using unsigned char for raw datatrialuser022015-12-0632-40/+40
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5820 90c681e8-e032-0410-971d-27865f9a5e38
* skinned: disable "Anti-aliasing" action on normal sizetrialuser022015-12-051-0/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5815 90c681e8-e032-0410-971d-27865f9a5e38
* updated Russian translationtrialuser022015-12-051-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5813 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022015-12-0552-1924/+2054
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5812 90c681e8-e032-0410-971d-27865f9a5e38
* skinned: added feature to disable anti-aliasingtrialuser022015-12-055-1/+10
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5810 90c681e8-e032-0410-971d-27865f9a5e38
* building of .app package for MacOS X with CMake (patch by Ivan Ponomarev)trialuser022015-12-0463-67/+68
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5807 90c681e8-e032-0410-971d-27865f9a5e38
* fixed mp3 cover issue (#828)trialuser022015-11-281-0/+12
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5797 90c681e8-e032-0410-971d-27865f9a5e38
* renamed resourcetrialuser022015-11-273-4/+4
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5793 90c681e8-e032-0410-971d-27865f9a5e38
* qsui: fixed equalizer trackingtrialuser022015-11-271-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5792 90c681e8-e032-0410-971d-27865f9a5e38
* refactoringtrialuser022015-11-172-48/+34
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5789 90c681e8-e032-0410-971d-27865f9a5e38
* fixed skin parsingtrialuser022015-11-141-6/+7
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5778 90c681e8-e032-0410-971d-27865f9a5e38
* fixed macports libraries detection on MacOS X (Ivan Ponomarev)trialuser022015-11-131-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5766 90c681e8-e032-0410-971d-27865f9a5e38
* updated German translation (Ettore Atalan)trialuser022015-11-121-8/+8
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5764 90c681e8-e032-0410-971d-27865f9a5e38
* updated Portuguese translation (Sérgio Marques)trialuser022015-11-121-8/+8
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5763 90c681e8-e032-0410-971d-27865f9a5e38
* updated .ts filestrialuser022015-11-1226-156/+156
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5762 90c681e8-e032-0410-971d-27865f9a5e38
* reduced CPU loading in Qt Multimedia output module (patch by Ivan Ponomarev)trialuser022015-11-122-2/+18
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5759 90c681e8-e032-0410-971d-27865f9a5e38
* updated Ukrainian translationsmotsyo2015-11-111-7/+7
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5758 90c681e8-e032-0410-971d-27865f9a5e38
* fixed 'hide on close' featuretrialuser022015-11-111-0/+5
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5752 90c681e8-e032-0410-971d-27865f9a5e38
* fixed cmake scriptstrialuser022015-11-111-2/+6
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5746 90c681e8-e032-0410-971d-27865f9a5e38
* fixed qmake filestrialuser022015-11-111-2/+3
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5745 90c681e8-e032-0410-971d-27865f9a5e38
* fixed build without QtMultimedia moduletrialuser022015-11-111-2/+4
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5744 90c681e8-e032-0410-971d-27865f9a5e38
* added .ts filestrialuser022015-11-1125-5/+1109
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5742 90c681e8-e032-0410-971d-27865f9a5e38
* adding support of Qt Multimedia output (patch by Ivan Ponomarev)trialuser022015-11-1114-0/+699
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5741 90c681e8-e032-0410-971d-27865f9a5e38
* fixed Dutch translation (patch by Rhythmdrill, see #825); updated .ts filestrialuser022015-11-0326-598/+598
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5735 90c681e8-e032-0410-971d-27865f9a5e38
* rgscan: fixed segmentation faulttrialuser022015-10-271-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5729 90c681e8-e032-0410-971d-27865f9a5e38
* skinned: fixed geometry saving bugtrialuser022015-10-246-9/+15
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5722 90c681e8-e032-0410-971d-27865f9a5e38
* refactoringtrialuser022015-10-243-18/+18
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5721 90c681e8-e032-0410-971d-27865f9a5e38
* improved function MetaDataFormatter::formatLengthtrialuser022015-10-171-4/+2
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5700 90c681e8-e032-0410-971d-27865f9a5e38
* qsui: fixed time indicatortrialuser022015-10-171-1/+3
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5696 90c681e8-e032-0410-971d-27865f9a5e38
* fixed crash in the mplayer enginetrialuser022015-10-141-1/+1
| | | | git-svn-id: http://svn.code.sf.net/p/qmmp-dev/code/trunk/qmmp@5677 90c681e8-e032-0410-971d-27865f9a5e38
='alt'>
4b94c1347
26724c66d
06d187781
26724c66d

06d187781
26724c66d




















12746dbfb















06d187781
2e50594a7

525d822be
45117f6d2


2d622fd9b

7586a6542
2d622fd9b
4beb7f075
2d622fd9b



4beb7f075

2d622fd9b









7d2e0f57b
acb3d9b6c
2d622fd9b





f0a1d05ed
2d622fd9b



72d49c830
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
                                                                            
                                                                            














                                                                            
                                                                            

                                                                             


                      
                
                



                            
                          

                            


                                                                                              
                              
                             

                           



                              













                                                                         


                                                             
                                                        
                    








                                                                     
                        

         
                 

 
                                                         
 












                                                                        
                                                                    
                                                 
             
                                           
     
                 

 
                                                             
 
                                 
                                        
                                 
                                                                   
                                              
                                                           

                                  
                      

 
                                                                        
 



                                         
                                                        

             

 
                                                                                                             
 
                                            
                         




                                                                                              
                                                                    
      
 

                    
                                                                     
                                   
 
                              
 



                                                                                 
 
                        
                                   
         


                                        



                                                                                              
                                       






                                                                               
                                     
                                                           

                                       
                                          

                      

                                       
         

                            

                                                       
 
                   
                                                       

                         
         




















                                                                                  















                                                                                                         
         

                                  
                                                             


                           

 
                                                                                           
 
                                                               



                                                     

                                                                    









                                                                            
                                                                                  
                                                                           





                                                                 
                                              



                                                        
                                        
/***************************************************************************
 *   Copyright (C) 2008-2015 by Ilya Kotov                                 *
 *   forkotov02@hotmail.ru                                                 *
 *                                                                         *
 *   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 <QtGui>
#include <QDialog>
#include <QMessageBox>
#include <QFile>
#include <mad.h>
#include <taglib/tag.h>
#include <taglib/fileref.h>
#include <taglib/id3v1tag.h>
#include <taglib/id3v2tag.h>
#include <taglib/apetag.h>
#include <taglib/tfile.h>
#include <taglib/mpegfile.h>
#if (TAGLIB_MAJOR_VERSION > 1) || ((TAGLIB_MAJOR_VERSION == 1) && (TAGLIB_MINOR_VERSION >= 8))
#include <taglib/tfilestream.h>
#endif
#include "mpegmetadatamodel.h"
#include "replaygainreader.h"
#include "settingsdialog.h"
#include "decoder_mad.h"
#include "decodermadfactory.h"

// DecoderMADFactory

DecoderMADFactory::DecoderMADFactory()
{
    //detecting rusxmms patch
    m_using_rusxmms = false;
    char str[] = { char(0xF2), char(0xE5), char(0xF1), char(0xF2), '\0'};
    QTextCodec *codec = QTextCodec::codecForName ("windows-1251");
    TagLib::String tstr(str);
    if(codec->toUnicode(str) == QString::fromUtf8(tstr.toCString(true)))
    {
        qDebug("DecoderMADFactory: found taglib with rusxmms patch");
        m_using_rusxmms = true;
    }
}

bool DecoderMADFactory::supports(const QString &source) const
{
    QString ext = source.right(4).toLower();
    if (ext == ".mp1" || ext == ".mp2" || ext == ".mp3")
        return true;
    else if (ext == ".wav") //check for mp3 wav files
    {
        QFile file(source);
        file.open(QIODevice::ReadOnly);
        char buf[22];
        file.peek(buf,sizeof(buf));
        file.close();
        if (!memcmp(buf + 8, "WAVE", 4) && !memcmp(buf + 20, "U" ,1))
        {
            return true;
        }
    }
    return false;
}

bool DecoderMADFactory::canDecode(QIODevice *input) const
{
    char buf[16 * 512];

    if (input->peek(buf,sizeof(buf)) == sizeof(buf))
    {
        struct mad_stream stream;
        struct mad_header header;
        int dec_res;

        mad_stream_init (&stream);
        mad_header_init (&header);
        mad_stream_buffer (&stream, (unsigned char *) buf, sizeof(buf));
        stream.error = MAD_ERROR_NONE;

        while ((dec_res = mad_header_decode(&header, &stream)) == -1
                && MAD_RECOVERABLE(stream.error))
            ;
        return dec_res != -1 ? true: false;
    }
    return false;
}

const DecoderProperties DecoderMADFactory::properties() const
{
    DecoderProperties properties;
    properties.name = tr("MPEG Plugin");
    properties.shortName = "mad";
    properties.filters << "*.mp1" << "*.mp2" << "*.mp3" << "*.wav";
    properties.description = tr("MPEG Files");
    properties.contentTypes << "audio/mp3" << "audio/mpeg";
    properties.hasAbout = true;
    properties.hasSettings = true;
    return properties;
}

Decoder *DecoderMADFactory::create(const QString &url, QIODevice *input)
{
    Decoder *d = new DecoderMAD(input);
    if(!url.contains("://")) //local file
    {
        ReplayGainReader rg(url);
        d->setReplayGainInfo(rg.replayGainInfo(), true);
    }
    return d;
}

QList<FileInfo *> DecoderMADFactory::createPlayList(const QString &fileName, bool useMetaData, QStringList *)
{
    FileInfo *info = new FileInfo(fileName);
    TagLib::Tag *tag = 0;

#if (TAGLIB_MAJOR_VERSION > 1) || ((TAGLIB_MAJOR_VERSION == 1) && (TAGLIB_MINOR_VERSION >= 8))
    TagLib::FileStream stream(fileName.toLocal8Bit().constData(), true);
    TagLib::MPEG::File fileRef(&stream, TagLib::ID3v2::FrameFactory::instance());
#else
    TagLib::MPEG::File fileRef(fileName.toLocal8Bit ().constData());
#endif

    if (useMetaData)
    {
        QSettings settings(Qmmp::configFile(), QSettings::IniFormat);
        settings.beginGroup("MAD");

        QTextCodec *codec = 0;

        uint tag_array[3];
        tag_array[0] = settings.value("tag_1", SettingsDialog::ID3v2).toInt();
        tag_array[1] = settings.value("tag_2", SettingsDialog::Disabled).toInt();
        tag_array[2] = settings.value("tag_3", SettingsDialog::Disabled).toInt();

        QByteArray name;
        for (int i = 0; i < 3; ++i)
        {
            switch ((uint) tag_array[i])
            {
            case SettingsDialog::ID3v1:
                codec = QTextCodec::codecForName(settings.value("ID3v1_encoding","ISO-8859-1")
                                                 .toByteArray ());
                tag = fileRef.ID3v1Tag();
                break;
            case SettingsDialog::ID3v2:
                name = settings.value("ID3v2_encoding","UTF-8").toByteArray ();
                if (name.contains("UTF"))
                    codec = QTextCodec::codecForName ("UTF-8");
                else
                    codec = QTextCodec::codecForName(name);
                tag = fileRef.ID3v2Tag();
                break;
            case SettingsDialog::APE:
                codec = QTextCodec::codecForName ("UTF-8");
                tag = fileRef.APETag();
                break;
            case SettingsDialog::Disabled:
                break;
            }
            if (tag && !tag->isEmpty())
                break;
        }
        settings.endGroup();

        if(m_using_rusxmms)
            codec = QTextCodec::codecForName ("UTF-8");

        if (!codec)
            codec = QTextCodec::codecForName ("UTF-8");

        if (tag && codec)
        {
            bool utf = codec->name ().contains("UTF");
            TagLib::String album = tag->album();
            TagLib::String artist = tag->artist();
            TagLib::String comment = tag->comment();
            TagLib::String genre = tag->genre();
            TagLib::String title = tag->title();

            info->setMetaData(Qmmp::ALBUM,
                              codec->toUnicode(album.toCString(utf)).trimmed());
            info->setMetaData(Qmmp::ARTIST,
                              codec->toUnicode(artist.toCString(utf)).trimmed());
            info->setMetaData(Qmmp::COMMENT,
                              codec->toUnicode(comment.toCString(utf)).trimmed());
            info->setMetaData(Qmmp::GENRE,
                              codec->toUnicode(genre.toCString(utf)).trimmed());
            info->setMetaData(Qmmp::TITLE,
                              codec->toUnicode(title.toCString(utf)).trimmed());
            info->setMetaData(Qmmp::YEAR,
                              tag->year());
            info->setMetaData(Qmmp::TRACK,
                              tag->track());

            if(tag == fileRef.ID3v2Tag())
            {
                if(!fileRef.ID3v2Tag()->frameListMap()["TCOM"].isEmpty())
                {
                    TagLib::String composer;
                    composer = fileRef.ID3v2Tag()->frameListMap()["TCOM"].front()->toString();
                    info->setMetaData(Qmmp::COMPOSER,
                                      codec->toUnicode(composer.toCString(utf)).trimmed());
                }
                if(!fileRef.ID3v2Tag()->frameListMap()["TPOS"].isEmpty())
                {
                    TagLib::String disc = fileRef.ID3v2Tag()->frameListMap()["TPOS"].front()->toString();
                    info->setMetaData(Qmmp::DISCNUMBER, QString(disc.toCString()).trimmed());
                }
            }
        }
    }
    if (fileRef.audioProperties())
        info->setLength(fileRef.audioProperties()->length());
    QList <FileInfo*> list;
    list << info;
    return list;
}

MetaDataModel* DecoderMADFactory::createMetaDataModel(const QString &path, QObject *parent)
{
   return new MPEGMetaDataModel(m_using_rusxmms, path, parent);
}

void DecoderMADFactory::showSettings(QWidget *parent)
{
    SettingsDialog *s = new SettingsDialog(m_using_rusxmms, parent);
    s->show();
}

void DecoderMADFactory::showAbout(QWidget *parent)
{
    QMessageBox::about (parent, tr("About MPEG Audio Plugin"),
                        tr("Qmmp MPEG Audio Plugin")+"\n"+
                        tr("Compiled against libmad version:")+" "+
                        QString("%1.%2.%3%4").arg(MAD_VERSION_MAJOR)
                        .arg(MAD_VERSION_MINOR)
                        .arg(MAD_VERSION_PATCH).arg(MAD_VERSION_EXTRA)+"\n"+
                        tr("Written by: Ilya Kotov <forkotov02@hotmail.ru>")+"\n"+
                        tr("Source code based on mq3 and madplay projects")
                       );
}

QTranslator *DecoderMADFactory::createTranslator(QObject *parent)
{
    QTranslator *translator = new QTranslator(parent);
    QString locale = Qmmp::systemLanguageID();
    translator->load(QString(":/mad_plugin_") + locale);
    return translator;
}

Q_EXPORT_PLUGIN2(mad, DecoderMADFactory)