int soundio_instream_open(struct SoundIoInStream *instream) { SoundIoDevice *device = instream->device; if (device->aim != SoundIoDeviceAimInput) return SoundIoErrorInvalid; if (instream->format <= SoundIoFormatInvalid) return SoundIoErrorInvalid; if (instream->layout.channel_count > SOUNDIO_MAX_CHANNELS) return SoundIoErrorInvalid; if (device->probe_error) return device->probe_error; if (instream->format == SoundIoFormatInvalid) { instream->format = soundio_device_supports_format(device, SoundIoFormatFloat32NE) ? SoundIoFormatFloat32NE : device->formats[0]; } if (!instream->layout.channel_count) { const SoundIoChannelLayout *stereo = soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdStereo); instream->layout = soundio_device_supports_layout(device, stereo) ? *stereo : device->layouts[0]; } if (!instream->sample_rate) instream->sample_rate = soundio_device_nearest_sample_rate(device, 48000); instream->bytes_per_frame = soundio_get_bytes_per_frame(instream->format, instream->layout.channel_count); instream->bytes_per_sample = soundio_get_bytes_per_sample(instream->format); SoundIo *soundio = device->soundio; SoundIoPrivate *si = (SoundIoPrivate *)soundio; SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)instream; return si->instream_open(si, is); }
static int set_all_device_channel_layouts(struct SoundIoDevice *device) { device->layout_count = soundio_channel_layout_builtin_count(); device->layouts = ALLOCATE(struct SoundIoChannelLayout, device->layout_count); if (!device->layouts) return SoundIoErrorNoMem; for (int i = 0; i < device->layout_count; i += 1) device->layouts[i] = *soundio_channel_layout_get_builtin(i); return 0; }
static void set_from_pulseaudio_channel_map(pa_channel_map channel_map, struct SoundIoChannelLayout *channel_layout) { channel_layout->channel_count = channel_map.channels; for (int i = 0; i < channel_map.channels; i += 1) { channel_layout->channels[i] = from_pulseaudio_channel_pos(channel_map.map[i]); } channel_layout->name = NULL; int builtin_layout_count = soundio_channel_layout_builtin_count(); for (int i = 0; i < builtin_layout_count; i += 1) { const struct SoundIoChannelLayout *builtin_layout = soundio_channel_layout_get_builtin(i); if (soundio_channel_layout_equal(builtin_layout, channel_layout)) { channel_layout->name = builtin_layout->name; break; } } }
int create_resample_descriptor(GenesisPipeline *pipeline) { GenesisNodeDescriptor *node_descr = genesis_create_node_descriptor(pipeline, 2, "resample", "Resample audio and remap channel layouts."); if (!node_descr) { genesis_node_descriptor_destroy(node_descr); return GenesisErrorNoMem; } genesis_node_descriptor_set_run_callback(node_descr, resample_run); genesis_node_descriptor_set_create_callback(node_descr, resample_create); genesis_node_descriptor_set_destroy_callback(node_descr, resample_destroy); genesis_node_descriptor_set_seek_callback(node_descr, resample_seek); struct GenesisPortDescriptor *audio_in_port = genesis_node_descriptor_create_port( node_descr, 0, GenesisPortTypeAudioIn, "audio_in"); struct GenesisPortDescriptor *audio_out_port = genesis_node_descriptor_create_port( node_descr, 1, GenesisPortTypeAudioOut, "audio_out"); if (!audio_in_port || !audio_out_port) { genesis_node_descriptor_destroy(node_descr); return GenesisErrorNoMem; } genesis_port_descriptor_set_connect_callback(audio_in_port, in_connect); genesis_port_descriptor_set_connect_callback(audio_out_port, out_connect); genesis_port_descriptor_set_disconnect_callback(audio_in_port, in_disconnect); genesis_port_descriptor_set_disconnect_callback(audio_out_port, out_disconnect); int default_sample_rate = genesis_pipeline_get_sample_rate(pipeline); const struct SoundIoChannelLayout *mono_layout = soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdMono); genesis_audio_port_descriptor_set_channel_layout(audio_in_port, mono_layout, false, -1); genesis_audio_port_descriptor_set_sample_rate(audio_in_port, default_sample_rate, false, -1); genesis_audio_port_descriptor_set_channel_layout(audio_out_port, mono_layout, false, -1); genesis_audio_port_descriptor_set_sample_rate(audio_out_port, default_sample_rate, false, -1); return 0; }
struct GrooveFingerprinter *groove_fingerprinter_create(struct Groove *groove) { struct GrooveFingerprinterPrivate *p = allocate<GrooveFingerprinterPrivate>(1); if (!p) { av_log(NULL, AV_LOG_ERROR, "unable to allocate fingerprinter\n"); return NULL; } p->abort_request.store(false); p->groove = groove; struct GrooveFingerprinter *printer = &p->externals; if (pthread_mutex_init(&p->info_head_mutex, NULL) != 0) { groove_fingerprinter_destroy(printer); av_log(NULL, AV_LOG_ERROR, "unable to create mutex\n"); return NULL; } p->info_head_mutex_inited = 1; if (pthread_cond_init(&p->drain_cond, NULL) != 0) { groove_fingerprinter_destroy(printer); av_log(NULL, AV_LOG_ERROR, "unable to create mutex condition\n"); return NULL; } p->drain_cond_inited = 1; p->info_queue = groove_queue_create(); if (!p->info_queue) { groove_fingerprinter_destroy(printer); av_log(NULL, AV_LOG_ERROR, "unable to allocate queue\n"); return NULL; } p->info_queue->context = printer; p->info_queue->cleanup = info_queue_cleanup; p->info_queue->put = info_queue_put; p->info_queue->get = info_queue_get; p->info_queue->purge = info_queue_purge; p->sink = groove_sink_create(groove); if (!p->sink) { groove_fingerprinter_destroy(printer); av_log(NULL, AV_LOG_ERROR, "unable to allocate sink\n"); return NULL; } GrooveAudioFormat audio_format; audio_format.sample_rate = 44100; audio_format.layout = *soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdStereo); audio_format.format = SoundIoFormatS16NE; audio_format.is_planar = false; groove_sink_set_only_format(p->sink, &audio_format); p->sink->userdata = printer; p->sink->purge = sink_purge; p->sink->flush = sink_flush; // set some defaults printer->info_queue_size = INT_MAX; printer->sink_buffer_size_bytes = p->sink->buffer_size_bytes; return printer; }