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
31
34 /** OpenAL capture device context. **/
36 /** The number of channels in the captured audio. **/
38 /** The sample rate (in Hz) of the captured audio. **/
40 /** The sample size (in bits) of the captured audio. **/
42 /** The OpenAL sample format of the captured audio. **/
44 /** The number of bytes between two consecutive samples of the same channel/component. **/
46 /** If true, print a list of capture devices on this system and exit. **/
49
55
56 #define LOWEST_AL_FORMAT FFMIN(FFMIN(AL_FORMAT_MONO8,AL_FORMAT_MONO16),FFMIN(AL_FORMAT_STEREO8,AL_FORMAT_STEREO16))
57
58 /**
59 * Get information about an AL_FORMAT value.
60 * @param al_fmt the AL_FORMAT value to find information about.
61 * @return A pointer to a structure containing information about the AL_FORMAT value.
62 */
64 {
70 };
71
73 }
74
75 /**
76 * Get the OpenAL error code, translated into an av/errno error code.
77 * @param device The ALC device to check for errors.
78 * @param error_msg_ret A pointer to a char* in which to return the error message, or NULL if desired.
79 * @return The error code, or 0 if there is no error.
80 */
81 static inline int al_get_error(ALCdevice *device,
const char** error_msg_ret)
82 {
83 ALCenum error = alcGetError(device);
84 if (error_msg_ret)
85 *error_msg_ret = (const char*) alcGetString(device, error);
86 switch (error) {
87 case ALC_NO_ERROR:
88 return 0;
89 case ALC_INVALID_DEVICE:
91 break;
92 case ALC_INVALID_CONTEXT:
93 case ALC_INVALID_ENUM:
94 case ALC_INVALID_VALUE:
96 break;
97 case ALC_OUT_OF_MEMORY:
99 break;
100 default:
102 }
103 }
104
105 /**
106 * Print out a list of OpenAL capture devices on this system.
107 */
109 {
110 const char *devices;
111
112 if (!(devices = alcGetString(
NULL, ALC_CAPTURE_DEVICE_SPECIFIER)))
113 return;
114
115 av_log(log_ctx,
AV_LOG_INFO,
"List of OpenAL capture devices on this system:\n");
116
117 for (; *devices != '0円'; devices += strlen(devices) + 1)
119 }
120
122 {
124 static const ALCenum sample_formats[2][2] = {
125 { AL_FORMAT_MONO8, AL_FORMAT_STEREO8 },
126 { AL_FORMAT_MONO16, AL_FORMAT_STEREO16 }
127 };
128 int error = 0;
129 const char *error_msg;
132
136 }
137
139
140 /* Open device for capture */
145 ad->
sample_rate);
/* Maximum 1 second of sample data to be read at once */
146
148
149 /* Create stream */
152 goto fail;
153 }
154
155 /* We work in microseconds */
157
158 /* Set codec parameters */
164
165 /* This is needed to read the audio data */
168
169 /* Finally, start the capture process */
170 alcCaptureStart(ad->
device);
171
172 return 0;
173
174 fail:
175 /* Handle failure */
177 alcCaptureCloseDevice(ad->
device);
178 if (error_msg)
180 return error;
181 }
182
184 {
186 int error=0;
187 const char *error_msg;
188 ALCint nb_samples;
189
190 /* Get number of samples available */
191 alcGetIntegerv(ad->
device, ALC_CAPTURE_SAMPLES, (ALCsizei)
sizeof(ALCint), &nb_samples);
193
194 /* Create a packet of appropriate size */
196 goto fail;
198
199 /* Fill the packet with the available samples */
200 alcCaptureSamples(ad->
device, pkt->
data, nb_samples);
202
204 fail:
205 /* Handle failure */
208 if (error_msg)
210 return error;
211 }
212
214 {
216
218 alcCaptureStop(ad->
device);
219 alcCaptureCloseDevice(ad->
device);
220 }
221 return 0;
222 }
223
224 #define OFFSET(x) offsetof(al_data, x)
225
234 };
235
242 };
243
247 .priv_data_size =
sizeof(
al_data),
253 .priv_class = &class
254 };