diff options
Diffstat (limited to 'kradio3/plugins/oss-sound/oss-sound.cpp')
-rw-r--r-- | kradio3/plugins/oss-sound/oss-sound.cpp | 991 |
1 files changed, 0 insertions, 991 deletions
diff --git a/kradio3/plugins/oss-sound/oss-sound.cpp b/kradio3/plugins/oss-sound/oss-sound.cpp deleted file mode 100644 index 0c06f33..0000000 --- a/kradio3/plugins/oss-sound/oss-sound.cpp +++ /dev/null @@ -1,991 +0,0 @@ -/*************************************************************************** - oss-sound.cpp - description - ------------------- - begin : Sun Mar 21 2004 - copyright : (C) 2004 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 "oss-sound.h" - -#include "../../src/include/aboutwidget.h" -#include <klocale.h> -#include <kaboutdata.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/soundcard.h> -#include <sys/ioctl.h> -#include <fcntl.h> -#include <unistd.h> -#include <math.h> -#include <errno.h> - -#include "oss-sound-configuration.h" -#include "../../src/include/utils.h" - -/////////////////////////////////////////////////////////////////////// -//// plugin library functions - -PLUGIN_LIBRARY_FUNCTIONS(OSSSoundDevice, "kradio-oss-sound", i18n("Open Sound System (OSS) Support")); - -///////////////////////////////////////////////////////////////////////////// - -struct _lrvol { unsigned char l, r; short dummy; }; - -OSSSoundDevice::OSSSoundDevice(const TQString &name) - : TQObject(NULL, NULL), - PluginBase(name, i18n("TDERadio OSS Sound Plugin")), - m_DSPDeviceName(""), - m_MixerDeviceName(""), - m_DSP_fd(-1), - m_Mixer_fd(-1), - m_DuplexMode(DUPLEX_UNKNOWN), - m_DSPFormat(), - m_PassivePlaybackStreams(), - m_PlaybackStreamID(), - m_CaptureStreamID(), - m_BufferSize(65536), - m_PlaybackBuffer(m_BufferSize), - m_CaptureBuffer(m_BufferSize), - m_CaptureRequestCounter(0), - m_CapturePos(0), - m_CaptureStartTime(0), - //m_PlaybackSkipCount(0), - m_CaptureSkipCount(0), - m_EnablePlayback(true), - m_EnableCapture(true) -{ - TQObject::connect(&m_PollingTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotPoll())); -} - - -OSSSoundDevice::~OSSSoundDevice() -{ - stopCapture(m_CaptureStreamID); - stopPlayback(m_PlaybackStreamID); - closeDSPDevice(); - closeMixerDevice(); -} - - -bool OSSSoundDevice::connectI(Interface *i) -{ - bool a = PluginBase::connectI(i); - bool b = ISoundStreamClient::connectI(i); - return a || b; -} - - -bool OSSSoundDevice::disconnectI(Interface *i) -{ - bool a = PluginBase::disconnectI(i); - bool b = ISoundStreamClient::disconnectI(i); - return a || b; -} - -void OSSSoundDevice::noticeConnectedI (ISoundStreamServer *s, bool pointer_valid) -{ - ISoundStreamClient::noticeConnectedI(s, pointer_valid); - if (s && pointer_valid) { - s->register4_sendReleasePlayback(this); - s->register4_sendReleaseCapture(this); - s->register4_sendPlaybackVolume(this); - s->register4_sendCaptureVolume(this); - s->register4_queryPlaybackVolume(this); - s->register4_queryCaptureVolume(this); - s->register4_sendStartPlayback(this); - s->register4_sendPausePlayback(this); - s->register4_sendStopPlayback(this); - s->register4_queryIsPlaybackRunning(this); - s->register4_sendStartCaptureWithFormat(this); - s->register4_sendStopCapture(this); - s->register4_queryIsCaptureRunning(this); - s->register4_notifySoundStreamClosed(this); - s->register4_notifySoundStreamRedirected(this); - s->register4_notifySoundStreamData(this); - } -} - -// PluginBase - -void OSSSoundDevice::saveState (TDEConfig *c) const -{ - c->setGroup(TQString("oss-sound-") + PluginBase::name()); - - c->writeEntry("dsp-device", m_DSPDeviceName); - c->writeEntry("mixer-device", m_MixerDeviceName); - c->writeEntry("enable-playback", m_EnablePlayback); - c->writeEntry("enable-capture", m_EnableCapture); - c->writeEntry("buffer-size", m_BufferSize); - c->writeEntry("soundstreamclient-id", m_SoundStreamClientID); -} - - -void OSSSoundDevice::restoreState (TDEConfig *c) -{ - c->setGroup(TQString("oss-sound-") + PluginBase::name()); - - m_EnablePlayback = c->readBoolEntry("enable-playback", true); - m_EnableCapture = c->readBoolEntry("enable-capture", true); - m_BufferSize = c->readNumEntry ("buffer-size", 65536); - - setDSPDeviceName (c->readEntry ("dsp-device", "/dev/dsp")); - setMixerDeviceName (c->readEntry ("mixer-device", "/dev/mixer")); - - m_PlaybackBuffer.resize(m_BufferSize); - m_CaptureBuffer.resize(m_BufferSize); - - setSoundStreamClientID(c->readEntry("soundstreamclient-id", getSoundStreamClientID())); - - emit sigUpdateConfig(); -} - - -void OSSSoundDevice::setMixerDeviceName(const TQString &dev_name) -{ - if (m_MixerDeviceName != dev_name) { - m_MixerDeviceName = dev_name; - if (m_Mixer_fd >= 0) - openMixerDevice(true); - getMixerChannels(SOUND_MIXER_DEVMASK, m_PlaybackChannels, m_revPlaybackChannels); - getMixerChannels(SOUND_MIXER_RECMASK, m_CaptureChannels, m_revCaptureChannels); - notifyPlaybackChannelsChanged(m_SoundStreamClientID, m_PlaybackChannels); - notifyCaptureChannelsChanged(m_SoundStreamClientID, m_CaptureChannels); - } -} - - -ConfigPageInfo OSSSoundDevice::createConfigurationPage() -{ - OSSSoundConfiguration *conf = new OSSSoundConfiguration(NULL, this); - TQObject::connect(this, TQT_SIGNAL(sigUpdateConfig()), conf, TQT_SLOT(slotUpdateConfig())); - return ConfigPageInfo (conf, - i18n("OSS Sound"), - i18n("OSS Sound Device Options"), - "kradio_oss"); -} - - -AboutPageInfo OSSSoundDevice::createAboutPage() -{ -/* TDEAboutData aboutData("kradio", - NULL, - NULL, - I18N_NOOP("OSS Sound Plugin for TDERadio"), - TDEAboutData::License_GPL, - "(c) 2004 Martin Witte", - 0, - "http://sourceforge.net/projects/kradio", - 0); - aboutData.addAuthor("Martin Witte", "", "witte@kawo1.rwth-aachen.de"); - - return AboutPageInfo( - new TDERadioAboutWidget(aboutData, TDERadioAboutWidget::AbtTabbed), - i18n("OSS Sound"), - i18n("OSS Sound"), - "kradio_oss_sound" - ); -*/ - return AboutPageInfo(); -} - - - -bool OSSSoundDevice::preparePlayback(SoundStreamID id, const TQString &channel, bool active_mode, bool start_immediately) -{ - if (id.isValid() && m_revPlaybackChannels.contains(channel)) { - m_PlaybackStreams.insert(id, SoundStreamConfig(m_revPlaybackChannels[channel], active_mode)); - if (start_immediately) - startPlayback(id); - return true; - // FIXME: what to do if stream is already playing? - } - return false; -} - - -bool OSSSoundDevice::prepareCapture(SoundStreamID id, const TQString &channel) -{ - if (id.isValid() && m_revCaptureChannels.contains(channel)) { - m_CaptureStreams.insert(id, SoundStreamConfig(m_revCaptureChannels[channel])); - return true; - // FIXME: what to do if stream is already playing? - } - return false; -} - -bool OSSSoundDevice::releasePlayback(SoundStreamID id) -{ - if (id.isValid() && m_PlaybackStreams.contains(id)) { - if (m_PlaybackStreamID == id || m_PassivePlaybackStreams.contains(id)) { - stopPlayback(id); - } - m_PlaybackStreams.remove(id); - return true; - } - return false; -} - -bool OSSSoundDevice::releaseCapture(SoundStreamID id) -{ - if (id.isValid() && m_CaptureStreams.contains(id)) { - if (m_CaptureStreamID == id) { - stopCapture(id); - } - m_CaptureStreams.remove(id); - return true; - } - return false; -} - -bool OSSSoundDevice::supportsPlayback() const -{ - return m_EnablePlayback; -} - - -bool OSSSoundDevice::supportsCapture() const -{ - return m_EnableCapture; -} - - -bool OSSSoundDevice::startPlayback(SoundStreamID id) -{ - if (id.isValid() && m_PlaybackStreams.contains(id) && m_EnablePlayback) { - - SoundStreamConfig &cfg = m_PlaybackStreams[id]; - - bool ok = false; - if (cfg.m_ActiveMode) { - if (!m_PlaybackStreamID.isValid()) { - m_PlaybackStreamID = id; - ok = true; - } - } else { - if (!m_PassivePlaybackStreams.contains(id)) - m_PassivePlaybackStreams.append(id); - ok = true; - } - - if (ok) { - openMixerDevice(); - if (cfg.m_Volume >= 0) - writeMixerVolume(cfg.m_Channel, cfg.m_Volume); - } - - // error handling? - return true; - } else { - return false; - } -} - - -bool OSSSoundDevice::pausePlayback(SoundStreamID /*id*/) -{ - //return stopPlayback(id); - return false; -} - - -bool OSSSoundDevice::stopPlayback(SoundStreamID id) -{ - if (id.isValid() && m_PlaybackStreams.contains(id)) { - - SoundStreamConfig &cfg = m_PlaybackStreams[id]; - - if (!cfg.m_ActiveMode) { - if (m_PassivePlaybackStreams.contains(id)) { -// writeMixerVolume(cfg.m_Channel, 0); - m_PassivePlaybackStreams.remove(id); - } - } else if (m_PlaybackStreamID == id) { - m_PlaybackStreamID = SoundStreamID::InvalidID; - m_PlaybackBuffer.clear(); - closeDSPDevice(); - } - - closeMixerDevice(); - return true; - } else { - return false; - } -} - -bool OSSSoundDevice::isPlaybackRunning(SoundStreamID id, bool &b) const -{ - if (id.isValid() && m_PlaybackStreams.contains(id)) { - b = true; - return true; - } else { - return false; - } -} - -bool OSSSoundDevice::startCaptureWithFormat(SoundStreamID id, - const SoundFormat &proposed_format, - SoundFormat &real_format, - bool force_format) -{ - if (m_CaptureStreams.contains(id) && m_EnableCapture) { - - if (m_CaptureStreamID != id) { - m_CapturePos = 0; - m_CaptureStartTime = time(NULL); - } - - if (m_CaptureStreamID != id || force_format) { - - m_CaptureStreamID = id; - SoundStreamConfig &cfg = m_CaptureStreams[id]; - - openMixerDevice(); - selectCaptureChannel(cfg.m_Channel); - if (cfg.m_Volume >= 0) - writeMixerVolume(cfg.m_Channel, cfg.m_Volume); - - openDSPDevice(proposed_format); - - // FIXME: error handling? - } - - real_format = m_DSPFormat; - m_CaptureRequestCounter++; - - return true; - } else { - return false; - } -} - - -bool OSSSoundDevice::stopCapture(SoundStreamID id) -{ - if (id.isValid() && m_CaptureStreamID == id) { - - if (--m_CaptureRequestCounter == 0) { - m_CaptureStreamID = SoundStreamID::InvalidID; - m_CaptureBuffer.clear(); - - closeMixerDevice(); - closeDSPDevice(); - } - return true; - } else { - return false; - } -} - - -bool OSSSoundDevice::isCaptureRunning(SoundStreamID id, bool &b, SoundFormat &sf) const -{ - if (id.isValid() && m_CaptureStreamID == id) { - b = true; - sf = m_DSPFormat; - return true; - } else { - return false; - } -} - - -bool OSSSoundDevice::noticeSoundStreamClosed(SoundStreamID id) -{ - bool found = false; - if (m_PlaybackStreamID == id || m_PassivePlaybackStreams.contains(id)) { - stopPlayback(id); - found = true; - } - if (m_CaptureStreamID == id) { - stopCapture(id); - found = true; - } - m_PlaybackStreams.remove(id); - m_CaptureStreams.remove(id); - return found; -} - - -bool OSSSoundDevice::noticeSoundStreamRedirected(SoundStreamID oldID, SoundStreamID newID) -{ - bool found = false; - if (m_PlaybackStreams.contains(oldID)) { - m_PlaybackStreams.insert(newID, m_PlaybackStreams[oldID]); - if (newID != oldID) - m_PlaybackStreams.remove(oldID); - found = true; - } - if (m_CaptureStreams.contains(oldID)) { - m_CaptureStreams.insert(newID, m_CaptureStreams[oldID]); - if (newID != oldID) - m_CaptureStreams.remove(oldID); - found = true; - } - - if (m_PlaybackStreamID == oldID) - m_PlaybackStreamID = newID; - if (m_CaptureStreamID == oldID) - m_CaptureStreamID = newID; - if (m_PassivePlaybackStreams.contains(oldID)) { - m_PassivePlaybackStreams.remove(oldID); - m_PassivePlaybackStreams.append(newID); - } - return found; -} - - -bool OSSSoundDevice::noticeSoundStreamData(SoundStreamID id, - const SoundFormat &format, - const char *data, size_t size, size_t &consumed_size, - const SoundMetaData &/*md*/ - ) -{ - if (!id.isValid() || id != m_PlaybackStreamID) - return false; - - if (m_DSP_fd < 0) { - openDSPDevice(format); - } else if (format != m_DSPFormat) { - if (m_CaptureStreamID.isValid()) - return false; - - // flush playback buffer - size_t buffersize = 0; - char *buffer = m_PlaybackBuffer.getData(buffersize); - write(m_DSP_fd, buffer, buffersize); - - // if not all could be written, it must be discarded - m_PlaybackBuffer.clear(); - - closeDSPDevice(); - openDSPDevice(format); - // error handling ? - } - - size_t n = m_PlaybackBuffer.addData(data, size); - consumed_size = (consumed_size == SIZE_T_DONT_CARE) ? n : min(consumed_size, n); - -// if (n < size) { -// m_PlaybackSkipCount += size - n; -// } else if (m_PlaybackSkipCount > 0) { -// logWarning(i18n("%1: Playback buffer overflow. Skipped %1 bytes").arg(m_DSPDeviceName).arg(TQString::number(m_PlaybackSkipCount))); -// m_PlaybackSkipCount = 0; -// } - - return true; //m_PlaybackSkipCount == 0; -} - - - -void OSSSoundDevice::slotPoll() -{ - int err = 0; - - if (m_CaptureStreamID.isValid() && m_DSP_fd >= 0) { - - size_t bufferSize = 0; - char *buffer = m_CaptureBuffer.getFreeSpace(bufferSize); - - int bytesRead = read(m_DSP_fd, buffer, bufferSize); - - if (bytesRead > 0) { - m_CaptureBuffer.removeFreeSpace(bytesRead); - } else if (bytesRead < 0 && errno == EAGAIN) { - bytesRead = 0; - } else if (bytesRead == 0) { - err = -1; - logError(i18n("OSS device %1: No data to record").arg(m_DSPDeviceName)); - } else { - err = errno; - } - - while (m_CaptureBuffer.getFillSize() > m_CaptureBuffer.getSize() / 3) { - size_t size = 0; - buffer = m_CaptureBuffer.getData(size); - time_t cur_time = time(NULL); - size_t consumed_size = SIZE_T_DONT_CARE; - notifySoundStreamData(m_CaptureStreamID, m_DSPFormat, buffer, size, consumed_size, SoundMetaData(m_CapturePos, cur_time - m_CaptureStartTime, cur_time, i18n("internal stream, not stored (%1)").arg(m_DSPDeviceName))); - if (consumed_size == SIZE_T_DONT_CARE) - consumed_size = size; - m_CaptureBuffer.removeData(consumed_size); - m_CapturePos += consumed_size; - if (consumed_size < size) - break; - } - } - - if (m_PlaybackStreamID.isValid()/* && m_DSP_fd >= 0*/) { - - if (m_PlaybackBuffer.getFillSize() > 0 && m_DSP_fd >= 0) { - - size_t buffersize = 0; - char *buffer = m_PlaybackBuffer.getData(buffersize); - int bytesWritten = write(m_DSP_fd, buffer, buffersize); - - if (bytesWritten > 0) { - m_PlaybackBuffer.removeData(bytesWritten); - } else if (bytesWritten < 0 && errno == EAGAIN) { - bytesWritten = 0; - } else { - err = errno; - } - } - - if (m_PlaybackBuffer.getFreeSize() > 0) - notifyReadyForPlaybackData(m_PlaybackStreamID, m_PlaybackBuffer.getFreeSize()); - } - - if (err) { - logError(i18n("Error %1 while handling OSS device %2").arg(TQString().setNum(err)).arg(m_DSPDeviceName)); - } - - if (m_PlaybackStreamID.isValid()) - checkMixerVolume(m_PlaybackStreamID); - if (m_CaptureStreamID.isValid()) - checkMixerVolume(m_CaptureStreamID); - - TQValueListConstIterator<SoundStreamID> end = m_PassivePlaybackStreams.end(); - for (TQValueListConstIterator<SoundStreamID> it = m_PassivePlaybackStreams.begin(); it != end; ++it) - checkMixerVolume(*it); - -} - - -bool OSSSoundDevice::openDSPDevice(const SoundFormat &format, bool reopen) -{ - if (m_DSP_fd >= 0) { - - if (reopen) { - - closeDSPDevice ( /* force = */ true); - - } else { - - if (format != m_DSPFormat) - return false; - - if (m_DuplexMode != DUPLEX_FULL && m_CaptureStreamID.isValid() && m_PlaybackStreamID.isValid()) - return false; - - return true; - } - } else { - if (reopen) - return true; - } - - m_DSPFormat = format; - - // first testopen for CAPS - m_DSP_fd = open(m_DSPDeviceName.ascii(), O_NONBLOCK | O_RDONLY); - bool err = m_DSP_fd < 0; - if (err) { - logError(i18n("Cannot open DSP device %1").arg(m_DSPDeviceName)); - return false; - } - int caps = 0; - err |= (ioctl (m_DSP_fd, SNDCTL_DSP_GETCAPS, &caps) != 0); - if (err) - logError(i18n("Cannot read DSP capabilities for %1").arg(m_DSPDeviceName)); - - m_DuplexMode = (caps & DSP_CAP_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF; - close (m_DSP_fd); - m_DSP_fd = -1; - - // opening and seeting up the device file - int mode = O_NONBLOCK; - if (m_DuplexMode == DUPLEX_FULL) { - mode |= O_RDWR; - } else if (m_CaptureStreamID.isValid()) { - mode |= O_RDONLY; - } else { - mode |= O_WRONLY; - } - - m_DSP_fd = open(m_DSPDeviceName.ascii(), mode); - - err = m_DSP_fd < 0; - if (err) { - logError(i18n("Cannot open DSP device %1").arg(m_DSPDeviceName)); - return false; - } - - int oss_format = getOSSFormat(m_DSPFormat); - err |= (ioctl(m_DSP_fd, SNDCTL_DSP_SETFMT, &oss_format) != 0); - if (err) - logError(i18n("Cannot set DSP sample format for %1").arg(m_DSPDeviceName)); - - int channels = m_DSPFormat.m_Channels; - err |= (ioctl(m_DSP_fd, SNDCTL_DSP_CHANNELS, &channels) != 0); - if (err) - logError(i18n("Cannot set number of channels for %1").arg(m_DSPDeviceName)); - - int rate = m_DSPFormat.m_SampleRate; - err |= (ioctl(m_DSP_fd, SNDCTL_DSP_SPEED, &rate) != 0); - if (err) - logError(i18n("Cannot set sampling rate for %1").arg(m_DSPDeviceName)); - if (rate != (int)m_DSPFormat.m_SampleRate) { - logWarning(i18n("Asking for %1 Hz but %2 uses %3 Hz"). - arg(TQString::number(m_DSPFormat.m_SampleRate)). - arg(m_DSPDeviceName). - arg(TQString::number(rate))); - m_DSPFormat.m_SampleRate = rate; - } - - int stereo = m_DSPFormat.m_Channels == 2; - err |= (ioctl(m_DSP_fd, SNDCTL_DSP_STEREO, &stereo) != 0); - if (err) - logError(i18n("Cannot set stereo mode for %1").arg(m_DSPDeviceName)); - - unsigned sampleSize = m_DSPFormat.m_SampleBits; - err |= (ioctl(m_DSP_fd, SNDCTL_DSP_SAMPLESIZE, &sampleSize) != 0); - if (err || sampleSize != m_DSPFormat.m_SampleBits) - logError(i18n("Cannot set sample size for %1").arg(m_DSPDeviceName)); - - // setup buffer, ask for 40ms latency - int tmp = (400 * m_DSPFormat.frameSize() * m_DSPFormat.m_SampleRate) / 1000; - int mask = -1; for (; tmp; tmp >>= 1) ++mask; - if (mask < 8) mask = 12; // default 4kB - mask |= 0x7FFF0000; - err |= ioctl (m_DSP_fd, SNDCTL_DSP_SETFRAGMENT, &mask); - if (err) - logError(i18n("Cannot set buffers for %1").arg(m_DSPDeviceName)); - - int bufferBlockSize = 0; - err |= ioctl (m_DSP_fd, SNDCTL_DSP_GETBLKSIZE, &bufferBlockSize); - if (err) { - logError(i18n("Cannot read buffer size for %1").arg(m_DSPDeviceName)); - } else { - logInfo(i18n("%1 uses buffer blocks of %2 bytes").arg(m_DSPDeviceName).arg(TQString::number(bufferBlockSize))); - size_t tmp = (((m_BufferSize - 1) / bufferBlockSize) + 1) * bufferBlockSize; - setBufferSize(tmp); - logInfo(i18n("adjusted own buffer size to %1 bytes").arg(TQString::number(tmp))); - } - - int trigger = ~PCM_ENABLE_INPUT & ~PCM_ENABLE_OUTPUT; - ioctl(m_DSP_fd, SNDCTL_DSP_SETTRIGGER, &trigger); - trigger = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT; - ioctl(m_DSP_fd, SNDCTL_DSP_SETTRIGGER, &trigger); - - if (!err) { - m_PollingTimer.start(40); - } else { - closeDSPDevice(); - } - - m_CaptureSkipCount = 0; - //m_PlaybackSkipCount = 0; - - return !err; -} - - -bool OSSSoundDevice::closeDSPDevice(bool force) -{ - if ((!m_PlaybackStreamID.isValid() && !m_CaptureStreamID.isValid()) || force) { - - if (m_Mixer_fd < 0) - m_PollingTimer.stop(); - - if (m_DSP_fd >= 0) - close (m_DSP_fd); - m_DSP_fd = -1; - - m_PlaybackBuffer.clear(); - m_CaptureBuffer.clear(); - } - return true; -} - - -bool OSSSoundDevice::openMixerDevice(bool reopen) -{ - if (reopen) { - if (m_Mixer_fd >= 0) - closeMixerDevice(/* force = */ true); - else - return true; - } - - if (m_Mixer_fd < 0) - m_Mixer_fd = open(m_MixerDeviceName.ascii(), O_RDONLY); - - if (m_Mixer_fd < 0) { - logError(i18n("Cannot open mixer device %1").arg(m_MixerDeviceName)); - } else { - m_PollingTimer.start(40); - } - return m_Mixer_fd >= 0; -} - - -bool OSSSoundDevice::closeMixerDevice(bool force) -{ - if ((!m_PlaybackStreamID.isValid() && !m_CaptureStreamID.isValid()) || force) { - - if (m_DSP_fd < 0) - m_PollingTimer.stop(); - - if (m_Mixer_fd >= 0) - close (m_Mixer_fd); - m_Mixer_fd = -1; - } - return m_Mixer_fd < 0; -} - - -void OSSSoundDevice::getMixerChannels(int query, TQStringList &retval, TQMap<TQString, int> &revmap) const -{ - retval.clear(); - revmap.clear(); - - int fd = m_Mixer_fd; - if (fd < 0) - fd = open(m_MixerDeviceName.ascii(), O_RDONLY); - - if (fd < 0) { - logError(i18n("OSSSoundDevice::getMixerChannels: Cannot open mixer device %1").arg(m_MixerDeviceName)); - } - - if (fd >= 0) { - int mask = 0; - if ( ioctl(fd, MIXER_READ(query), &mask) == 0 ) { - for (int i = 0; i < SOUND_MIXER_NRDEVICES; ++i) { - if (mask & (1 << i)) { - static const char *labels[] = SOUND_DEVICE_LABELS; - retval.append(i18n(labels[i])); - revmap.insert(i18n(labels[i]), i); - } - } - } else { - logError(i18n("OSSSoundDevice::getMixerChannels: Cannot read mixer device mask on device %1").arg(m_MixerDeviceName)); - } - } - if (fd != m_Mixer_fd) - close(fd); -} - - -const TQStringList &OSSSoundDevice::getPlaybackChannels() const -{ - return m_PlaybackChannels; -} - - -const TQStringList &OSSSoundDevice::getCaptureChannels() const -{ - return m_CaptureChannels; -} - - -bool OSSSoundDevice::setPlaybackVolume(SoundStreamID id, float volume) -{ - if (id.isValid() && (m_PlaybackStreamID == id || m_PassivePlaybackStreams.contains(id))) { - SoundStreamConfig &cfg = m_PlaybackStreams[id]; - - if (rint(100*volume) != rint(100*cfg.m_Volume)) { - cfg.m_Volume = writeMixerVolume(cfg.m_Channel, volume); - notifyPlaybackVolumeChanged(id, cfg.m_Volume); - } - return true; - } - return false; -} - - -bool OSSSoundDevice::setCaptureVolume(SoundStreamID id, float volume) -{ - if (id.isValid() && m_CaptureStreamID == id) { - SoundStreamConfig &cfg = m_CaptureStreams[id]; - - if (rint(100*volume) != rint(100*cfg.m_Volume)) { - cfg.m_Volume = writeMixerVolume(cfg.m_Channel, volume); - notifyCaptureVolumeChanged(id, cfg.m_Volume); - } - return true; - } - return false; -} - - -bool OSSSoundDevice::getPlaybackVolume(SoundStreamID id, float &volume) const -{ - if (id.isValid() && (m_PlaybackStreamID == id || m_PassivePlaybackStreams.contains(id))) { - const SoundStreamConfig &cfg = m_PlaybackStreams[id]; - volume = cfg.m_Volume; - return true; - } - return false; -} - - -bool OSSSoundDevice::getCaptureVolume(SoundStreamID id, float &volume) const -{ - if (id.isValid() && m_CaptureStreamID == id) { - const SoundStreamConfig &cfg = m_CaptureStreams[id]; - volume = cfg.m_Volume; - return true; - } - return false; -} - - -void OSSSoundDevice::checkMixerVolume(SoundStreamID id) -{ - if (m_Mixer_fd >= 0 && id.isValid()) { - - if (m_PassivePlaybackStreams.contains(id) || m_PlaybackStreamID == id) { - SoundStreamConfig &cfg = m_PlaybackStreams[id]; - - float v = readMixerVolume(cfg.m_Channel); - if (rint(100*cfg.m_Volume) != rint(100*v)) { - cfg.m_Volume = v; - notifyPlaybackVolumeChanged(id, v); - } - } - - if (m_CaptureStreamID == id) { - SoundStreamConfig &cfg = m_CaptureStreams[id]; - - float v = readMixerVolume(cfg.m_Channel); - if (rint(100*cfg.m_Volume) != rint(100*v)) { - cfg.m_Volume = v; - notifyCaptureVolumeChanged(id, v); - } - } - } -} - - -float OSSSoundDevice::readMixerVolume(int channel) const -{ - _lrvol tmpvol; - int err = ioctl(m_Mixer_fd, MIXER_READ(channel), &tmpvol); - if (err) { - logError("OSSSound::readMixerVolume: " + - i18n("error %1 while reading volume from %2") - .arg(TQString().setNum(err)) - .arg(m_MixerDeviceName)); - tmpvol.l = tmpvol.r = 0; - } - return float(tmpvol.l) / 100.0; -} - - -float OSSSoundDevice::writeMixerVolume (int channel, float vol) -{ - if (vol > 1.0) vol = 1.0; - if (vol < 0) vol = 0.0; - - const int divs = 100; - vol = rint(vol * divs) / float(divs); - - if (m_Mixer_fd >= 0) { - _lrvol tmpvol; - tmpvol.r = tmpvol.l = (unsigned int)(rint(vol * divs)); - int err = ioctl(m_Mixer_fd, MIXER_WRITE(channel), &tmpvol); - if (err != 0) { - logError("OSSSoundDevice::writeMixerVolume: " + - i18n("error %1 while setting volume to %2 on device %3") - .arg(TQString().setNum(err)) - .arg(TQString().setNum(vol)) - .arg(m_MixerDeviceName)); - return -1; - } - } - return vol; -} - - -void OSSSoundDevice::selectCaptureChannel (int channel) -{ - int x = 1 << channel; - int err = ioctl(m_Mixer_fd, SOUND_MIXER_WRITE_RECSRC, &x); - if (err) - logError(i18n("Selecting recording source on device %1 failed with error code %2") - .arg(m_MixerDeviceName) - .arg(TQString::number(err))); - _lrvol tmpvol; - err = ioctl(m_Mixer_fd, MIXER_READ(SOUND_MIXER_IGAIN), &tmpvol); - if (err) - logError(i18n("Reading igain volume on device %1 failed with error code %2") - .arg(m_MixerDeviceName) - .arg(TQString::number(err))); - if (tmpvol.r == 0 && tmpvol.l == 0) { - tmpvol.r = tmpvol.l = 1; - err = ioctl(m_Mixer_fd, MIXER_WRITE(SOUND_MIXER_IGAIN), &tmpvol); - if (err) - logError(i18n("Setting igain volume on device %1 failed with error code %2") - .arg(m_MixerDeviceName) - .arg(TQString::number(err))); - } -} - - -int OSSSoundDevice::getOSSFormat(const SoundFormat &f) -{ - if (f.m_SampleBits == 16) { - switch (2 * f.m_IsSigned + (f.m_Endianess == LITTLE_ENDIAN)) { - case 0: return AFMT_U16_BE; - case 1: return AFMT_U16_LE; - case 2: return AFMT_S16_BE; - case 3: return AFMT_S16_LE; - } - } - if (f.m_SampleBits == 8) { - switch (f.m_IsSigned) { - case 0: return AFMT_U8; - case 1: return AFMT_S8; - } - } - return 0; -} - - -void OSSSoundDevice::setBufferSize(int s) -{ - m_BufferSize = s; - m_PlaybackBuffer.resize(m_BufferSize); - m_CaptureBuffer.resize(m_BufferSize); -} - - -void OSSSoundDevice::enablePlayback(bool on) -{ - m_EnablePlayback = on; -} - - -void OSSSoundDevice::enableCapture(bool on) -{ - m_EnableCapture = on; -} - - -void OSSSoundDevice::setDSPDeviceName(const TQString &s) -{ - m_DSPDeviceName = s; - SoundFormat f = m_DSPFormat; - if (m_DSP_fd >= 0) - openDSPDevice(f, /* reopen = */ true); -} - - -TQString OSSSoundDevice::getSoundStreamClientDescription() const -{ - return i18n("OSS Sound Device %1").arg(PluginBase::name()); -} - - - -#include "oss-sound.moc" |