PageRenderTime 251ms CodeModel.GetById 141ms app.highlight 18ms RepoModel.GetById 90ms app.codeStats 0ms

/thirdparty/liblastfm2/src/fingerprint/contrib/main.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 173 lines | 122 code | 18 blank | 33 comment | 50 complexity | 9603d808b609322ac7f4357770d1061b MD5 | raw file
  1/*
  2   Copyright 2009 Last.fm Ltd. 
  3   Copyright 2009 John Stamp <jstamp@users.sourceforge.net>
  4
  5   This file is part of liblastfm.
  6
  7   liblastfm is free software: you can redistribute it and/or modify
  8   it under the terms of the GNU General Public License as published by
  9   the Free Software Foundation, either version 3 of the License, or
 10   (at your option) any later version.
 11
 12   liblastfm is distributed in the hope that it will be useful,
 13   but WITHOUT ANY WARRANTY; without even the implied warranty of
 14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15   GNU General Public License for more details.
 16
 17   You should have received a copy of the GNU General Public License
 18   along with liblastfm.  If not, see <http://www.gnu.org/licenses/>.
 19*/
 20
 21// ubuntu 9.04: sudo apt-get install libmad0-dev libvorbis-dev libflac-dev libfaac-dev
 22// macports: sudo port install libmad libvorbis libflac
 23// Windows: lol
 24
 25#include "MadSource.h"
 26#include "VorbisSource.h"
 27#include "FlacSource.h"
 28#include "AacSource.h"
 29#include <lastfm.h>
 30#include <QCoreApplication>
 31#include <QFile>
 32#include <QStringList>
 33#include <iostream>
 34int typeOf(const QString& path);
 35lastfm::FingerprintableSource* factory(int type);
 36enum { MP3, OGG, FLAC, AAC, UNKNOWN };
 37namespace lastfm { Track taglib(const QString& path); }
 38
 39
 40int main(int argc, char** argv) try
 41{
 42    if (argc < 2) {
 43        std::cerr << "usage: " << argv[0] << " path" << std::endl;
 44        return 1;
 45    }
 46 
 47    QCoreApplication app(argc, argv);
 48    QEventLoop loop;
 49    
 50    QString const path = QFile::decodeName(argv[1]);
 51    
 52    lastfm::Track t = lastfm::taglib(path); //see contrib //TODO mbid
 53    lastfm::Fingerprint fp(t);
 54    if (fp.id().isNull()) {
 55        lastfm::FingerprintableSource* src = factory(typeOf(path));
 56        fp.generate(src);
 57        QNetworkReply* reply = fp.submit();
 58        loop.connect(reply, SIGNAL(finished()), SLOT(quit()));
 59        fp.decode(reply);
 60    }
 61    
 62    QNetworkReply* reply = fp.id().getSuggestions();
 63    loop.connect(reply, SIGNAL(finished()), SLOT(quit()));
 64    
 65    std::cout << reply->readAll().data() << std::endl; //returns XML
 66    return 0;
 67}
 68catch (std::exception& e)
 69{
 70    std::cerr << e.what() << std::endl;
 71}
 72
 73lastfm::FingerprintableSource* factory(int type)
 74{
 75    switch (type) {
 76        case MP3: return new MadSource;
 77        case OGG: return new VorbisSource;
 78        case FLAC: return new FlacSource;
 79    #ifndef MACPORTS_SUCKS
 80        case AAC: return new AacSource;
 81    #endif
 82        default: throw std::runtime_error("Cannot handle filetype");
 83    }
 84}
 85
 86int typeOf(const QString& fileName)
 87{
 88    QStringList parts = fileName.split( "." );
 89    QString extension;
 90    if ( parts.size() > 1 )
 91        extension = parts.last();
 92
 93    // Let's be trusting about extensions
 94    if ( extension.toLower() == "mp3" )
 95        return MP3;
 96    else if ( extension.toLower() == "ogg" )
 97        return OGG;
 98    else if ( extension.toLower() == "oga" )
 99        return FLAC;
100    else if ( extension.toLower() == "flac" )
101        return FLAC;
102    else if ( extension.toLower() == "aac" )
103        return AAC;
104    else if ( extension.toLower() == "m4a" )
105        return AAC;
106
107    // So much for relying on extensions.  Let's try file magic instead.
108    FILE *fp = NULL;
109    unsigned char header[35];
110
111    fp = fopen(QFile::encodeName(fileName), "rb");
112    if ( !fp )
113    {
114        return UNKNOWN;
115    }
116    int fType = UNKNOWN;
117    fread( header, 1, 35, fp );
118
119    // Some formats can have ID3 tags (or not), so let's just
120    // get them out of the way first before we check what we have.
121    if ( memcmp( header, "ID3", 3) == 0 )
122    {
123        int tagsize = 0;
124        /* high bit is not used */
125        tagsize = (header[6] << 21) | (header[7] << 14) |
126            (header[8] <<  7) | (header[9] <<  0);
127
128        tagsize += 10;
129        fseek( fp, tagsize, SEEK_SET );
130        fread( header, 1, 35, fp );
131    }
132
133    if ( (header[0] == 0xFF) && ((header[1] & 0xFE) == 0xFA ) )
134    {
135        fType = MP3;
136    }
137    else if ( memcmp(header, "OggS", 4) == 0 )
138    {
139        if ( memcmp(&header[29], "vorbis", 6) == 0 )
140        {
141            // ogg vorbis (.ogg)
142            fType = OGG;
143        }
144        else if ( memcmp(&header[29], "FLAC", 4) == 0 )
145        {
146            // ogg flac (.oga)
147            fType = FLAC;
148        }
149    }
150    else if ( memcmp(header, "fLaC", 4 ) == 0 )
151    {
152        // flac file
153        fType = FLAC;
154    }
155    else if ( (header[0] == 0xFF) && ((header[1] & 0xF6) == 0xF0) )
156    {
157        // aac adts
158        fType = AAC;
159    }
160    else if (memcmp(header, "ADIF", 4) == 0)
161    {
162        // aac adif
163        fType = AAC;
164    }
165    else if ( memcmp( &header[4], "ftyp", 4 ) == 0 )
166    {
167        // mp4 header: aac
168        fType = AAC;
169    }
170
171    fclose(fp);
172    return fType;
173}