summaryrefslogtreecommitdiffstats
path: root/audiooutput.cpp
blob: 03f3c5c7329c18e0aed473b2182538babc4915bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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;
        }
    }
}