PageRenderTime 37ms CodeModel.GetById 5ms RepoModel.GetById 0ms app.codeStats 1ms

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