Beispiel #1
0
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);
}
Beispiel #2
0
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;
}
Beispiel #3
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;
        }
    }
}
Beispiel #4
0
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;
}
Beispiel #5
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;
}