X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=audio_mixer.cpp;h=b61a3c300009eda219179863617914325517ba1e;hb=95c6bc9d8e340b02112f713389390102d547cc4c;hp=a9b2d4c0f87a4b4ced15c1bc58d4387e8136893e;hpb=19a44f0f0dacb3cd96bacf83bb55ceda7590fda9;p=nageru diff --git a/audio_mixer.cpp b/audio_mixer.cpp index a9b2d4c..b61a3c3 100644 --- a/audio_mixer.cpp +++ b/audio_mixer.cpp @@ -19,6 +19,24 @@ namespace { // TODO: If these prove to be a bottleneck, they can be SSSE3-optimized // (usually including multiple channels at a time). +void convert_fixed16_to_fp32(float *dst, size_t out_channel, size_t out_num_channels, + const uint8_t *src, size_t in_channel, size_t in_num_channels, + size_t num_samples) +{ + assert(in_channel < in_num_channels); + assert(out_channel < out_num_channels); + src += in_channel * 2; + dst += out_channel; + + for (size_t i = 0; i < num_samples; ++i) { + int16_t s = le16toh(*(int16_t *)src); + *dst = s * (1.0f / 32768.0f); + + src += 2 * in_num_channels; + dst += out_num_channels; + } +} + void convert_fixed24_to_fp32(float *dst, size_t out_channel, size_t out_num_channels, const uint8_t *src, size_t in_channel, size_t in_num_channels, size_t num_samples) @@ -102,7 +120,7 @@ void AudioMixer::reset_device_mutex_held(DeviceSpec device_spec) } else { // TODO: ResamplingQueue should probably take the full device spec. // (It's only used for console output, though.) - device->resampling_queue.reset(new ResamplingQueue(device_spec.index, OUTPUT_FREQUENCY, OUTPUT_FREQUENCY, device->interesting_channels.size())); + device->resampling_queue.reset(new ResamplingQueue(device_spec.index, device->capture_frequency, OUTPUT_FREQUENCY, device->interesting_channels.size())); } device->next_local_pts = 0; } @@ -120,7 +138,7 @@ void AudioMixer::add_audio(DeviceSpec device_spec, const uint8_t *data, unsigned unsigned num_channels = device->interesting_channels.size(); assert(num_channels > 0); - // Convert the audio to stereo fp32. + // Convert the audio to fp32. vector audio; audio.resize(num_samples * num_channels); unsigned channel_index = 0; @@ -129,6 +147,9 @@ void AudioMixer::add_audio(DeviceSpec device_spec, const uint8_t *data, unsigned case 0: assert(num_samples == 0); break; + case 16: + convert_fixed16_to_fp32(&audio[0], channel_index, num_channels, data, *channel_it, audio_format.num_channels, num_samples); + break; case 24: convert_fixed24_to_fp32(&audio[0], channel_index, num_channels, data, *channel_it, audio_format.num_channels, num_samples); break; @@ -231,6 +252,9 @@ vector AudioMixer::get_output(double pts, unsigned num_samples, Resamplin lock_guard lock(audio_mutex); // Pick out all the interesting channels from all the cards. + // TODO: If the card has been hotswapped, the number of channels + // might have changed; if so, we need to do some sort of remapping + // to silence. for (unsigned card_index = 0; card_index < num_cards; ++card_index) { AudioDevice *device = &cards[card_index]; if (!device->interesting_channels.empty()) { @@ -375,15 +399,19 @@ vector AudioMixer::get_output(double pts, unsigned num_samples, Resamplin return samples_out; } -vector AudioMixer::get_names() const +map AudioMixer::get_devices() const { lock_guard lock(audio_mutex); - vector names; + map devices; for (unsigned card_index = 0; card_index < num_cards; ++card_index) { + const DeviceSpec spec{ InputSourceType::CAPTURE_CARD, card_index }; const AudioDevice *device = &cards[card_index]; - names.push_back(device->name); + DeviceInfo info; + info.name = device->name; + info.num_channels = 8; // FIXME: This is wrong for fake cards. + devices.insert(make_pair(spec, info)); } - return names; + return devices; } void AudioMixer::set_name(DeviceSpec device_spec, const string &name) @@ -398,13 +426,12 @@ void AudioMixer::set_input_mapping(const InputMapping &new_input_mapping) { lock_guard lock(audio_mutex); - // FIXME: This needs to be keyed on DeviceSpec. - map> interesting_channels; + map> interesting_channels; for (const InputMapping::Bus &bus : new_input_mapping.buses) { if (bus.device.type == InputSourceType::CAPTURE_CARD) { for (unsigned channel = 0; channel < 2; ++channel) { if (bus.source_channel[channel] != -1) { - interesting_channels[bus.device.index].insert(bus.source_channel[channel]); + interesting_channels[bus.device].insert(bus.source_channel[channel]); } } } @@ -412,9 +439,10 @@ void AudioMixer::set_input_mapping(const InputMapping &new_input_mapping) // Reset resamplers for all cards that don't have the exact same state as before. for (unsigned card_index = 0; card_index < num_cards; ++card_index) { + DeviceSpec device_spec{InputSourceType::CAPTURE_CARD, card_index}; AudioDevice *device = &cards[card_index]; - if (device->interesting_channels != interesting_channels[card_index]) { - device->interesting_channels = interesting_channels[card_index]; + if (device->interesting_channels != interesting_channels[device_spec]) { + device->interesting_channels = interesting_channels[device_spec]; reset_device_mutex_held(DeviceSpec{InputSourceType::CAPTURE_CARD, card_index}); } }