Remove lame usage, its not actually required for audio cd playback!
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
-----
|
||||
|
||||
21
README
21
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
|
||||
|
||||
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -32,22 +32,37 @@
|
||||
#include <QProcess>
|
||||
#include <QFile>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 <QTcpSocket>
|
||||
#include <QNetworkInterface>
|
||||
@@ -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 && writePos<toWrite);
|
||||
count++;
|
||||
}
|
||||
#ifdef LAME_FOUND
|
||||
if (lame) {
|
||||
lame_close(lame);
|
||||
lame=0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
QFile f(url.path());
|
||||
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
qint64 from=0;
|
||||
qint64 to=0;
|
||||
qint64 totalBytes = f.size();
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
qint32 totalBytes = f.size();
|
||||
|
||||
getRange(params, from, to);
|
||||
writeMimeType(detectMimeType(url.path()), socket, totalBytes);
|
||||
writeMimeType(detectMimeType(url.path()), socket, totalBytes, true);
|
||||
ok=true;
|
||||
static const int constChunkSize=32768;
|
||||
char buffer[constChunkSize];
|
||||
qint64 readPos = 0;
|
||||
qint64 bytesRead = 0;
|
||||
qint32 readPos = 0;
|
||||
qint32 bytesRead = 0;
|
||||
bool stop=false;
|
||||
|
||||
if (0!=from) {
|
||||
if (!f.seek(from)) {
|
||||
if (0!=readBytesFrom) {
|
||||
if (!f.seek(readBytesFrom)) {
|
||||
ok=false;
|
||||
}
|
||||
bytesRead+=from;
|
||||
bytesRead+=readBytesFrom;
|
||||
}
|
||||
|
||||
if (0!=to && to>from && 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;
|
||||
|
||||
Reference in New Issue
Block a user