You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
10 KiB
298 lines
10 KiB
/***************************************************************************
|
|
alsa-sound.h - description
|
|
-------------------
|
|
begin : Thu May 26 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. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#ifndef _KRADIO_ALSA_SOUND_H
|
|
#define _KRADIO_ALSA_SOUND_H
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include "../../src/include/ringbuffer.h"
|
|
#include "../../src/include/plugins.h"
|
|
#include "../../src/include/soundstreamclient_interfaces.h"
|
|
|
|
#include "alsa-config-mixer-setting.h"
|
|
|
|
#include <tqobject.h>
|
|
#include <tqtimer.h>
|
|
#include <alsa/asoundlib.h>
|
|
|
|
enum DUPLEX_MODE { DUPLEX_UNKNOWN, DUPLEX_FULL, DUPLEX_HALF };
|
|
|
|
|
|
struct SoundStreamConfig
|
|
{
|
|
SoundStreamConfig()
|
|
: m_ActiveMode(false),
|
|
m_Channel(TQString()),
|
|
m_Volume(-1),
|
|
m_Muted(false)
|
|
{}
|
|
|
|
SoundStreamConfig(const TQString &_channel, bool active_mode = true)
|
|
: m_ActiveMode(active_mode),
|
|
m_Channel(_channel),
|
|
m_Volume(-1),
|
|
m_Muted(false)
|
|
{}
|
|
|
|
SoundStreamConfig(const SoundStreamConfig &c)
|
|
: m_ActiveMode(c.m_ActiveMode),
|
|
m_Channel(c.m_Channel),
|
|
m_Volume(c.m_Volume),
|
|
m_Muted(c.m_Muted)
|
|
{}
|
|
|
|
bool m_ActiveMode;
|
|
TQString m_Channel;
|
|
float m_Volume;
|
|
bool m_Muted;
|
|
};
|
|
|
|
|
|
class AlsaCaptureThread;
|
|
|
|
class AlsaMixerElement
|
|
{
|
|
public:
|
|
AlsaMixerElement() { snd_mixer_selem_id_malloc(&m_ID); }
|
|
AlsaMixerElement(snd_mixer_selem_id_t *id) { snd_mixer_selem_id_malloc(&m_ID); snd_mixer_selem_id_copy(m_ID, id) ; }
|
|
AlsaMixerElement(const AlsaMixerElement &x) { snd_mixer_selem_id_malloc(&m_ID); snd_mixer_selem_id_copy(m_ID, x.m_ID); }
|
|
~AlsaMixerElement() { snd_mixer_selem_id_free (m_ID); }
|
|
|
|
operator snd_mixer_selem_id_t *&() { return m_ID; }
|
|
|
|
AlsaMixerElement &operator = (const AlsaMixerElement &x) { snd_mixer_selem_id_copy(m_ID, x.m_ID); return *this; }
|
|
|
|
protected:
|
|
snd_mixer_selem_id_t *m_ID;
|
|
};
|
|
|
|
|
|
class AlsaSoundDevice : public TQObject,
|
|
public PluginBase,
|
|
public ISoundStreamClient
|
|
{
|
|
Q_OBJECT
|
|
TQ_OBJECT
|
|
|
|
public:
|
|
AlsaSoundDevice (const TQString &name);
|
|
virtual ~AlsaSoundDevice ();
|
|
|
|
virtual bool connectI(Interface *i);
|
|
virtual bool disconnectI(Interface *i);
|
|
|
|
// PluginBase
|
|
|
|
public:
|
|
virtual void saveState (KConfig *) const;
|
|
virtual void restoreState (KConfig *);
|
|
|
|
virtual TQString pluginClassName() const { return "AlsaSoundDevice"; }
|
|
|
|
virtual const TQString &name() const { return PluginBase::name(); }
|
|
virtual TQString &name() { return PluginBase::name(); }
|
|
|
|
virtual ConfigPageInfo createConfigurationPage();
|
|
virtual AboutPageInfo createAboutPage();
|
|
|
|
// ISoundStreamClient: direct device access
|
|
|
|
RECEIVERS:
|
|
void noticeConnectedI (ISoundStreamServer *s, bool pointer_valid);
|
|
bool preparePlayback(SoundStreamID id, const TQString &channel, bool active_mode, bool start_immediately);
|
|
bool prepareCapture(SoundStreamID id, const TQString &channel);
|
|
bool releasePlayback(SoundStreamID id);
|
|
bool releaseCapture(SoundStreamID id);
|
|
|
|
ANSWERS:
|
|
bool supportsPlayback() const;
|
|
bool supportsCapture() const;
|
|
|
|
TQString getSoundStreamClientDescription() const;
|
|
|
|
// ISoundStreamClient: mixer access
|
|
|
|
public:
|
|
static
|
|
void getPlaybackMixerChannels(int card, snd_mixer_t *mixer_handle,
|
|
TQStringList &retval, TQMap<TQString, AlsaMixerElement> &int2id);
|
|
static
|
|
void getCaptureMixerChannels (int card, snd_mixer_t *mixer_handle,
|
|
TQStringList &vol_list, TQMap<TQString, AlsaMixerElement> &vol_ch2id,
|
|
TQStringList &sw_list, TQMap<TQString, AlsaMixerElement> &sw_ch2id,
|
|
TQStringList *all_list = NULL);
|
|
|
|
ANSWERS:
|
|
const TQStringList &getPlaybackChannels() const;
|
|
const TQStringList &getCaptureChannels() const;
|
|
|
|
RECEIVERS:
|
|
bool setPlaybackVolume(SoundStreamID id, float volume);
|
|
bool setCaptureVolume(SoundStreamID id, float volume);
|
|
bool getPlaybackVolume(SoundStreamID id, float &volume) const;
|
|
bool getCaptureVolume(SoundStreamID id, float &volume) const;
|
|
|
|
bool mute (SoundStreamID id, bool mute);
|
|
bool unmute (SoundStreamID id, bool unmute);
|
|
bool isMuted(SoundStreamID id, bool &m) const;
|
|
|
|
|
|
// ISoundStreamClient: generic broadcasts
|
|
|
|
RECEIVERS:
|
|
bool startPlayback(SoundStreamID id);
|
|
bool pausePlayback(SoundStreamID id);
|
|
bool stopPlayback(SoundStreamID id);
|
|
bool isPlaybackRunning(SoundStreamID id, bool &b) const;
|
|
|
|
bool startCaptureWithFormat(SoundStreamID id,
|
|
const SoundFormat &proposed_format,
|
|
SoundFormat &real_format,
|
|
bool force_format);
|
|
bool stopCapture(SoundStreamID id);
|
|
bool isCaptureRunning(SoundStreamID id, bool &b, SoundFormat &sf) const;
|
|
|
|
bool noticeSoundStreamClosed(SoundStreamID id);
|
|
bool noticeSoundStreamRedirected(SoundStreamID oldID, SoundStreamID newID);
|
|
|
|
bool noticeSoundStreamData(SoundStreamID id,
|
|
const SoundFormat &,
|
|
const char *data, size_t size, size_t &consumed_size,
|
|
const SoundMetaData &md
|
|
);
|
|
|
|
|
|
// Config Access
|
|
|
|
int getHWBufferSize() const { return m_HWBufferSize; }
|
|
int getBufferSize() const { return m_BufferSize; }
|
|
bool isPlaybackEnabled() const { return m_EnablePlayback; }
|
|
bool isCaptureEnabled() const { return m_EnableCapture; }
|
|
int getPlaybackCard() const { return m_PlaybackCard; }
|
|
int getPlaybackDevice() const { return m_PlaybackDevice; }
|
|
int getCaptureCard() const { return m_CaptureCard; }
|
|
int getCaptureDevice() const { return m_CaptureDevice; }
|
|
const TQMap<TQString, AlsaConfigMixerSetting> &
|
|
getCaptureMixerSettings() const { return m_CaptureMixerSettings; }
|
|
|
|
void setHWBufferSize(int s);
|
|
void setBufferSize(int s);
|
|
void enablePlayback(bool on);
|
|
void enableCapture(bool on);
|
|
void setPlaybackDevice(int card, int device);
|
|
void setCaptureDevice(int card, int device);
|
|
void setCaptureMixerSettings(const TQMap<TQString, AlsaConfigMixerSetting> &map);
|
|
|
|
protected slots:
|
|
|
|
void slotPollPlayback();
|
|
void slotPollCapture();
|
|
|
|
signals:
|
|
|
|
void sigUpdateConfig();
|
|
|
|
protected:
|
|
// bool event(TQEvent *_e);
|
|
|
|
bool openAlsaDevice(snd_pcm_t *&alsa_handle, SoundFormat &format, const char *pcm_name, snd_pcm_stream_t stream, int flags, unsigned &latency);
|
|
|
|
bool openPlaybackDevice (const SoundFormat &format, bool reopen = false);
|
|
bool openCaptureDevice (const SoundFormat &format, bool reopen = false);
|
|
bool closePlaybackDevice(bool force = false);
|
|
bool closeCaptureDevice (bool force = false);
|
|
|
|
bool openPlaybackMixerDevice (bool reopen = false);
|
|
bool openCaptureMixerDevice (bool reopen = false);
|
|
static bool openMixerDevice(snd_mixer_t *&mixer_handle, int card, bool reopen, TQTimer *timer, int timer_latency);
|
|
bool closeCaptureMixerDevice (bool force = false);
|
|
bool closePlaybackMixerDevice(bool force = false);
|
|
static bool closeMixerDevice(snd_mixer_t *&mixer_handle, int card, SoundStreamID id, snd_pcm_t *pcm_handle, bool force, TQTimer *timer);
|
|
|
|
void checkMixerVolume(SoundStreamID id);
|
|
float readPlaybackMixerVolume(const TQString &channel, bool &muted) const;
|
|
float readCaptureMixerVolume(const TQString &channel) const;
|
|
bool writePlaybackMixerVolume(const TQString &channel, float &vol, bool muted);
|
|
bool writeCaptureMixerVolume(const TQString &channel, float &vol);
|
|
bool writeCaptureMixerSwitch(const TQString &channel, bool capture);
|
|
|
|
void selectCaptureChannel (const TQString &channel);
|
|
|
|
/* ALSA HANDLES */
|
|
snd_pcm_t *m_hPlayback;
|
|
snd_pcm_t *m_hCapture;
|
|
snd_mixer_t *m_hPlaybackMixer;
|
|
snd_mixer_t *m_hCaptureMixer;
|
|
|
|
SoundFormat m_PlaybackFormat;
|
|
SoundFormat m_CaptureFormat;
|
|
int m_PlaybackCard;
|
|
int m_PlaybackDevice;
|
|
int m_CaptureCard;
|
|
int m_CaptureDevice;
|
|
|
|
unsigned m_PlaybackLatency;
|
|
unsigned m_CaptureLatency;
|
|
|
|
TQStringList m_PlaybackChannels,
|
|
m_CaptureChannels,
|
|
m_CaptureChannelsSwitch;
|
|
|
|
TQMap<TQString, AlsaMixerElement> m_PlaybackChannels2ID,
|
|
m_CaptureChannels2ID,
|
|
m_CaptureChannelsSwitch2ID;
|
|
|
|
TQMap<SoundStreamID, SoundStreamConfig>
|
|
m_PlaybackStreams,
|
|
m_CaptureStreams;
|
|
|
|
TQValueList<SoundStreamID>
|
|
m_PassivePlaybackStreams;
|
|
SoundStreamID m_PlaybackStreamID,
|
|
m_CaptureStreamID;
|
|
|
|
size_t m_HWBufferSize;
|
|
size_t m_BufferSize;
|
|
RingBuffer m_PlaybackBuffer,
|
|
m_CaptureBuffer;
|
|
|
|
unsigned m_CaptureRequestCounter;
|
|
TQ_UINT64 m_CapturePos;
|
|
time_t m_CaptureStartTime;
|
|
|
|
size_t //m_PlaybackSkipCount,
|
|
m_CaptureSkipCount;
|
|
|
|
bool m_EnablePlayback,
|
|
m_EnableCapture;
|
|
|
|
TQTimer m_PlaybackPollingTimer;
|
|
TQTimer m_CapturePollingTimer;
|
|
|
|
// AlsaCaptureThread *m_captureThread;
|
|
|
|
TQMap<TQString, AlsaConfigMixerSetting> m_CaptureMixerSettings;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|