Repository navigation
Expand file tree
/
Copy pathalsa.c
More file actions
139 lines (113 loc) · 3.52 KB
/
Copy pathalsa.c
File metadata and controls
139 lines (113 loc) · 3.52 KB
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
* Copyright (C) 2013 Daniel Carrera <dcarrera@miten.es>
*
* This file is part of rtstream.
*
* rtstream is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* rtstream is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with rtstream. If not, see <http://www.gnu.org/licenses/>.
*/
#include "alsa.h"
/* Global ALSA PCM */
snd_pcm_t *pcmc;
snd_pcm_t *pcmp;
int audio_format_to_alsa_format(int format) {
int aformat;
if(format == FORMAT_S16_LE) {
aformat = SND_PCM_FORMAT_S16_LE;
}
else {
aformat = SND_PCM_FORMAT_S16_LE;
}
return aformat;
}
/* Simple functions to handle soundcard.
* now is only for ALSA */
void audio_alsa_capture_open(struct audio *au) {
int err;
err = snd_pcm_open(&pcmc, au->device, SND_PCM_STREAM_CAPTURE, 0);
if (err < 0) {
printf("ALSA: Playback open error: %s\n", snd_strerror(err));
return;
}
int format;
format = audio_format_to_alsa_format(au->format);
if(!au->buffer){
au->buffer = 500000;// buf 0.5sec 500000
}
err = snd_pcm_set_params(pcmc, format, SND_PCM_ACCESS_RW_INTERLEAVED,
au->channels, au->sample_rate, 1, au->buffer);
if (err < 0) {
printf("ALSA: Playback open error: %s\n", snd_strerror(err));
return;
}
}
/* Function to read audio from soundcard */
int audio_alsa_capture_read(short *buffer, int size) {
snd_pcm_sframes_t frames;
frames = snd_pcm_readi(pcmc, buffer, size);
if (frames == -EBADFD) {
fprintf (stderr, "ALSA: PCM is not in the right state\n");
}
else if (frames == -EPIPE) {
fprintf (stderr, "ALSA: an underrun occurred\n");
frames = snd_pcm_prepare(pcmc);
}
else if (frames == -ESTRPIPE) {
fprintf (stderr, "ALSA: a suspend event occurred (stream is suspended and waiting for an application recovery)\n");
}
return frames;
}
void audio_alsa_capture_close() {
// wait to empty pcm buffer
snd_pcm_drain (pcmc);
snd_pcm_close (pcmc);
}
/* Simple functions to handle soundcard.
* now is only for ALSA */
void audio_alsa_play_open(struct audio *au) {
int err;
err = snd_pcm_open(&pcmp, au->device, SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
printf("ALSA: Playback open error: %s\n", snd_strerror(err));
return;
}
int format;
format = audio_format_to_alsa_format(au->format);
err = snd_pcm_set_params(pcmp, format, SND_PCM_ACCESS_RW_INTERLEAVED,
au->channels, au->sample_rate, 1, au->buffer);
if (err < 0) {
printf("ALSA: Playback open error: %s\n", snd_strerror(err));
return;
}
}
/* Function to write audio on soundcard */
int audio_alsa_play_write(short *buffer, int size) {
snd_pcm_sframes_t frames;
frames = snd_pcm_writei(pcmp, buffer, size);
if (frames == -EBADFD) {
fprintf (stderr, "ALSA: PCM is not in the right state\n");
}
else if (frames == -EPIPE) {
fprintf (stderr, "ALSA: an underrun occurred\n");
frames = snd_pcm_prepare(pcmp);
}
else if (frames == -ESTRPIPE) {
fprintf (stderr, "ALSA: a suspend event occurred (stream is suspended and waiting for an application recovery)\n");
}
return frames;
}
void audio_alsa_play_close() {
// wait to empty pcm buffer
snd_pcm_drain (pcmp);
snd_pcm_close (pcmp);
}