72#define MOD_NAME "[Portaudio capture] "
89static int callback(
const void *inputBuffer,
void *outputBuffer,
90 unsigned long framesPerBuffer,
91 const PaStreamCallbackTimeInfo* timeInfo,
92 PaStreamCallbackFlags statusFlags,
97 PaError error = Pa_StartStream(stream);
98 if (error != paNoError) {
120 Pa_StopStream(stream);
121 Pa_CloseStream(stream);
126parse_fmt(
const char *cfg, PaTime *latency,
int *input_device_idx,
127 char device_name[
static STR_LEN])
129 if (isdigit(cfg[0])) {
130 *input_device_idx = atoi(cfg);
131 cfg = strchr(cfg,
':') ? strchr(cfg,
':') + 1 : cfg + strlen(cfg);
135 char *saveptr = NULL;
136 while ((
item = strtok_r(ccfg,
":", &saveptr)) != NULL) {
138 *latency = atof(strchr(
item,
'=') + 1);
140 const char *dev = strchr(
item,
'=') + 1;
141 if (isdigit(dev[0])) {
142 *input_device_idx = atoi(dev);
144 snprintf(device_name,
STR_LEN,
"%s", dev);
156 printf(
"PortAudio capture usage:\n");
160 printf(
"options:\n");
161 color_printf(
"\t" TBOLD(
" <l> ")
"\tsuggested latency in sec (experimental, use in case of problems)\n");
162 color_printf(
"\t" TBOLD(
"<dev>")
"\tdevice name (or a part of it); device index is also accepted here\n");
163 printf(
"\nAvailable PortAudio capture devices:\n");
173 if (strcmp(cfg,
"help") == 0) {
178 int input_device_idx = -1;
179 char input_device_name[
STR_LEN] =
"";
182 PaTime latency = -1.0;
184 if (!
parse_fmt(cfg, &latency, &input_device_idx, input_device_name)) {
192 pthread_mutex_init(&s->
lock, NULL);
193 pthread_cond_init(&s->
cv, NULL);
195 error = Pa_Initialize();
196 if (error != paNoError) {
205 PaStreamParameters inputParameters;
208 if (strlen(input_device_name) > 0) {
211 if (input_device_idx == -1) {
214 inputParameters.device = Pa_GetDefaultInputDevice();
215 device_info = Pa_GetDeviceInfo(Pa_GetDefaultInputDevice());
216 }
else if (input_device_idx >= 0) {
219 inputParameters.device = input_device_idx;
225 MOD_NAME "Follows list of available Portaudio devices.\n", input_device_idx);
241 inputParameters.sampleFormat = paInt32;
248 inputParameters.sampleFormat = paInt16;
251 inputParameters.suggestedLatency = latency == -1.0 ? Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency : latency;
252 inputParameters.hostApiSpecificStreamInfo = NULL;
258 paFramesPerBufferUnspecified,
263 if (error != paNoError) {
282static int callback(
const void *inputBuffer,
void *outputBuffer,
283 unsigned long framesPerBuffer,
284 const PaStreamCallbackTimeInfo* timeInfo,
285 PaStreamCallbackFlags statusFlags,
294 pthread_mutex_lock(&s->
lock);
297 pthread_cond_signal(&s->
cv);
298 pthread_mutex_unlock(&s->
lock);
312 pthread_mutex_lock(&s->
lock);
314 pthread_cond_wait(&s->
cv, &s->
lock);
316 pthread_mutex_unlock(&s->
lock);
328 pthread_mutex_destroy(&s->
lock);
329 pthread_cond_destroy(&s->
cv);
int void(** deleter)(void *))
This file contains definition of some common audio types.
#define AUDIO_CAPTURE_ABI_VERSION
static void portaudio_close(PaStream *stream)
static const struct audio_capture_info acap_portaudio_info
static _Bool parse_fmt(const char *cfg, PaTime *latency, int *input_device_idx, char device_name[static STR_LEN])
static void * audio_cap_portaudio_init(struct module *parent, const char *cfg)
static void audio_cap_portaudio_done(void *state)
static void audio_cap_portaudio_help()
static void audio_cap_portaudio_probe(struct device_info **available_devices, int *count, void(**deleter)(void *))
static struct audio_frame * audio_cap_portaudio_read(void *state)
static int portaudio_start_stream(PaStream *stream)
int color_printf(const char *format,...)
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_NOTICE
information that may be interesting
#define LOG_LEVEL_INFO
normal reporting
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_WARNING
less severe errors
unsigned int audio_capture_bps
unsigned int audio_capture_sample_rate
unsigned int audio_capture_channels
#define DEFAULT_AUDIO_CAPTURE_CHANNELS
@ LIBRARY_CLASS_AUDIO_CAPTURE
#define REGISTER_MODULE(name, info, lclass, abi)
Registers module to global modules' registry.
#define IS_KEY_PREFIX(tok, key)
expands to true value if <k> from tok in format <k>=<v> is prefix of key
@ STR_LEN
"standard" string length placeholder
int portaudio_select_device_by_name(const char *name)
void portaudio_print_version()
void audio_portaudio_probe(struct device_info **available_devices, int *count, enum portaudio_device_direction dir)
const char * portaudio_get_device_name(PaDeviceIndex device)
void portaudio_print_help(enum portaudio_device_direction kind)
void ring_buffer_destroy(struct ring_buffer *ring)
struct ring_buffer * ring_buffer_init(int size)
int ring_buffer_read(struct ring_buffer *ring, char *out, int max_len)
void ring_buffer_write(struct ring_buffer *ring, const char *in, int len)
Option::Callback::fcn_type callback
struct used to comunicate with audio capture/playback device
struct ring_buffer * buffer