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(¶ms);
/* 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;
}
}
}
|