}
}
+void convert_fixed16_to_fixed32(int32_t *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) {
+ uint32_t s = uint32_t(uint16_t(le16toh(*(int16_t *)src))) << 16;
+
+ // Keep the sign bit in place, repeat the other 15 bits as far as they go.
+ *dst = s | ((s & 0x7fffffff) >> 15) | ((s & 0x7fffffff) >> 30);
+
+ 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)
uint32_t s1 = src[0];
uint32_t s2 = src[1];
uint32_t s3 = src[2];
- uint32_t s = s1 | (s1 << 8) | (s2 << 16) | (s3 << 24);
- *dst = int(s) * (1.0f / 2147483648.0f);
+ uint32_t s = (s1 << 8) | (s2 << 16) | (s3 << 24); // Note: The bottom eight bits are zero; s3 includes the sign bit.
+ *dst = int(s) * (1.0f / (256.0f * 8388608.0f)); // 256 for signed down-shift by 8, then 2^23 for the actual conversion.
+
+ src += 3 * in_num_channels;
+ dst += out_num_channels;
+ }
+}
+
+void convert_fixed24_to_fixed32(int32_t *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 * 3;
+ dst += out_channel;
+
+ for (size_t i = 0; i < num_samples; ++i) {
+ uint32_t s1 = src[0];
+ uint32_t s2 = src[1];
+ uint32_t s3 = src[2];
+ uint32_t s = (s1 << 8) | (s2 << 16) | (s3 << 24);
+
+ // Keep the sign bit in place, repeat the other 23 bits as far as they go.
+ *dst = s | ((s & 0x7fffffff) >> 23);
src += 3 * in_num_channels;
dst += out_num_channels;
}
}
+// Basically just a reinterleave.
+void convert_fixed32_to_fixed32(int32_t *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 * 4;
+ dst += out_channel;
+
+ for (size_t i = 0; i < num_samples; ++i) {
+ int32_t s = le32toh(*(int32_t *)src);
+ *dst = s;
+
+ src += 4 * in_num_channels;
+ dst += out_num_channels;
+ }
+}
+
float find_peak_plain(const float *samples, size_t num_samples) __attribute__((unused));
float find_peak_plain(const float *samples, size_t num_samples)
&new_input_mapping)) {
fprintf(stderr, "Failed to load input mapping from '%s', exiting.\n",
global_flags.input_mapping_filename.c_str());
- exit(1);
+ abort();
}
set_input_mapping(new_input_mapping);
} else {
}
}
-bool AudioMixer::add_audio(DeviceSpec device_spec, const uint8_t *data, unsigned num_samples, AudioFormat audio_format, int64_t frame_length, steady_clock::time_point frame_time)
+bool AudioMixer::add_audio(DeviceSpec device_spec, const uint8_t *data, unsigned num_samples, AudioFormat audio_format, steady_clock::time_point frame_time)
{
AudioDevice *device = find_audio_device(device_spec);
}
unsigned num_channels = device->interesting_channels.size();
- assert(num_channels > 0);
+ if (num_channels == 0) {
+ // No buses use this device; throw it away. (Normally, we should not
+ // be here, but probably, we are in the process of changing a mapping,
+ // and the queue just isn't gone yet. In any case, returning is harmless.)
+ return true;
+ }
// Convert the audio to fp32.
unique_ptr<float[]> audio(new float[num_samples * num_channels]);
return true;
}
-bool AudioMixer::add_silence(DeviceSpec device_spec, unsigned samples_per_frame, unsigned num_frames, int64_t frame_length)
+vector<int32_t> convert_audio_to_fixed32(const uint8_t *data, unsigned num_samples, bmusb::AudioFormat audio_format, unsigned num_channels)
+{
+ vector<int32_t> audio;
+
+ if (num_channels > audio_format.num_channels) {
+ audio.resize(num_samples * num_channels, 0);
+ } else {
+ audio.resize(num_samples * num_channels);
+ }
+ for (unsigned channel_index = 0; channel_index < num_channels && channel_index < audio_format.num_channels; ++channel_index) {
+ switch (audio_format.bits_per_sample) {
+ case 0:
+ assert(num_samples == 0);
+ break;
+ case 16:
+ convert_fixed16_to_fixed32(&audio[0], channel_index, num_channels, data, channel_index, audio_format.num_channels, num_samples);
+ break;
+ case 24:
+ convert_fixed24_to_fixed32(&audio[0], channel_index, num_channels, data, channel_index, audio_format.num_channels, num_samples);
+ break;
+ case 32:
+ convert_fixed32_to_fixed32(&audio[0], channel_index, num_channels, data, channel_index, audio_format.num_channels, num_samples);
+ break;
+ default:
+ fprintf(stderr, "Cannot handle audio with %u bits per sample\n", audio_format.bits_per_sample);
+ assert(false);
+ }
+ }
+
+ return audio;
+}
+
+bool AudioMixer::add_silence(DeviceSpec device_spec, unsigned samples_per_frame, unsigned num_frames)
{
AudioDevice *device = find_audio_device(device_spec);