12#include "libmythbase/mythconfig.h"
20#define LOC QString("AOOSS: ")
53 while (
int rate = settings->GetNextRate())
56 if(ioctl(
m_audioFd, SNDCTL_DSP_SPEED, &rate2) >= 0
58 settings->AddSupportedRate(rate);
62 Error(
LOC +
"Error retrieving formats" +
": " +
ENO);
67 int ofmt = AFMT_QUERY;
77 settings->AddSupportedFormat(fmt);
83 settings->setPassthrough(
static_cast<int>((
formats & AFMT_AC3) != 0) - 1);
86 for (
int i = 1; i <= 2; i++)
90 if (ioctl(
m_audioFd, SNDCTL_DSP_CHANNELS, &channel) >= 0 &&
93 settings->AddSupportedChannels(i);
110 LOG(VB_AUDIO, LOG_INFO,
LOC + QString(
"Opening OSS audio device '%1'.").arg(
m_mainDevice));
115 m_audioFd = open(device.constData(), O_WRONLY);
116 if (
m_audioFd < 0 && errno != EAGAIN && errno != EINTR)
120 LOG(VB_GENERAL, LOG_WARNING,
LOC + QString(
"Something is currently using: %1.")
124 Error(
LOC + QString(
"Error opening audio device (%1)")
141 Error(
LOC + QString(
"Error removing the O_NONBLOCK flag from audio device FD (%1)").arg(
m_mainDevice) +
": " +
ENO);
145 int format = AFMT_QUERY;
158#if defined(AFMT_AC3) && defined(SNDCTL_DSP_GETFMTS)
161 int format_support = 0;
162 if (!ioctl(
m_audioFd, SNDCTL_DSP_GETFMTS, &format_support) &&
163 (format_support & AFMT_AC3))
174 ioctl(
m_audioFd, SNDCTL_DSP_SETFMT, &format) < 0)
180 if (ioctl(
m_audioFd, SNDCTL_DSP_STEREO, &stereo) < 0 ||
182 ioctl(
m_audioFd, SNDCTL_DSP_SETFMT, &format) < 0)
188 Error(
LOC + QString(
"Unable to set audio device (%1) to %2 kHz, %3 bits, "
201 Error(
LOC +
"Error retrieving card buffer size" +
": " +
ENO);
209 if (ioctl(
m_audioFd, SNDCTL_DSP_GETCAPS, &caps) == 0)
211 if (!(caps & DSP_CAP_REALTIME))
212 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"The audio device cannot report buffer state "
213 "accurately! audio/video sync will be bad, continuing...");
217 Error(
LOC +
"Unable to get audio card capabilities" +
": " +
ENO);
247 uchar *tmpbuf = aubuf;
249 while ((written < size) &&
258 Error(
LOC + QString(
"Error writing to audio device (%1)")
267 int soundcard_buffer=0;
269#ifdef SNDCTL_DSP_GETODELAY
270 if(ioctl(
m_audioFd, SNDCTL_DSP_GETODELAY, &soundcard_buffer) < 0)
271 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Error retrieving buffering delay" +
": " +
ENO);
273 return soundcard_buffer;
281 if (device.toLower() ==
"software")
284 QByteArray dev = device.toLatin1();
285 m_mixerFd = open(dev.constData(), O_RDONLY);
289 if (controlLabel ==
"Master")
296 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Unable to open mixer: '%1'").arg(device));
303 int tmpVol = (volume << 8) + volume;
304 int ret = ioctl(
m_mixerFd, MIXER_WRITE(SOUND_MIXER_VOLUME), &tmpVol);
306 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Error Setting initial Master Volume") +
ENO);
309 tmpVol = (volume << 8) + volume;
310 ret = ioctl(
m_mixerFd, MIXER_WRITE(SOUND_MIXER_PCM), &tmpVol);
312 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Error setting initial PCM Volume") +
ENO);
336 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Error reading volume for channel %1").arg(channel));
341 volume = tmpVol & 0xff;
342 else if (channel == 1)
343 volume = (tmpVol >> 8) & 0xff;
345 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Invalid channel. Only stereo volume supported");
355 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Error setting channel %1. Only 2 ch volume supported")
372 LOG(VB_GENERAL, LOG_ERR,
LOC + QString(
"Error setting volume on channel %1").arg(channel));
void KillAudio(void)
Kill the output thread and cleanup.
void Reconfigure(const AudioSettings &settings) override
(Re)Configure AudioOutputBase
AudioFormat m_outputFormat
int m_outputBytesPerFrame
long m_soundcardBufferSize
void InitSettings(const AudioSettings &settings)
void WriteAudio(unsigned char *aubuf, int size) override
~AudioOutputOSS() override
int GetVolumeChannel(int channel) const override
void CloseDevice(void) override
int GetBufferedOnSoundcard(void) const override
Return the size in bytes of frames currently in the audio buffer adjusted with the audio playback lat...
AudioOutputOSS(const AudioSettings &settings)
bool OpenDevice(void) override
void SetVolumeChannel(int channel, int volume) override
AudioOutputSettings * GetOutputSettings(bool digital) override
static int FormatToBits(AudioFormat format)
void Error(const QString &msg)
bool m_init
If set to false, AudioOutput instance will not try to initially open the audio device.
static void usleep(std::chrono::microseconds time)
QString GetSetting(const QString &key, const QString &defaultval="")
int GetNumSetting(const QString &key, int defaultval=0)
A QElapsedTimer based timer to replace use of QTime as a timer.
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
void start(void)
starts measuring elapsed time.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define ENO
This can be appended to the LOG args with "+".
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
def write(text, progress=True)
static eu8 clamp(eu8 value, eu8 low, eu8 high)
const std::array< const std::string, 8 > formats