summaryrefslogtreecommitdiffstats
path: root/tderadio3/plugins/recording/recording.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tderadio3/plugins/recording/recording.cpp')
-rw-r--r--tderadio3/plugins/recording/recording.cpp731
1 files changed, 0 insertions, 731 deletions
diff --git a/tderadio3/plugins/recording/recording.cpp b/tderadio3/plugins/recording/recording.cpp
deleted file mode 100644
index 2f1ce05..0000000
--- a/tderadio3/plugins/recording/recording.cpp
+++ /dev/null
@@ -1,731 +0,0 @@
-/***************************************************************************
- recording.cpp - description
- -------------------
- begin : Mi Aug 27 2003
- copyright : (C) 2003 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 "../../src/include/radiostation.h"
-#include "../../src/include/errorlog-interfaces.h"
-#include "../../src/include/aboutwidget.h"
-#include "../../src/include/fileringbuffer.h"
-#include "../../src/include/utils.h"
-
-#include "recording.h"
-#include "recording-configuration.h"
-#include "soundstreamevent.h"
-#include "recording-monitor.h"
-#include "encoder_mp3.h"
-#include "encoder_ogg.h"
-#include "encoder_pcm.h"
-
-#include <tqevent.h>
-#include <tqapplication.h>
-#include <tqregexp.h>
-
-#include <tdeconfig.h>
-#include <tdeversion.h>
-
-#include <tdeaboutdata.h>
-
-
-///////////////////////////////////////////////////////////////////////
-//// plugin library functions
-
-PLUGIN_LIBRARY_FUNCTIONS2(
- Recording, "tderadio-recording", i18n("TDERadio Recording Plugin"),
- RecordingMonitor, i18n("TDERadio Recording Monitor")
-);
-
-///////////////////////////////////////////////////////////////////////
-
-Recording::Recording(const TQString &name)
- : TQObject(NULL, NULL),
- PluginBase(name, i18n("TDERadio Recording Plugin")),
- m_config()
-{
-}
-
-
-Recording::~Recording()
-{
- TQMapIterator<SoundStreamID, RecordingEncoding*> it = m_EncodingThreads.begin();
- TQMapIterator<SoundStreamID, RecordingEncoding*> end = m_EncodingThreads.end();
- for (; it != end; ++it) {
- sendStopRecording(it.key());
- }
-}
-
-
-bool Recording::connectI(Interface *i)
-{
- bool a = IRecCfg::connectI(i);
- bool b = PluginBase::connectI(i);
- bool c = ISoundStreamClient::connectI(i);
- return a || b || c;
-}
-
-
-bool Recording::disconnectI(Interface *i)
-{
- bool a = IRecCfg::disconnectI(i);
- bool b = PluginBase::disconnectI(i);
- bool c = ISoundStreamClient::disconnectI(i);
- return a || b || c;
-}
-
-
-void Recording::noticeConnectedI (ISoundStreamServer *s, bool pointer_valid)
-{
- ISoundStreamClient::noticeConnectedI(s, pointer_valid);
- if (s && pointer_valid) {
- s->register4_sendStartPlayback(this);
- s->register4_sendStopPlayback(this);
- s->register4_sendStartRecording(this);
- s->register4_sendStartRecordingWithFormat(this);
- s->register4_notifySoundStreamData(this);
- s->register4_sendStopRecording(this);
- s->register4_queryIsRecordingRunning(this);
- s->register4_querySoundStreamDescription(this);
- s->register4_querySoundStreamRadioStation(this);
- s->register4_queryEnumerateSoundStreams(this);
- s->register4_notifySoundStreamChanged(this);
- s->register4_notifySoundStreamClosed(this);
- }
-}
-
-// PluginBase
-
-void Recording::saveState (TDEConfig *c) const
-{
- c->setGroup(TQString("recording-") + PluginBase::name());
- m_config.saveConfig(c);
-}
-
-
-void Recording::restoreState (TDEConfig *c)
-{
- c->setGroup(TQString("recording-") + PluginBase::name());
- RecordingConfig cfg;
- cfg.restoreConfig(c);
- setRecordingConfig(cfg);
- //notifyRecordingConfigChanged(m_config);
-}
-
-
-ConfigPageInfo Recording::createConfigurationPage()
-{
- RecordingConfiguration *c = new RecordingConfiguration(NULL);
- connectI(c);
- return ConfigPageInfo(c,
- i18n("Recording"),
- i18n("Recording"),
- "tderadio_record");
-}
-
-
-AboutPageInfo Recording::createAboutPage()
-{
-/* TDEAboutData aboutData("tderadio",
- NULL,
- NULL,
- I18N_NOOP("Recording Monitor for TDERadio"),
- TDEAboutData::License_GPL,
- "(c) 2002-2005 Martin Witte",
- 0,
- "http://sourceforge.net/projects/tderadio",
- 0);
- aboutData.addAuthor("Martin Witte", "", "witte@kawo1.rwth-aachen.de");
-
- return AboutPageInfo(
- new TDERadioAboutWidget(aboutData, TDERadioAboutWidget::AbtTabbed),
- i18n("Recording"),
- i18n("Recording Plugin"),
- "tderadio_record"
- );*/
- return AboutPageInfo();
-}
-
-
-// IRecCfg
-
-bool Recording::setEncoderBuffer (size_t BufferSize, size_t BufferCount)
-{
- if (m_config.m_EncodeBufferSize != BufferSize ||
- m_config.m_EncodeBufferCount != BufferCount)
- {
- m_config.m_EncodeBufferSize = BufferSize;
- m_config.m_EncodeBufferCount = BufferCount;
- notifyEncoderBufferChanged(BufferSize, BufferCount);
- }
- return true;
-}
-
-bool Recording::setSoundFormat (const SoundFormat &sf)
-{
- if (m_config.m_SoundFormat != sf) {
- m_config.m_SoundFormat = sf;
- notifySoundFormatChanged(sf);
- }
- return true;
-}
-
-bool Recording::setMP3Quality (int q)
-{
- if (m_config.m_mp3Quality != q) {
- m_config.m_mp3Quality = q;
- notifyMP3QualityChanged(q);
- }
- return true;
-}
-
-bool Recording::setOggQuality (float q)
-{
- if (m_config.m_oggQuality != q) {
- m_config.m_oggQuality = q;
- notifyOggQualityChanged(q);
- }
- return true;
-}
-
-bool Recording::setRecordingDirectory(const TQString &dir)
-{
- if (m_config.m_Directory != dir) {
- m_config.m_Directory = dir;
- notifyRecordingDirectoryChanged(dir);
- }
- return true;
-}
-
-bool Recording::setOutputFormat (RecordingConfig::OutputFormat of)
-{
- if (m_config.m_OutputFormat != of) {
- m_config.m_OutputFormat = of;
- notifyOutputFormatChanged(of);
- }
- return true;
-}
-
-bool Recording::setPreRecording (bool enable, int seconds)
-{
- if (m_config.m_PreRecordingEnable != enable || m_config.m_PreRecordingSeconds != seconds) {
- m_config.m_PreRecordingEnable = enable;
- m_config.m_PreRecordingSeconds = seconds;
-
- if (enable) {
- for (TQMapIterator<SoundStreamID,FileRingBuffer*> it = m_PreRecordingBuffers.begin(); it != m_PreRecordingBuffers.end(); ++it) {
- if (*it != NULL) {
- delete *it;
- }
- *it = new FileRingBuffer(m_config.m_Directory + "/tderadio-prerecord-"+TQString::number(it.key().getID()), m_config.m_PreRecordingSeconds * m_config.m_SoundFormat.m_SampleRate * m_config.m_SoundFormat.frameSize());
- SoundFormat sf = m_config.m_SoundFormat;
- sendStartCaptureWithFormat(it.key(), sf, sf, false);
- }
- }
- else {
- for (TQMapIterator<SoundStreamID,FileRingBuffer*> it = m_PreRecordingBuffers.begin(); it != m_PreRecordingBuffers.end(); ++it) {
- if (*it != NULL) {
- sendStopCapture(it.key());
- delete *it;
- }
- }
- m_PreRecordingBuffers.clear();
- }
-
- notifyPreRecordingChanged(enable, seconds);
- }
- return true;
-}
-
-void Recording::getEncoderBuffer(size_t &BufferSize, size_t &BufferCount) const
-{
- BufferSize = m_config.m_EncodeBufferSize;
- BufferCount = m_config.m_EncodeBufferCount;
-}
-
-const SoundFormat &Recording::getSoundFormat () const
-{
- return m_config.m_SoundFormat;
-}
-
-int Recording::getMP3Quality () const
-{
- return m_config.m_mp3Quality;
-}
-
-float Recording::getOggQuality () const
-{
- return m_config.m_oggQuality;
-}
-
-const TQString &Recording::getRecordingDirectory() const
-{
- return m_config.m_Directory;
-}
-
-RecordingConfig::OutputFormat Recording::getOutputFormat() const
-{
- return m_config.m_OutputFormat;
-}
-
-bool Recording::getPreRecording(int &seconds) const
-{
- seconds = m_config.m_PreRecordingSeconds;
- return m_config.m_PreRecordingEnable;
-}
-
-const RecordingConfig &Recording::getRecordingConfig() const
-{
- return m_config;
-}
-
-bool Recording::setRecordingConfig(const RecordingConfig &c)
-{
- setEncoderBuffer (c.m_EncodeBufferSize, c.m_EncodeBufferCount);
- setSoundFormat (c.m_SoundFormat);
- setMP3Quality (c.m_mp3Quality);
- setOggQuality (c.m_oggQuality);
- setRecordingDirectory(c.m_Directory);
- setOutputFormat (c.m_OutputFormat);
- setPreRecording (c.m_PreRecordingEnable, c.m_PreRecordingSeconds);
-
- m_config = c;
-
- notifyRecordingConfigChanged(m_config);
-
- return true;
-}
-
-
-// ISoundStreamClient
-bool Recording::startPlayback(SoundStreamID id)
-{
- if (m_PreRecordingBuffers.contains(id))
- delete m_PreRecordingBuffers[id];
- m_PreRecordingBuffers[id] = NULL;
- if (m_config.m_PreRecordingEnable) {
- m_PreRecordingBuffers[id] = new FileRingBuffer(m_config.m_Directory + "/tderadio-prerecord-"+TQString::number(id.getID()), m_config.m_PreRecordingSeconds * m_config.m_SoundFormat.m_SampleRate * m_config.m_SoundFormat.frameSize());
- SoundFormat sf = m_config.m_SoundFormat;
- sendStartCaptureWithFormat(id, sf, sf, false);
- }
- return false;
-}
-
-bool Recording::stopPlayback(SoundStreamID id)
-{
- if (m_PreRecordingBuffers.contains(id)) {
- if (m_PreRecordingBuffers[id])
- delete m_PreRecordingBuffers[id];
- m_PreRecordingBuffers.remove(id);
- sendStopCapture(id);
- }
- return false;
-}
-
-bool Recording::startRecording(SoundStreamID id)
-{
-
-/* FileRingBuffer *test = new FileRingBuffer("/tmp/ringbuffertest", 2048);
- char buffer1[1024];
- char buffer2[1024];
- char buffer3[1024];
- for (int i = 0; i < 1024; ++i) {
- buffer1[i] = 'a';
- buffer2[i] = 'b';
- buffer3[i] = 'c';
- }
- test->addData(buffer1, 1024);
- test->addData(buffer2, 1024);
- test->removeData(1024);
- test->addData(buffer3, 1024);
-*/
-
- SoundFormat realFormat = m_config.m_SoundFormat;
- return sendStartRecordingWithFormat(id, realFormat, realFormat);
-}
-
-bool Recording::startRecordingWithFormat(SoundStreamID id, const SoundFormat &sf, SoundFormat &real_format)
-{
- if (!sendStartCaptureWithFormat(id, sf, real_format, /* force_format = */ true)) {
- logError(i18n("start capture not handled"));
- return false;
- }
-
- RecordingConfig cfg = m_config;
- cfg.m_SoundFormat = real_format;
-
- logInfo(i18n("Recording starting"));
- if (!startEncoder(id, cfg)) {
- logError(i18n("starting encoding thread failed"));
- sendStopCapture(id);
- return false;
- }
-
- return true;
-}
-
-
-bool Recording::stopRecording(SoundStreamID id)
-{
- if (m_EncodingThreads.contains(id)) {
- sendStopCapture(id);
- if (m_config.m_PreRecordingEnable) {
- if (!m_PreRecordingBuffers.contains(id)) {
- if (m_PreRecordingBuffers[id] != NULL) {
- delete m_PreRecordingBuffers[id];
- }
- bool b = false;
- queryIsPlaybackRunning(id, b);
- if (b) {
- m_PreRecordingBuffers[id] = new FileRingBuffer(m_config.m_Directory + "/tderadio-prerecord-"+TQString::number(id.getID()), m_config.m_PreRecordingSeconds * m_config.m_SoundFormat.m_SampleRate * m_config.m_SoundFormat.frameSize());
- } else {
- m_PreRecordingBuffers[id] = NULL;
- }
- }
- }
- stopEncoder(id);
- return true;
- }
- return false;
-}
-
-
-
-bool Recording::noticeSoundStreamData(SoundStreamID id,
- const SoundFormat &/*sf*/, const char *data, size_t size, size_t &consumed_size,
- const SoundMetaData &md
-)
-{
- if (m_PreRecordingBuffers.contains(id) && m_PreRecordingBuffers[id] != NULL) {
-
- FileRingBuffer &fbuf = *m_PreRecordingBuffers[id];
- if (fbuf.getFreeSize() < size) {
- fbuf.removeData(size - fbuf.getFreeSize());
- }
- size_t n = fbuf.addData(data, size);
- consumed_size = (consumed_size == SIZE_T_DONT_CARE) ? n : min(consumed_size, n);
-// if (n != size) {
-// logDebug("recording packet: was not written completely to tmp buf");
-// }
-
-// //BEGIN DEBUG
-// char tmp[4096];
-// for (unsigned int i = 0; i < sizeof(tmp); ++i) { tmp[i] = 0; }
-// if (fbuf.getFreeSize() < sizeof(tmp)) {
-// fbuf.removeData(sizeof(tmp) - fbuf.getFreeSize());
-// }
-// fbuf.addData((char*)tmp, sizeof(tmp));
-// //END DEBUG
-
- if (m_EncodingThreads.contains(id)) {
-
- //logDebug("recording packet: " + TQString::number(size));
-
- RecordingEncoding *thread = m_EncodingThreads[id];
-
- //logDebug("noticeSoundStreamData thread = " + TQString::number((long long)thread, 16));
-
- size_t remSize = fbuf.getFillSize();
-
- while (remSize > 0) {
- size_t bufferSize = remSize;
- char *buf = thread->lockInputBuffer(bufferSize);
- if (!buf) {
- // Encoder buffer is full and bigger than remaining data
- break;
- }
- if (bufferSize > remSize) {
- bufferSize = remSize;
- }
- if (fbuf.takeData(buf, bufferSize) != bufferSize) {
- logError(i18n("could not read suffient data"));
- }
-
- thread->unlockInputBuffer(bufferSize, md);
- remSize -= bufferSize;
- }
-
- if (remSize == 0) {
- delete m_PreRecordingBuffers[id];
- m_PreRecordingBuffers.remove(id);
- }
- }
-
- return true;
- }
-
- else if (m_EncodingThreads.contains(id)) {
-
- //logDebug("recording packet: " + TQString::number(size));
-
- RecordingEncoding *thread = m_EncodingThreads[id];
-
- //logDebug("noticeSoundStreamData thread = " + TQString::number((long long)thread, 16));
-
- size_t remSize = size;
- const char *remData = data;
-
- while (remSize > 0) {
- size_t bufferSize = remSize;
- char *buf = thread->lockInputBuffer(bufferSize);
- if (!buf) {
- logWarning(i18n("Encoder input buffer overflow (buffer configuration problem?). Skipped %1 input bytes").arg(TQString::number(remSize)));
- break;
- }
- if (bufferSize > remSize) {
- bufferSize = remSize;
- }
- memcpy(buf, remData, bufferSize);
-
- thread->unlockInputBuffer(bufferSize, md);
- remSize -= bufferSize;
- remData += bufferSize;
- }
- consumed_size = (consumed_size == SIZE_T_DONT_CARE) ? size - remSize : min(consumed_size, size - remSize);
-
- return true;
- }
- return false;
-}
-
-
-
-
-bool Recording::startEncoder(SoundStreamID ssid, const RecordingConfig &cfg)
-{
- if (m_EncodingThreads.contains(ssid))
- return false;
-
- SoundStreamID encID = createNewSoundStream(ssid, false);
- m_RawStreams2EncodedStreams[ssid] = encID;
- m_EncodedStreams2RawStreams[encID] = ssid;
-
- TQString ext = ".wav";
- switch (m_config.m_OutputFormat) {
- case RecordingConfig::outputWAV: ext = ".wav"; break;
- case RecordingConfig::outputAIFF: ext = ".aiff"; break;
- case RecordingConfig::outputAU: ext = ".au"; break;
-#ifdef HAVE_LAME
- case RecordingConfig::outputMP3: ext = ".mp3"; break;
-#endif
-#ifdef HAVE_LAME
- case RecordingConfig::outputOGG: ext = ".ogg"; break;
-#endif
- case RecordingConfig::outputRAW: ext = ".raw"; break;
- default: ext = ".wav"; break;
- }
- const RadioStation *rs = NULL;
- querySoundStreamRadioStation(ssid, rs);
- TQString station = rs ? rs->name() + "-" : "";
- station.replace(TQRegExp("[/*?]"), "_");
-
- TQDate date = TQDate::currentDate();
- TQTime time = TQTime::currentTime();
- TQString sdate;
-
- sdate.sprintf("%d.%d.%d.%d.%d",date.year(),date.month(),date.day(),time.hour(),time.minute());
-
- TQString output = m_config.m_Directory
- + "/tderadio-recording-"
- + station
- + sdate
- + ext;
-
- logInfo(i18n("Recording::outputFile: ") + output);
-
- RecordingEncoding *thread = NULL;
- switch (m_config.m_OutputFormat) {
-#ifdef HAVE_LAME
- case RecordingConfig::outputMP3:
- thread = new RecordingEncodingMP3(this, ssid, cfg, rs, output);
- break;
-#endif
-#ifdef HAVE_OGG
- case RecordingConfig::outputOGG:
- thread = new RecordingEncodingOgg(this, ssid, cfg, rs, output);
- break;
-#endif
- default:
- thread = new RecordingEncodingPCM(this, ssid, cfg, rs, output);
- }
-
- //m_encodingThread->openOutput(output, rs);
-
- if (thread->error()) {
- //m_context.setError();
- logError(thread->errorString());
- } else {
- thread->start();
- }
- // store thread even if it has indicated an error
- m_EncodingThreads[ssid] = thread;
-
- //logDebug("startEncoder thread = " + TQString::number((long long)thread, 16));
-
- notifySoundStreamCreated(encID);
- return !thread->error();
-}
-
-
-void Recording::stopEncoder(SoundStreamID id)
-{
- if (m_EncodingThreads.contains(id)) {
-
- RecordingEncoding *thread = m_EncodingThreads[id];
-
- thread->setDone();
-
- //logDebug("stopEncoder thread = " + TQString::number((long long)thread, 16));
- //logDebug("stopEncoder thread error = " + TQString::number(thread->error(), 16));
-
- // FIXME: set a timer and do waiting "in background"
- if (!thread->wait(5000)) {
- //m_context.setError();
- logError(i18n("The encoding thread did not finish. It will be killed now."));
- thread->terminate();
- thread->wait();
- } else {
- if (thread->error()) {
- //m_context.setError();
- logError(thread->errorString());
- } else {
- //TQ_UINT64 size = thread->encodedSize();
- //m_context.setEncodedSize(low, high);
- //notifyRecordingContextChanged(m_context);
- }
- }
- delete thread;
- m_EncodingThreads.remove(id);
- SoundStreamID encID = m_RawStreams2EncodedStreams[id];
- m_EncodedStreams2RawStreams.remove(encID);
- m_RawStreams2EncodedStreams.remove(id);
- sendStopPlayback(encID);
- closeSoundStream(encID);
- logInfo(i18n("Recording stopped"));
- }
-}
-
-
-bool Recording::event(TQEvent *_e)
-{
- if (SoundStreamEvent::isSoundStreamEvent(_e)) {
- SoundStreamEvent *e = static_cast<SoundStreamEvent*>(_e);
- SoundStreamID id = e->getSoundStreamID();
-
- if (m_EncodingThreads.contains(id)) {
-
- RecordingEncoding *thread = m_EncodingThreads[id];
-
- //logDebug("Recording::event: thread = " + TQString::number((long long)thread, 16));
-
- if (thread->error()) {
- logError(thread->errorString());
- //m_context.setError();
- stopEncoder(id);
- } else {
- //TQ_UINT64 size = thread->encodedSize();
- //m_context.setEncodedSize(low, high);
- //notifyRecordingContextChanged(m_context);
- if (e->type() == EncodingTerminated) {
- stopEncoder(id);
- } else if (e->type() == EncodingStep) {
- SoundStreamEncodingStepEvent *step = static_cast<SoundStreamEncodingStepEvent*>(e);
- size_t consumed_size = SIZE_T_DONT_CARE;
- notifySoundStreamData(m_RawStreams2EncodedStreams[id], thread->config().m_SoundFormat,
- step->data(), step->size(), consumed_size, step->metaData());
- if (consumed_size != SIZE_T_DONT_CARE && consumed_size < step->size()) {
- logError(i18n("Recording::notifySoundStreamData(encoded data): Receivers skipped %1 Bytes").arg(step->size() - consumed_size));
- }
- }
- }
- }
- return true;
- } else {
- return TQObject::event(_e);
- }
-}
-
-
-bool Recording::getSoundStreamDescription(SoundStreamID id, TQString &descr) const
-{
- if (m_EncodedStreams2RawStreams.contains(id)) {
- if (querySoundStreamDescription(m_EncodedStreams2RawStreams[id], descr)) {
- descr = name() + " - " + descr;
- return true;
- }
- }
- return false;
-}
-
-
-bool Recording::getSoundStreamRadioStation(SoundStreamID id, const RadioStation *&rs) const
-{
- if (m_EncodedStreams2RawStreams.contains(id)) {
- if (querySoundStreamRadioStation(m_EncodedStreams2RawStreams[id], rs)) {
- return true;
- }
- }
- return false;
-}
-
-
-bool Recording::enumerateSoundStreams(TQMap<TQString, SoundStreamID> &list) const
-{
- TQMapConstIterator<SoundStreamID,SoundStreamID> end = m_RawStreams2EncodedStreams.end();
- for (TQMapConstIterator<SoundStreamID,SoundStreamID> it = m_RawStreams2EncodedStreams.begin(); it != end; ++it) {
- TQString tmp = TQString();
- getSoundStreamDescription(*it, tmp);
- list[tmp] = *it;
- }
- return m_RawStreams2EncodedStreams.count() > 0;
-}
-
-
-bool Recording::noticeSoundStreamChanged(SoundStreamID id)
-{
- if (m_RawStreams2EncodedStreams.contains(id)) {
- notifySoundStreamChanged(m_RawStreams2EncodedStreams[id]);
- return true;
- }
- return false;
-}
-
-
-bool Recording::isRecordingRunning(SoundStreamID id, bool &b, SoundFormat &sf) const
-{
- if (m_EncodingThreads.contains(id)) {
- b = m_EncodingThreads[id]->running();
- sf = getSoundFormat();
- return true;
- }
- return false;
-}
-
-
-bool Recording::noticeSoundStreamClosed(SoundStreamID id)
-{
- if (m_PreRecordingBuffers.contains(id)) {
- if (m_PreRecordingBuffers[id])
- delete m_PreRecordingBuffers[id];
- m_PreRecordingBuffers.remove(id);
- }
-
- if (m_EncodingThreads.contains(id)) {
- sendStopRecording(id);
- return true;
- }
- return false;
-}
-
-
-#include "recording.moc"