diff options
Diffstat (limited to 'tderadio3/plugins/recording/recording.cpp')
| -rw-r--r-- | tderadio3/plugins/recording/recording.cpp | 731 |
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" |
