summaryrefslogtreecommitdiffstats
path: root/audiooutput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audiooutput.cpp')
-rw-r--r--audiooutput.cpp102
1 files changed, 102 insertions, 0 deletions
diff --git a/audiooutput.cpp b/audiooutput.cpp
new file mode 100644
index 0000000..03f3c5c
--- /dev/null
+++ b/audiooutput.cpp
@@ -0,0 +1,102 @@
+#include "audiooutput.h"
+
+#include <QDebug>
+
+AudioOutput::AudioOutput()
+ : QThread(), m_despotifySession(0),
+ frameSize(16 * 2 / 8), m_channels(2), m_bitrate(44100), m_state(Pause)
+{
+ int rc;
+ snd_pcm_hw_params_t *params;
+ int dir;
+ /* Open PCM device for playback. */
+ rc = snd_pcm_open(&m_alsaHandle, "default",
+ SND_PCM_STREAM_PLAYBACK, 0);
+ if (rc < 0) {
+ qWarning() << "unable to open pcm device: " << snd_strerror(rc);
+ }
+
+ /* Allocate a hardware parameters object. */
+ snd_pcm_hw_params_alloca(&params);
+
+ /* Fill it in with default values. */
+ snd_pcm_hw_params_any(m_alsaHandle, params);
+
+ /* Set the desired hardware parameters. */
+
+ /* Interleaved mode */
+ snd_pcm_hw_params_set_access(m_alsaHandle, params,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
+
+ /* Signed 16-bit little-endian format */
+ snd_pcm_hw_params_set_format(m_alsaHandle, params,
+ SND_PCM_FORMAT_S16);
+
+ /* Two channels (stereo) */
+ snd_pcm_hw_params_set_channels(m_alsaHandle, params, m_channels);
+
+ /* 44100 bits/second sampling rate (CD quality) */
+ snd_pcm_hw_params_set_rate_near(m_alsaHandle, params,
+ &m_bitrate, &dir);
+
+ /* Write the parameters to the driver */
+ rc = snd_pcm_hw_params(m_alsaHandle, params);
+ if (rc < 0) {
+ qWarning() << "unable to set hw parameters: " << snd_strerror(rc);
+ }
+ snd_pcm_prepare(m_alsaHandle);
+
+ start();
+
+}
+
+AudioOutput::~AudioOutput()
+{
+ snd_pcm_close (m_alsaHandle);
+}
+
+void AudioOutput::setDespotifySession(despotify_session *ds)
+{
+ pause();
+ m_despotifySession = ds;
+}
+
+void AudioOutput::play()
+{
+ if (m_state != Play) {
+ m_state = Play;
+ m_isPlaying.wakeAll();
+ }
+}
+
+void AudioOutput::pause()
+{
+ if (m_state != Pause) {
+ m_state = Pause;
+ QMutex lock;
+ lock.lock();
+ m_isPause.wait(&lock);
+ }
+}
+
+void AudioOutput::run()
+{
+ QMutex lock;
+ lock.lock();
+ forever {
+ switch (m_state) {
+ case Pause:
+ m_isPause.wakeAll();
+ m_isPlaying.wait(&lock);
+ break;
+ case Play:
+ pcm_data pcm;
+ despotify_get_pcm(m_despotifySession,&pcm);
+ int frames = pcm.len / frameSize;
+ int framesWritten = snd_pcm_writei(m_alsaHandle,pcm.buf,frames);
+ if (framesWritten != frames)
+ snd_pcm_prepare(m_alsaHandle);
+ break;
+ }
+ }
+}