1 /*
2 * Copyright (c) 2011 Jonathan Baldwin
3 *
4 * This file is part of FFmpeg.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
11 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
13 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
15 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 /**
20 * @file
21 * OpenAL 1.1 capture device for libavdevice
22 **/
23
24 #include <AL/al.h>
25 #include <AL/alc.h>
26
32
35 /** OpenAL capture device context. **/
37 /** The number of channels in the captured audio. **/
39 /** The sample rate (in Hz) of the captured audio. **/
41 /** The sample size (in bits) of the captured audio. **/
43 /** The OpenAL sample format of the captured audio. **/
45 /** The number of bytes between two consecutive samples of the same channel/component. **/
47 /** If true, print a list of capture devices on this system and exit. **/
50
56
57 #define LOWEST_AL_FORMAT FFMIN(FFMIN(AL_FORMAT_MONO8,AL_FORMAT_MONO16),FFMIN(AL_FORMAT_STEREO8,AL_FORMAT_STEREO16))
58
59 /**
60 * Get information about an AL_FORMAT value.
61 * @param al_fmt the AL_FORMAT value to find information about.
62 * @return A pointer to a structure containing information about the AL_FORMAT value.
63 */
65 {
71 };
72
74 }
75
76 /**
77 * Get the OpenAL error code, translated into an av/errno error code.
78 * @param device The ALC device to check for errors.
79 * @param error_msg_ret A pointer to a char* in which to return the error message, or NULL if desired.
80 * @return The error code, or 0 if there is no error.
81 */
82 static inline int al_get_error(ALCdevice *device,
const char** error_msg_ret)
83 {
84 ALCenum
error = alcGetError(device);
85 if (error_msg_ret)
86 *error_msg_ret = (
const char*) alcGetString(device,
error);
88 case ALC_NO_ERROR:
89 return 0;
90 case ALC_INVALID_DEVICE:
92 break;
93 case ALC_INVALID_CONTEXT:
94 case ALC_INVALID_ENUM:
95 case ALC_INVALID_VALUE:
97 break;
98 case ALC_OUT_OF_MEMORY:
100 break;
101 default:
103 }
104 }
105
106 /**
107 * Print out a list of OpenAL capture devices on this system.
108 */
110 {
111 const char *devices;
112
113 if (!(devices = alcGetString(
NULL, ALC_CAPTURE_DEVICE_SPECIFIER)))
114 return;
115
116 av_log(log_ctx,
AV_LOG_INFO,
"List of OpenAL capture devices on this system:\n");
117
118 for (; *devices != '0円'; devices += strlen(devices) + 1)
120 }
121
123 {
125 static const ALCenum sample_formats[2][2] = {
126 { AL_FORMAT_MONO8, AL_FORMAT_STEREO8 },
127 { AL_FORMAT_MONO16, AL_FORMAT_STEREO16 }
128 };
130 const char *error_msg;
133
137 }
138
140
141 /* Open device for capture */
146 ad->
sample_rate);
/* Maximum 1 second of sample data to be read at once */
147
149
150 /* Create stream */
154 }
155
156 /* We work in microseconds */
158
159 /* Set codec parameters */
165
166 /* This is needed to read the audio data */
169
170 /* Finally, start the capture process */
171 alcCaptureStart(ad->
device);
172
173 return 0;
174
176 /* Handle failure */
178 alcCaptureCloseDevice(ad->
device);
179 if (error_msg)
182 }
183
185 {
188 const char *error_msg;
189 ALCint nb_samples;
190
191 for (;;) {
192 /* Get number of samples available */
193 alcGetIntegerv(ad->
device, ALC_CAPTURE_SAMPLES, (ALCsizei)
sizeof(ALCint), &nb_samples);
195 if (nb_samples > 0)
196 break;
200 }
201
202 /* Create a packet of appropriate size */
206
207 /* Fill the packet with the available samples */
210
213 /* Handle failure */
216 if (error_msg)
219 }
220
222 {
224
226 alcCaptureStop(ad->
device);
227 alcCaptureCloseDevice(ad->
device);
228 }
229 return 0;
230 }
231
232 #define OFFSET(x) offsetof(al_data, x)
233
242 };
243
250 };
251
256 .p.priv_class = &class,
257 .priv_data_size =
sizeof(
al_data),
262 };