From 83bf3339d97c9eda0e9ea9df45e4905a3623839f Mon Sep 17 00:00:00 2001 From: "craig.p.drummond" Date: Fri, 12 Jul 2013 19:29:34 +0000 Subject: [PATCH] Remove lame usage, its not actually required for audio cd playback! --- CMakeLists.txt | 24 ++------- ChangeLog | 1 + README | 21 ++++---- cmake/FindLame.cmake | 14 ------ config.h.cmake | 1 - devices/extractjob.cpp | 31 +++++++++--- devices/extractjob.h | 3 +- http/httpsocket.cpp | 107 +++++++++++++++++------------------------ 8 files changed, 85 insertions(+), 117 deletions(-) delete mode 100644 cmake/FindLame.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f1cf8793..16c40a5c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,6 @@ option(ENABLE_OVERLAYSCROLLBARS "Enable support for overlay style scrollbars whe option(ENABLE_CDPARANOIA "Enable CDParanoia libraries(required for AudioCD support)" ON) option(ENABLE_CDDB "Enable CDDB libraries(either this or MusicBrianz required for AudioCD support)" ON) option(ENABLE_MUSICBRAINZ "Enable MusicBrianz libraries(either this or CDDB required for AudioCD support)" ON) -option(ENABLE_LAME "Enable LAME libraries(required for AudioCD playback support)" ON) option(ENABLE_PROXY_CONFIG "Enable proxy config in settings dialog" OFF) if (ENABLE_QT5) @@ -148,9 +147,6 @@ if (ENABLE_TAGLIB) if (ENABLE_MUSICBRAINZ) find_package(MusicBrainz5) endif (ENABLE_MUSICBRAINZ) - if (ENABLE_LAME) - find_package(Lame) - endif (ENABLE_LAME) endif (CDPARANOIA_FOUND) endif (TAGLIB_FOUND AND ENABLE_CDPARANOIA) endif (ENABLE_TAGLIB) @@ -495,13 +491,9 @@ else (WIN32) target_link_libraries(cantata ${MUSICBRAINZ5_LIBRARIES}) include_directories(${MUSICBRAINZ5_INCLUDE_DIR}) endif (MUSICBRAINZ5_FOUND) - if (LAME_FOUND) - target_link_libraries(cantata ${LAME_LIBS}) - include_directories(${LAME_INCLUDE_DIR}) - if (ENABLE_KDE_SUPPORT) - install(FILES cantata-play-audiocd.desktop DESTINATION ${DATA_INSTALL_DIR}/solid/actions) - endif (ENABLE_KDE_SUPPORT) - endif (LAME_FOUND) + if (ENABLE_KDE_SUPPORT) + install(FILES cantata-play-audiocd.desktop DESTINATION ${DATA_INSTALL_DIR}/solid/actions) + endif (ENABLE_KDE_SUPPORT) endif (CDDB_FOUND OR MUSICBRAINZ5_FOUND) endif (WIN32) @@ -584,9 +576,6 @@ if (TAGLIB_FOUND) endif (MTP_FOUND) if (CDDB_FOUND OR MUSICBRAINZ5_FOUND) message(" - AudioCD") - if (LAME_FOUND) - message(" - AudioCD playback via MP3") - endif (LAME_FOUND) endif (CDDB_FOUND OR MUSICBRAINZ5_FOUND) if (ENABLE_REMOTE_DEVICES) message(" - Remote device sync (EXPERIMENTAL)") @@ -602,7 +591,7 @@ if (TAGLIB_FOUND) endif (ENABLE_PROXY_CONFIG) endif (ENABLE_REMOTE_DEVICES OR ENABLE_HTTP_STREAM_PLAYBACK OR AUDIOCD_SUPPORT OR MTP_FOUND OR ENABLE_PROXY_CONFIG OR ENABLE_REPLAYGAIN_SUPPORT) - if (NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT AUDIOCD_SUPPORT OR NOT ENABLE_REPLAYGAIN_SUPPORT OR NOT ENABLE_HTTP_STREAM_PLAYBACK OR NOT ENABLE_REMOTE_DEVICES OR (NOT ENABLE_PROXY_CONFIG AND NOT ENABLE_KDE_SUPPORT) OR (AUDIOCD_SUPPORT AND NOT LAME_FOUND)) + if (NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT AUDIOCD_SUPPORT OR NOT ENABLE_REPLAYGAIN_SUPPORT OR NOT ENABLE_HTTP_STREAM_PLAYBACK OR NOT ENABLE_REMOTE_DEVICES OR (NOT ENABLE_PROXY_CONFIG AND NOT ENABLE_KDE_SUPPORT)) message(" Disabled features:") if (NOT ENABLE_HTTP_STREAM_PLAYBACK) message(" - MPD HTTP stream playback (Phonon required for Qt4, QtMultiMedia for Qt5)") @@ -613,9 +602,6 @@ if (TAGLIB_FOUND) if (NOT AUDIOCD_SUPPORT AND NOT WIN32) message(" - AudioCD (libcdparanoia and libcddb/libmusicbrainz5 required)") endif (NOT AUDIOCD_SUPPORT AND NOT WIN32) - if (AUDIOCD_SUPPORT AND NOT LAME_FOUND) - message(" - AudioCD playback via MP3 (liblame required)") - endif (AUDIOCD_SUPPORT AND NOT LAME_FOUND) if (NOT ENABLE_REMOTE_DEVICES) message(" - Remote device sync (EXPERIMENTAL)") endif (NOT ENABLE_REMOTE_DEVICES) @@ -625,7 +611,7 @@ if (TAGLIB_FOUND) if (NOT ENABLE_PROXY_CONFIG AND NOT ENABLE_KDE_SUPPORT) message(" - Proxy configuration") endif (NOT ENABLE_PROXY_CONFIG AND NOT ENABLE_KDE_SUPPORT) - endif (NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT AUDIOCD_SUPPORT OR NOT ENABLE_REPLAYGAIN_SUPPORT OR NOT ENABLE_HTTP_STREAM_PLAYBACK OR NOT ENABLE_REMOTE_DEVICES OR (NOT ENABLE_PROXY_CONFIG AND NOT ENABLE_KDE_SUPPORT) OR (AUDIOCD_SUPPORT AND NOT LAME_FOUND)) + endif (NOT TAGLIB_FOUND OR NOT MTP_FOUND OR NOT AUDIOCD_SUPPORT OR NOT ENABLE_REPLAYGAIN_SUPPORT OR NOT ENABLE_HTTP_STREAM_PLAYBACK OR NOT ENABLE_REMOTE_DEVICES OR (NOT ENABLE_PROXY_CONFIG AND NOT ENABLE_KDE_SUPPORT)) else (TAGLIB_FOUND) diff --git a/ChangeLog b/ChangeLog index c0be4b0e0..70d31c9b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -113,6 +113,7 @@ 71. Allow seeking in cantata HTTP streams. 72. Default to enabling use of media keys under GNOME/Unity. 73. Add SoundCloud to online services. +74. Drop usage of lame when playing back AudioCDs, its not required. 1.0.3 ----- diff --git a/README b/README index 8d1d2ace3..0411b94bd 100644 --- a/README +++ b/README @@ -19,17 +19,16 @@ Cantata requires the following Qt libraries: Cantata may also use the following optional libraries: - 1. KDElibs4 - 2. TagLib - Tag edit dialog, replaygain, track organizer, and UMS device - support. - 3. LibMTP - MTP devices. - 4. FFMPEG (libavcodec) - ReplayGain detection code. - 5. SpeexDSP - ReplayGain detection code. - 6. MPG123 - ReplayGain detection code. - 7. CDParanoia - Read/rip Audio CDs. - 8. CDDB - either this or MusicBrainz5 required for Audio CDs - 9. MusicBrainz5 - either this or CDDB required for Audio CDs -10. Lame - Encode Audio CD streams when sent via HTTP server. +1. KDElibs4 +2. TagLib - Tag edit dialog, replaygain, track organizer, and UMS device + support. +3. LibMTP - MTP devices. +4. FFMPEG (libavcodec) - ReplayGain detection code. +5. SpeexDSP - ReplayGain detection code. +6. MPG123 - ReplayGain detection code. +7. CDParanoia - Read/rip Audio CDs. +8. CDDB - either this or MusicBrainz5 required for Audio CDs +9. MusicBrainz5 - either this or CDDB required for Audio CDs Translations diff --git a/cmake/FindLame.cmake b/cmake/FindLame.cmake deleted file mode 100644 index 3ddc752d0..000000000 --- a/cmake/FindLame.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# - Try to find LAME -# Once done this will define -# -# LAME_FOUND - system has UDev -# LAME_INCLUDE_DIR - the libudev include directory -# LAME_LIBS - The libudev libraries - -find_path(LAME_INCLUDE_DIR lame/lame.h) -find_library(LAME_LIBS mp3lame) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LAME DEFAULT_MSG LAME_INCLUDE_DIR LAME_LIBS) - -mark_as_advanced(LAME_INCLUDE_DIR LAME_LIBS) diff --git a/config.h.cmake b/config.h.cmake index 3e94e581d..53c5ae6b4 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -25,7 +25,6 @@ #cmakedefine ENABLE_HTTP_STREAM_PLAYBACK 1 #cmakedefine FFMPEG_FOUND 1 #cmakedefine MPG123_FOUND 1 -#cmakedefine LAME_FOUND 1 #cmakedefine CDDB_FOUND 1 #cmakedefine MUSICBRAINZ5_FOUND 1 #cmakedefine USE_SPEEX_RESAMPLER 1 diff --git a/devices/extractjob.cpp b/devices/extractjob.cpp index 76d757e43..e99cfd22f 100644 --- a/devices/extractjob.cpp +++ b/devices/extractjob.cpp @@ -32,22 +32,37 @@ #include #include -void ExtractJob::writeWavHeader(QIODevice &dev) +const int ExtractJob::constWavHeaderSize=44; // ffmpeg uses 46 byte header? + +static void insertSize(unsigned char *data, qint32 size) { - static const unsigned char riffHeader[] = { + data[0]=(size&0x000000ff); + data[1]=(size&0x0000ff00)>>8; + data[2]=(size&0x00ff0000)>>16; + data[3]=(size&0xff000000)>>24; +} + +void ExtractJob::writeWavHeader(QIODevice &dev, qint32 size) +{ + unsigned char riffHeader[] = { 0x52, 0x49, 0x46, 0x46, // 0 "RIFF" 0x00, 0x00, 0x00, 0x00, // 4 wavSize 0x57, 0x41, 0x56, 0x45, // 8 "WAVE" 0x66, 0x6d, 0x74, 0x20, // 12 "fmt " - 0x10, 0x00, 0x00, 0x00, // 16 - 0x01, 0x00, 0x02, 0x00, // 20 - 0x44, 0xac, 0x00, 0x00, // 24 - 0x10, 0xb1, 0x02, 0x00, // 28 - 0x04, 0x00, 0x10, 0x00, // 32 - 0x64, 0x61, 0x74, 0x61, // 36 "data" + 0x10, 0x00, 0x00, 0x00, // 16 Size of WAVE section chunk (ffmpeg has 12 here???) + 0x01, 0x00, 0x02, 0x00, // 20 WAVE type format / Number of channels + 0x44, 0xac, 0x00, 0x00, // 24 Samples per second + 0x10, 0xb1, 0x02, 0x00, // 28 Bytes per second + 0x04, 0x00, 0x10, 0x00, // 32 Block alignment / Bits per sample + 0x64, 0x61, 0x74, 0x61, // 36 "data" (ffmpeg preceeds this with two 0 bytes) 0x00, 0x00, 0x00, 0x00 // 40 byteCount }; + if (0!=size) { + insertSize(&riffHeader[4], (size+constWavHeaderSize)-8); + insertSize(&riffHeader[40], size); + } + dev.write((char*)riffHeader, 44); } diff --git a/devices/extractjob.h b/devices/extractjob.h index 91882982e..3793fe4c9 100644 --- a/devices/extractjob.h +++ b/devices/extractjob.h @@ -32,7 +32,8 @@ class ExtractJob : public FileJob { Q_OBJECT public: - static void writeWavHeader(QIODevice &dev); + static const int constWavHeaderSize; + static void writeWavHeader(QIODevice &dev, qint32 size=0); explicit ExtractJob(const Encoders::Encoder &enc, int val, const QString &src, const QString &dest, const Song &s, const QString &cover); virtual ~ExtractJob(); diff --git a/http/httpsocket.cpp b/http/httpsocket.cpp index a4b122e4c..1291c4a7e 100644 --- a/http/httpsocket.cpp +++ b/http/httpsocket.cpp @@ -28,9 +28,6 @@ #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND #include "cdparanoia.h" #include "extractjob.h" -#ifdef LAME_FOUND -#include "lame/lame.h" -#endif #endif #include #include @@ -128,18 +125,20 @@ static QString detectMimeType(const QString &file) return QString(); } -static void writeMimeType(const QString &mimeType, QTcpSocket *socket, qint64 size=0) +static void writeMimeType(const QString &mimeType, QTcpSocket *socket, qint32 size, bool allowSeek) { if (!mimeType.isEmpty()) { QTextStream os(socket); os.setAutoDetectUnicode(true); - if (size>0) { + if (allowSeek) { os << "HTTP/1.0 200 OK" << "\r\nAccept-Ranges: bytes" << "\r\nContent-Length: " << QString::number(size) << "\r\nContent-Type: " << mimeType << "\r\n\r\n"; } else { - os << "HTTP/1.0 200 OK\r\nContent-Type: " << mimeType << "\r\n\r\n"; + os << "HTTP/1.0 200 OK" + << "\r\nContent-Length: " << QString::number(size) + << "\r\nContent-Type: " << mimeType << "\r\n\r\n"; } } } @@ -198,7 +197,7 @@ static bool isFromMpd(const QStringList ¶ms) return false; } -static void getRange(const QStringList ¶ms, qint64 &from, qint64 &to) +static void getRange(const QStringList ¶ms, qint32 &from, qint32 &to) { foreach (const QString &str, params) { if (str.startsWith("Range:")) { @@ -206,10 +205,10 @@ static void getRange(const QStringList ¶ms, qint64 &from, qint64 &to) if (start>0) { QStringList range=str.mid(start+6).split("-", QString::SkipEmptyParts); if (1==range.length()) { - from=range.at(0).toLongLong(); + from=range.at(0).toLong(); } else if (2==range.length()) { - from=range.at(0).toLongLong(); - to=range.at(1).toLongLong(); + from=range.at(0).toLong(); + to=range.at(1).toLong(); } } break; @@ -327,6 +326,9 @@ void HttpSocket::readClient() QUrlQuery q(url); #endif bool ok=false; + qint32 readBytesFrom=0; + qint32 readBytesTo=0; + getRange(params, readBytesFrom, readBytesTo); if (q.hasQueryItem("cantata")) { Song song=HttpServer::self()->decodeUrl(url); @@ -340,32 +342,21 @@ void HttpSocket::readClient() if (cdparanoia) { int firstSector = cdparanoia.firstSectorOfTrack(song.id); int lastSector = cdparanoia.lastSectorOfTrack(song.id); + qint32 totalSize = ((lastSector-firstSector)+1)*CD_FRAMESIZE_RAW; int count = 0; + //int bytesToDiscard = 0; // Number of bytes to discard in first read sector due to range request in HTTP header + + //if (readBytesFrom>0) { + // int sectorsToSeek=readBytesFrom/CD_FRAMESIZE_RAW; + // firstSector+=sectorsToSeek; + // bytesToDiscard=readBytesFrom-(sectorsToSeek*CD_FRAMESIZE_RAW); + //} cdparanoia.seek(firstSector, SEEK_SET); ok=true; - #ifdef LAME_FOUND - static const int constMp3BufferSize=CD_FRAMESIZE_RAW*2*sizeof(short int); - static const int constPcmSize=CD_FRAMESIZE_RAW/(2*sizeof(short int)); - unsigned char mp3Buffer[constMp3BufferSize]; - lame_global_flags *lame = lame_init(); - lame_set_num_channels(lame, 2); - lame_set_in_samplerate(lame, 44100); - lame_set_brate(lame, 128); - lame_set_quality(lame, 5); - lame_set_VBR(lame, vbr_off); - if (-1!=lame_init_params(lame)) { - writeMimeType(QLatin1String("audio/mpeg"), socket); - } else { - lame_close(lame); - lame=0; - } - if (!lame) { - #endif - writeMimeType(QLatin1String("audio/x-wav"), socket); - ExtractJob::writeWavHeader(*socket); - #ifdef LAME_FOUND - } - #endif + writeMimeType(QLatin1String("audio/x-wav"), socket, totalSize+ExtractJob::constWavHeaderSize, false); + //if (0==readBytesFrom) { // Only write header if we are no seeking... + ExtractJob::writeWavHeader(*socket, totalSize); + //} bool stop=false; while (!terminated && (firstSector+count) <= lastSector && !stop) { qint16 *buf = cdparanoia.read(); @@ -373,18 +364,17 @@ void HttpSocket::readClient() break; } char *buffer=(char *)buf; - qint64 writePos=0; - qint64 toWrite=CD_FRAMESIZE_RAW; + qint32 writePos=0; + qint32 toWrite=CD_FRAMESIZE_RAW; - #ifdef LAME_FOUND - if (lame) { - toWrite=lame_encode_buffer_interleaved(lame, (short *)buffer, constPcmSize, mp3Buffer, constMp3BufferSize); - buffer=(char *)mp3Buffer; - } - #endif + //if (0==count && bytesToDiscard) { + // writePos=bytesToDiscard; + // toWrite-=bytesToDiscard; + // bytesToDiscard=0; + //} do { - qint64 bytesWritten=socket->write(&buffer[writePos], toWrite - writePos); + qint32 bytesWritten=socket->write(&buffer[writePos], toWrite - writePos); if (terminated || -1==bytesWritten) { stop=true; break; @@ -394,41 +384,32 @@ void HttpSocket::readClient() } while (!terminated && writePosfrom && to!=totalBytes) { - totalBytes-=(totalBytes-to); + if (0!=readBytesTo && readBytesTo>readBytesFrom && readBytesTo!=totalBytes) { + totalBytes-=(totalBytes-readBytesTo); } if (ok) { @@ -439,9 +420,9 @@ void HttpSocket::readClient() break; } - qint64 writePos=0; + qint32 writePos=0; do { - qint64 bytesWritten = socket->write(&buffer[writePos], bytesRead - writePos); + qint32 bytesWritten = socket->write(&buffer[writePos], bytesRead - writePos); if (terminated || -1==bytesWritten) { stop=true; break;