forked from mikejuni/shairport
-
Notifications
You must be signed in to change notification settings - Fork 1
/
audio_alsa.c
103 lines (87 loc) · 2.87 KB
/
audio_alsa.c
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
103
#define ALSA_PCM_NEW_HW_PARAMS_API
#include <alsa/asoundlib.h>
#include <math.h>
#include "common.h"
#define NUM_CHANNELS 2
static snd_pcm_t *alsa_handle = NULL;
static snd_pcm_hw_params_t *alsa_params = NULL;
static char g_card[56] = "default";
void parse_audio_arg(char* arg)
{
if (!strncmp(arg,"--alsa_pcm=",11))
{
strncpy(g_card,arg+11,55);
}
}
void audio_set_driver(char* driver) {
syslog(LOG_INFO, "ALSA: audio_set_driver: this sets the PCM device to :%s\n",g_card);
}
char* audio_get_driver(void)
{
return g_card;
}
char* audio_get_device_name(void)
{
return NULL;
}
char* audio_get_device_id(void)
{
return NULL;
}
inline void audio_play(char* outbuf, int samples, void* priv_data)
{
#ifdef DEBUGALSA
snd_pcm_sframes_t avail=snd_pcm_avail (alsa_handle);
syslog(LOG_DEBUG,"AUDIO_PLAY: Available buffer in ALSA:%d, Sample size %d\n",(int)avail,samples);
#endif
int err = snd_pcm_writei(alsa_handle, outbuf, samples);
if (err < 0)
{
err = snd_pcm_recover(alsa_handle, err, 0);
if (err < 0)
syslog(LOG_DEBUG, "AUDIO_PLAY: snd_pcm_writei failed: %s\n", snd_strerror(err));
}
}
void* audio_init(int sampling_rate)
{
syslog(LOG_INFO, "ALSA: audio_set_driver: this sets the PCM device to :%s\n",g_card);
#ifdef DEBUGALSA
syslog(LOG_DEBUG,"ALSA: Sample rate proposed %d\n",sampling_rate);
#endif
int rc, dir = 0;
snd_pcm_uframes_t frames = 32;
// rc = snd_pcm_open(&alsa_handle, g_card, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
rc = snd_pcm_open(&alsa_handle, g_card, SND_PCM_STREAM_PLAYBACK, 0);
if (rc < 0) {
syslog(LOG_ERR, "unable to open pcm device: %s\n", snd_strerror(rc));
die("alsa initialization failed");
}
snd_pcm_hw_params_alloca(&alsa_params);
snd_pcm_hw_params_any(alsa_handle, alsa_params);
snd_pcm_hw_params_set_access(alsa_handle, alsa_params, SND_PCM_ACCESS_RW_INTERLEAVED);
snd_pcm_hw_params_set_format(alsa_handle, alsa_params, SND_PCM_FORMAT_S16);
snd_pcm_hw_params_set_channels(alsa_handle, alsa_params, NUM_CHANNELS);
snd_pcm_hw_params_set_rate_near(alsa_handle, alsa_params, (unsigned int *)&sampling_rate, &dir);
#ifdef DEBUGALSA
syslog(LOG_DEBUG,"ALSA: Sample rate gotten %d\n",sampling_rate);
#endif
snd_pcm_hw_params_set_period_size_near(alsa_handle, alsa_params, &frames, &dir);
rc = snd_pcm_hw_params(alsa_handle, alsa_params);
if (rc < 0) {
syslog(LOG_ERR, "unable to set hw parameters: %s\n", snd_strerror(rc));
die("alsa initialization failed");
}
return alsa_handle;
}
void audio_deinit(void)
{
syslog(LOG_INFO,"ALSA: Deinitiating PCM handles\n");
if (alsa_handle) {
snd_pcm_drain(alsa_handle);
snd_pcm_close(alsa_handle);
}
}
void print_audio_args()
{
printf(" --alsa_pcm=<ALSA PCM Device> Sets ALSA PCM device (Can be found by aplay -L)\n");
}