summaryrefslogtreecommitdiffstats
path: root/kradio3/plugins/recording/encoder_mp3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kradio3/plugins/recording/encoder_mp3.cpp')
-rw-r--r--kradio3/plugins/recording/encoder_mp3.cpp214
1 files changed, 214 insertions, 0 deletions
diff --git a/kradio3/plugins/recording/encoder_mp3.cpp b/kradio3/plugins/recording/encoder_mp3.cpp
new file mode 100644
index 0000000..5ba0bc2
--- /dev/null
+++ b/kradio3/plugins/recording/encoder_mp3.cpp
@@ -0,0 +1,214 @@
+/***************************************************************************
+ encoder_mp3.cpp
+ -------------------
+ begin : Sat Aug 20 2005
+ copyright : (C) 2005 by Martin Witte
+ email : witte@kawo1.rwth-aachen.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "encoder_mp3.h"
+
+#include <qmutex.h>
+#include <klocale.h>
+
+RecordingEncodingMP3::RecordingEncodingMP3(QObject *parent, SoundStreamID ssid,
+ const RecordingConfig &cfg, const RadioStation *rs,
+ const QString &filename)
+ : RecordingEncoding(parent, ssid, cfg, rs, filename)
+#ifdef HAVE_LAME
+ ,
+ m_MP3Buffer(NULL),
+ m_MP3BufferSize(0),
+ m_MP3Output(NULL),
+ m_ID3Tags(NULL),
+ m_LAMEFlags(NULL),
+ m_MP3LBuffer(NULL),
+ m_MP3RBuffer(NULL)
+#endif
+{
+ m_config.m_OutputFormat = RecordingConfig::outputMP3;
+ m_config.m_SoundFormat.m_Encoding = "mp3";
+ openOutput(filename);
+}
+
+
+RecordingEncodingMP3::~RecordingEncodingMP3()
+{
+ closeOutput();
+}
+
+
+static QMutex lameSerialization;
+
+void RecordingEncodingMP3::encode(const char *_buffer, size_t buffer_size, char *&export_buffer, size_t &export_buffer_size)
+{
+ if (m_error)
+ return;
+
+#ifdef HAVE_LAME
+ short int *buffer = (short int*)_buffer;
+ size_t j = 0,
+ j_inc = (m_config.m_SoundFormat.m_Channels == 1) ? 1 : 2,
+ dj = (m_config.m_SoundFormat.m_Channels == 1) ? 0 : 1,
+ samples = buffer_size / m_config.m_SoundFormat.frameSize();
+
+ for (size_t i = 0; i < samples; ++i, j+=j_inc) {
+ m_MP3LBuffer[i] = buffer[j];
+ m_MP3RBuffer[i] = buffer[j+dj];
+ }
+
+ int n = 0;
+ lameSerialization.lock();
+ n = lame_encode_buffer(m_LAMEFlags,
+ m_MP3LBuffer,
+ m_MP3RBuffer,
+ samples,
+ m_MP3Buffer,
+ m_MP3BufferSize);
+ lameSerialization.unlock();
+ if (n < 0) {
+ m_errorString += i18n("Error %1 while encoding mp3. ").arg(QString().setNum(n));
+ m_error = true;
+ } else if (n > 0) {
+ m_encodedSize += n;
+
+ export_buffer = (char*)m_MP3Buffer;
+ export_buffer_size = n;
+ int r = fwrite(m_MP3Buffer, 1, n, m_MP3Output);
+
+ if (r <= 0) {
+ m_errorString += i18n("Error %1 writing output. ").arg(QString().setNum(r));
+ m_error = true;
+ }
+ }
+#endif
+}
+
+
+
+bool RecordingEncodingMP3::openOutput(const QString &output)
+{
+#ifdef HAVE_LAME
+// m_output = NULL;
+ m_LAMEFlags = lame_init();
+
+ if (!m_LAMEFlags) {
+ m_error = true;
+ m_errorString += i18n("Cannot initialize lalibmp3lame. ");
+ } else {
+ lame_set_in_samplerate(m_LAMEFlags, m_config.m_SoundFormat.m_SampleRate);
+ lame_set_num_channels(m_LAMEFlags, 2);
+ //lame_set_quality(m_LAMEFlags, m_config.mp3Quality);
+
+ lame_set_mode(m_LAMEFlags, m_config.m_SoundFormat.m_Channels == 1 ? MONO : JOINT_STEREO);
+
+ // lame_seterrorf(m_LAMEFlags, ...);
+ // lame_setdebugf(m_LAMEFlags, ...);
+ // lame_setmsgf(m_LAMEFlags, ...);
+
+ lame_set_VBR(m_LAMEFlags, vbr_default);
+ lame_set_VBR_q(m_LAMEFlags, m_config.m_mp3Quality);
+
+ if (lame_init_params(m_LAMEFlags) < 0) {
+ m_error = true;
+ m_errorString += i18n("Cannot initialize libmp3lame parameters. ").arg(output);
+ }
+
+ if (!m_error) {
+ id3tag_init(m_LAMEFlags);
+ id3tag_add_v2(m_LAMEFlags);
+ QString title = m_RadioStation->name() + QString().sprintf(" - %s", (QDateTime::currentDateTime().toString(Qt::ISODate)).ascii());
+ QString comment = i18n("Recorded by KRadio");
+ size_t l = title.length() + comment.length() + 10;
+ m_ID3Tags = new char[l];
+ char *ctitle = m_ID3Tags;
+ strcpy(ctitle, title.latin1());
+ char *ccomment = m_ID3Tags + strlen(ctitle) + 1;
+ strcpy(ccomment, comment.latin1());
+ id3tag_set_title(m_LAMEFlags, ctitle);
+ id3tag_set_comment(m_LAMEFlags, ccomment);
+ }
+
+ m_MP3Output = fopen(output.ascii(), "wb+");
+ if (!m_MP3Output) {
+ m_errorString += i18n("Cannot open output file %1. ").arg(output);
+ m_error = true;
+ }
+
+ size_t nSamples = m_config.m_EncodeBufferSize / m_config.m_SoundFormat.frameSize();
+ m_MP3BufferSize = nSamples + nSamples / 4 + 7200;
+ m_MP3Buffer = new unsigned char[m_MP3BufferSize];
+
+ m_MP3LBuffer = new short int[nSamples];
+ m_MP3RBuffer = new short int[nSamples];
+
+ if (!m_MP3Buffer || !m_MP3LBuffer || !m_MP3RBuffer) {
+ m_error = true;
+ m_errorString += i18n("Cannot allocate buffers for mp3 encoding. ");
+ }
+ }
+
+ if (m_error) {
+ if (m_LAMEFlags) lame_close(m_LAMEFlags);
+ m_LAMEFlags = NULL;
+ if (m_MP3Output) fclose(m_MP3Output);
+ m_MP3Output = NULL;
+ if (m_MP3Buffer) delete [] m_MP3Buffer;
+ m_MP3Buffer = NULL;
+ m_MP3BufferSize = 0;
+ if (m_ID3Tags) delete [] m_ID3Tags;
+ m_ID3Tags = NULL;
+ if (m_MP3LBuffer) delete[] m_MP3LBuffer;
+ if (m_MP3RBuffer) delete[] m_MP3RBuffer;
+ m_MP3LBuffer = m_MP3RBuffer = NULL;
+ }
+#endif
+ return !m_error;
+}
+
+
+void RecordingEncodingMP3::closeOutput()
+{
+#ifdef HAVE_LAME
+ if (m_LAMEFlags) {
+ if (m_config.m_OutputFormat == RecordingConfig::outputMP3) {
+ int n = lame_encode_flush(m_LAMEFlags,
+ m_MP3Buffer,
+ m_MP3BufferSize);
+ if (n < 0) {
+ m_error = true;
+ m_errorString += i18n("Error %1 while encoding mp3. ").arg(QString().setNum(n));
+ } else if (n > 0) {
+ int r = fwrite(m_MP3Buffer, 1, n, m_MP3Output);
+ if (r <= 0) {
+ m_error = true;
+ m_errorString += i18n("Error %1 writing output. ").arg(QString().setNum(r));
+ } else {
+ lame_mp3_tags_fid(m_LAMEFlags, m_MP3Output);
+ }
+ }
+ }
+ if (m_LAMEFlags) lame_close(m_LAMEFlags);
+ m_LAMEFlags = NULL;
+ if (m_MP3Output) fclose(m_MP3Output);
+ m_MP3Output = NULL;
+ m_MP3BufferSize = 0;
+ if (m_MP3Buffer) delete [] m_MP3Buffer;
+ m_MP3Buffer = NULL;
+ if (m_ID3Tags) delete [] m_ID3Tags;
+ m_ID3Tags = NULL;
+ if (m_MP3LBuffer) delete[] m_MP3LBuffer;
+ if (m_MP3RBuffer) delete[] m_MP3RBuffer;
+ m_MP3LBuffer = m_MP3RBuffer = NULL;
+ }
+#endif
+}