summaryrefslogtreecommitdiffstats
path: root/tderadio3/plugins/timeshifter/timeshifter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tderadio3/plugins/timeshifter/timeshifter.cpp')
-rw-r--r--tderadio3/plugins/timeshifter/timeshifter.cpp455
1 files changed, 0 insertions, 455 deletions
diff --git a/tderadio3/plugins/timeshifter/timeshifter.cpp b/tderadio3/plugins/timeshifter/timeshifter.cpp
deleted file mode 100644
index 146e530..0000000
--- a/tderadio3/plugins/timeshifter/timeshifter.cpp
+++ /dev/null
@@ -1,455 +0,0 @@
-/***************************************************************************
- timeshifter.cpp - description
- -------------------
- begin : Mon May 16 13:39:31 CEST 2005
- copyright : (C) 2005 by Ernst 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. *
- * *
- ***************************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <tdelocale.h>
-#include <linux/soundcard.h>
-
-#include "../../src/include/utils.h"
-#include "timeshifter.h"
-#include "timeshifter-configuration.h"
-
-///////////////////////////////////////////////////////////////////////
-
-PLUGIN_LIBRARY_FUNCTIONS(TimeShifter, "tderadio-timeshifter", i18n("TimeShift Support"));
-
-///////////////////////////////////////////////////////////////////////
-
-TimeShifter::TimeShifter (const TQString &name)
- : PluginBase(name, i18n("TimeShifter Plugin")),
- m_TempFileName("/tmp/tderadio-timeshifter-tempfile"),
- m_TempFileMaxSize(256*1024*1024),
- m_PlaybackMixerID(TQString()),
- m_PlaybackMixerChannel("PCM"),
- m_orgVolume(0.0),
- m_PlaybackMetaData(0,0,0),
- m_PlaybackDataLeftInBuffer(0),
- m_RingBuffer(m_TempFileName, m_TempFileMaxSize)
-{
-}
-
-
-TimeShifter::~TimeShifter ()
-{
-}
-
-
-bool TimeShifter::connectI (Interface *i)
-{
- bool a = PluginBase::connectI(i);
- bool b = ISoundStreamClient::connectI(i);
- return a || b;
-}
-
-
-bool TimeShifter::disconnectI (Interface *i)
-{
- bool a = PluginBase::disconnectI(i);
- bool b = ISoundStreamClient::disconnectI(i);
- return a || b;
-}
-
-
-void TimeShifter::noticeConnectedI (ISoundStreamServer *s, bool pointer_valid)
-{
- ISoundStreamClient::noticeConnectedI(s, pointer_valid);
- if (s && pointer_valid) {
- s->register4_notifySoundStreamClosed(this);
- s->register4_sendStartPlayback(this);
- s->register4_sendStopPlayback(this);
- s->register4_sendPausePlayback(this);
- s->register4_notifySoundStreamData(this);
- s->register4_notifyReadyForPlaybackData(this);
- s->register4_querySoundStreamDescription(this);
- s->register4_sendStartCaptureWithFormat(this);
- s->register4_sendStopCapture(this);
- }
-}
-
-
-void TimeShifter::saveState (TDEConfig *config) const
-{
- config->setGroup(TQString("timeshifter-") + name());
-
- config->writeEntry("temp-file-name", m_TempFileName);
- config->writeEntry("max-file-size", m_TempFileMaxSize / 1024 / 1024);
-
- config->writeEntry("PlaybackMixerID", m_PlaybackMixerID);
- config->writeEntry("PlaybackMixerChannel", m_PlaybackMixerChannel);
-}
-
-
-void TimeShifter::restoreState (TDEConfig *config)
-{
- config->setGroup(TQString("timeshifter-") + name());
-
- TQString fname = config->readEntry("temp-file-name", "/tmp/tderadio-timeshifter-tempfile");
- TQ_UINT64 fsize = 1024 * 1024 * config->readNumEntry("max-file-size", 256);
-
- TQString mixerID = config->readEntry ("PlaybackMixerID", TQString());
- TQString channel = config->readEntry ("PlaybackMixerChannel", "PCM");
-
- setPlaybackMixer(mixerID, channel);
- setTempFile(fname, fsize);
-
- emit sigUpdateConfig();
-}
-
-
-ConfigPageInfo TimeShifter::createConfigurationPage()
-{
- TimeShifterConfiguration *conf = new TimeShifterConfiguration(NULL, this);
- TQObject::connect(this, TQT_SIGNAL(sigUpdateConfig()), conf, TQT_SLOT(slotUpdateConfig()));
- return ConfigPageInfo (conf,
- i18n("Timeshifter"),
- i18n("Timeshifter Options"),
- "tderadio_pause");
-}
-
-AboutPageInfo TimeShifter::createAboutPage()
-{
- return AboutPageInfo();
-}
-
-
-bool TimeShifter::noticeSoundStreamClosed(SoundStreamID id)
-{
- return stopPlayback(id);
-}
-
-bool TimeShifter::startPlayback(SoundStreamID id)
-{
- if (id == m_OrgStreamID) {
- m_StreamPaused = false;
- return true;
- }
- return false;
-}
-
-bool TimeShifter::stopPlayback(SoundStreamID id)
-{
- if (id == m_NewStreamID) {
-
- return sendStopPlayback(m_OrgStreamID);
-
- } else if (id == m_OrgStreamID) {
-
- SoundStreamID tmp_newID = m_NewStreamID;
- SoundStreamID tmp_orgID = m_OrgStreamID;
-
- m_OrgStreamID.invalidate();
- m_NewStreamID.invalidate();
-
- sendStopCapture(tmp_newID);
- closeSoundStream(tmp_newID);
- stopPlayback(tmp_newID);
- m_RingBuffer.clear();
- m_PlaybackMetaData = SoundMetaData(0,0,0);
- m_PlaybackDataLeftInBuffer = 0;
- return true;
- }
- return false;
-}
-
-
-bool TimeShifter::pausePlayback(SoundStreamID id)
-{
- if (!m_OrgStreamID.isValid()) {
- SoundStreamID orgid = id;
- SoundStreamID newid = createNewSoundStream(orgid, false);
- m_OrgStreamID = orgid;
- m_NewStreamID = newid;
- notifySoundStreamCreated(newid);
- notifySoundStreamRedirected(orgid, newid);
- queryPlaybackVolume(newid, m_orgVolume);
- sendMute(newid);
- sendPlaybackVolume(newid, 0);
-
- m_NewStreamID.invalidate();
- sendStopPlayback(newid);
- m_NewStreamID = newid;
-
- m_StreamPaused = true;
-
- m_RingBuffer.clear();
- m_PlaybackMetaData = SoundMetaData(0,0,0);
- m_PlaybackDataLeftInBuffer = 0;
-
- sendStartCaptureWithFormat(m_NewStreamID, m_SoundFormat, m_realSoundFormat);
-
- ISoundStreamClient *playback_mixer = searchPlaybackMixer();
- if (playback_mixer) {
- playback_mixer->preparePlayback(m_OrgStreamID, m_PlaybackMixerChannel, /*active*/true, /*startimmediately*/ true);
- m_PlaybackMixerID = playback_mixer->getSoundStreamClientID();
- }
-
- return true;
-
- } else if (id == m_OrgStreamID) {
- m_StreamPaused = !m_StreamPaused;
- if (!m_StreamPaused) {
-// sendStartPlayback(m_OrgStreamID);
- sendUnmute(m_OrgStreamID);
- sendPlaybackVolume(m_OrgStreamID, m_orgVolume);
- } else {
- queryPlaybackVolume(m_OrgStreamID, m_orgVolume);
- }
- return true;
- }
- return false;
-}
-
-
-size_t TimeShifter::writeMetaDataToBuffer(const SoundMetaData &md, char *buffer, size_t buffer_size)
-{
- TQ_UINT64 pos = md.position();
- time_t abs = md.absoluteTimestamp();
- time_t rel = md.relativeTimestamp();
- size_t url_len = md.url().url().length() + 1;
- size_t req_size = sizeof(req_size) + sizeof(pos) + sizeof(abs) + sizeof(rel) + sizeof(url_len) + url_len;
- if (req_size <= buffer_size) {
- *(size_t*)buffer = req_size;
- buffer += sizeof(req_size);
- *(TQ_UINT64*)buffer = pos;
- buffer += sizeof(pos);
- *(time_t*)buffer = abs;
- buffer += sizeof(abs);
- *(time_t*)buffer = rel;
- buffer += sizeof(rel);
- *(size_t*)buffer = url_len;
- buffer += sizeof(url_len);
- memcpy(buffer, md.url().url().ascii(), url_len);
- buffer += url_len;
- return req_size;
- } else if (buffer_size >= sizeof(req_size)) {
- *(size_t*)buffer = sizeof(req_size);
- return sizeof(req_size);
- } else {
- return 0;
- }
-}
-
-size_t TimeShifter::readMetaDataFromBuffer(SoundMetaData &md, const char *buffer, size_t buffer_size)
-{
- size_t req_size = 0;
- TQ_UINT64 pos = 0;
- time_t abs = 0;
- time_t rel = 0;
- size_t url_len = 0;
- KURL url;
- if (buffer_size >= sizeof(req_size)) {
- req_size = *(size_t*)buffer;
- buffer += sizeof(req_size);
- if (req_size > sizeof(req_size)) {
- pos = *(TQ_UINT64*)buffer;
- buffer += sizeof(TQ_UINT64);
- abs = *(time_t*)buffer;
- buffer += sizeof(abs);
- rel = *(time_t*)buffer;
- buffer += sizeof(rel);
- url_len = *(size_t*)buffer;
- buffer += sizeof(url_len);
- url = buffer;
- buffer += url_len;
- }
- }
- md = SoundMetaData(pos, rel, abs, url);
- return req_size;
-}
-
-
-bool TimeShifter::noticeSoundStreamData(SoundStreamID id, const SoundFormat &/*sf*/, const char *data, size_t size, size_t &consumed_size, const SoundMetaData &md)
-{
- if (id == m_NewStreamID) {
- char buffer_meta[1024];
- size_t meta_buffer_size = writeMetaDataToBuffer(md, buffer_meta, 1024);
- size_t packet_size = meta_buffer_size + sizeof(size) + size;
- if (packet_size > m_RingBuffer.getMaxSize())
- return false;
- TQ_INT64 diff = m_RingBuffer.getFreeSize() - packet_size;
- while (diff < 0) {
- skipPacketInRingBuffer();
- diff = m_RingBuffer.getFreeSize() - packet_size;
- }
- m_RingBuffer.addData(buffer_meta, meta_buffer_size);
- m_RingBuffer.addData((const char*)&size, sizeof(size));
- m_RingBuffer.addData(data, size);
- consumed_size = (consumed_size == SIZE_T_DONT_CARE) ? size : min(consumed_size, size);
- return true;
- }
- return false;
-}
-
-
-void TimeShifter::skipPacketInRingBuffer()
-{
- if (m_PlaybackDataLeftInBuffer > 0) {
- m_RingBuffer.removeData(m_PlaybackDataLeftInBuffer);
- } else {
- size_t meta_size = 0;
- m_RingBuffer.takeData((char*)&meta_size, sizeof(meta_size));
- m_RingBuffer.removeData(meta_size - sizeof(meta_size));
- size_t packet_size = 0;
- m_RingBuffer.takeData((char*)&packet_size, sizeof(packet_size));
- m_RingBuffer.removeData(packet_size - sizeof(packet_size));
- }
-}
-
-
-bool TimeShifter::noticeReadyForPlaybackData(SoundStreamID id, size_t free_size)
-{
- if (id == m_OrgStreamID && !m_StreamPaused) {
-
- while (!m_RingBuffer.error() && m_RingBuffer.getFillSize() > 0 && free_size > 0) {
- if (m_PlaybackDataLeftInBuffer == 0) {
- char meta_buffer[1024];
- size_t &meta_size = *(size_t*)meta_buffer;
- meta_size = 0;
- m_RingBuffer.takeData(meta_buffer, sizeof(meta_size));
- if (meta_size && meta_size <= 1024) {
- m_RingBuffer.takeData(meta_buffer + sizeof(meta_size), meta_size - sizeof(meta_size));
- readMetaDataFromBuffer(m_PlaybackMetaData, meta_buffer, meta_size);
- } else {
- m_RingBuffer.removeData(meta_size - sizeof(meta_size));
- }
-
- m_PlaybackDataLeftInBuffer = 0;
- m_RingBuffer.takeData((char*)&m_PlaybackDataLeftInBuffer, sizeof(m_PlaybackDataLeftInBuffer));
- }
-
- const size_t buffer_size = 65536;
- char buffer[buffer_size];
-
- while (!m_RingBuffer.error() && m_PlaybackDataLeftInBuffer > 0 && free_size > 0) {
- size_t s = m_PlaybackDataLeftInBuffer < free_size ? m_PlaybackDataLeftInBuffer : free_size;
-
- if (s > buffer_size)
- s = buffer_size;
- s = m_RingBuffer.takeData(buffer, s);
-
- size_t consumed_size = SIZE_T_DONT_CARE;
- notifySoundStreamData(m_OrgStreamID, m_realSoundFormat, buffer, s, consumed_size, m_PlaybackMetaData);
- if (consumed_size == SIZE_T_DONT_CARE)
- consumed_size = s;
-
- free_size -= consumed_size;
- m_PlaybackDataLeftInBuffer -= consumed_size;
- if (consumed_size < s) {
- logError(i18n("TimeShifter::notifySoundStreamData: clients skipped %1 bytes. Data Lost").arg(s - consumed_size));
- free_size = 0; // break condition for outer loop
- break;
- }
- }
- }
- return true;
- }
- return false;
-}
-
-
-
-ISoundStreamClient *TimeShifter::searchPlaybackMixer()
-{
- ISoundStreamClient *playback_mixer = getSoundStreamClientWithID(m_PlaybackMixerID);
-
- // some simple sort of autodetection if one mixer isn't present any more
- if (!playback_mixer) {
- TQPtrList<ISoundStreamClient> playback_mixers = queryPlaybackMixers();
- if (!playback_mixers.isEmpty())
- playback_mixer = playback_mixers.first();
- }
- return playback_mixer;
-}
-
-
-bool TimeShifter::setPlaybackMixer(const TQString &soundStreamClientID, const TQString &ch)
-{
- m_PlaybackMixerID = soundStreamClientID;
- m_PlaybackMixerChannel = ch;
-
- ISoundStreamClient *playback_mixer = searchPlaybackMixer();
-
- float oldVolume;
- if (m_OrgStreamID.isValid()) {
- queryPlaybackVolume(m_OrgStreamID, oldVolume);
- sendStopPlayback(m_OrgStreamID);
- sendReleasePlayback(m_OrgStreamID);
- }
-
- if (playback_mixer)
- playback_mixer->preparePlayback(m_OrgStreamID, m_PlaybackMixerChannel, /*active*/true, /*start_imm*/false);
-
- if (m_OrgStreamID.isValid()) {
- sendStartPlayback(m_OrgStreamID);
- sendPlaybackVolume(m_OrgStreamID, oldVolume);
- }
-
- return true;
-}
-
-
-void TimeShifter::setTempFile(const TQString &filename, TQ_UINT64 s)
-{
- m_RingBuffer.clear();
- m_RingBuffer.resize(m_TempFileName = filename, m_TempFileMaxSize = s);
- m_PlaybackMetaData = SoundMetaData(0,0,0, i18n("internal stream, not stored"));
- m_PlaybackDataLeftInBuffer = 0;
-}
-
-bool TimeShifter::getSoundStreamDescription(SoundStreamID id, TQString &descr) const
-{
- if (id == m_NewStreamID) {
- descr = name();
- return true;
- }
- else {
- return false;
- }
-}
-
-bool TimeShifter::startCaptureWithFormat(
- SoundStreamID id,
- const SoundFormat &proposed_format,
- SoundFormat &real_format,
- bool force_format
-)
-{
- if (id == m_OrgStreamID) {
- if (force_format && m_realSoundFormat != proposed_format) {
- sendStopCapture(m_NewStreamID);
- sendStartCaptureWithFormat(m_NewStreamID, proposed_format, m_realSoundFormat);
- }
- real_format = m_realSoundFormat;
- return true;
- } else {
- return false;
- }
-}
-
-bool TimeShifter::stopCapture(SoundStreamID id)
-{
- if (id == m_OrgStreamID) {
- return true;
- } else {
- return false;
- }
-}
-
-#include "timeshifter.moc"