浏览代码

libobs/audio-monitoring: Fix PulseAudio monitoring volume for s32 format

When signed 32-bit audio arrived to pulseaudio-output and volume was
lowered, audio data was broken. In the function `process_volume`, the
type of the data is switched by `bytes_per_channel`. However the size of
signed 32-bit integer and the size of float are same so that the signed
32-bit integer is processed as float.
This commit changes these items.
- Use `format` instead of `bytes_per_channel` so that all the sample
  types can be differentiated.
- Change `short` to `int16_t` and renames existing function
  `process_short` to `process_s16` to clarify the function is
  processing signed 16-bit.
Norihiro Kamae 4 年之前
父节点
当前提交
0eed7ca98f
共有 1 个文件被更改,包括 25 次插入12 次删除
  1. 25 12
      libobs/audio-monitoring/pulse/pulseaudio-output.c

+ 25 - 12
libobs/audio-monitoring/pulse/pulseaudio-output.c

@@ -22,7 +22,6 @@ struct audio_monitor {
 	audio_resampler_t *resampler;
 	size_t buffer_size;
 	size_t bytesRemaining;
-	size_t bytes_per_channel;
 
 	bool ignore;
 	pthread_mutex_t playback_mutex;
@@ -134,10 +133,19 @@ static void process_byte(void *p, size_t frames, size_t channels, float vol)
 		*(cur++) *= vol;
 }
 
-static void process_short(void *p, size_t frames, size_t channels, float vol)
+static void process_s16(void *p, size_t frames, size_t channels, float vol)
 {
-	register short *cur = (short *)p;
-	register short *end = cur + frames * channels;
+	register int16_t *cur = (int16_t *)p;
+	register int16_t *end = cur + frames * channels;
+
+	while (cur < end)
+		*(cur++) *= vol;
+}
+
+static void process_s32(void *p, size_t frames, size_t channels, float vol)
+{
+	register int32_t *cur = (int32_t *)p;
+	register int32_t *end = cur + frames * channels;
 
 	while (cur < end)
 		*(cur++) *= vol;
@@ -155,19 +163,26 @@ static void process_float(void *p, size_t frames, size_t channels, float vol)
 void process_volume(const struct audio_monitor *monitor, float vol,
 		    uint8_t *const *resample_data, uint32_t resample_frames)
 {
-	switch (monitor->bytes_per_channel) {
-	case 1:
+	switch (monitor->format) {
+	case PA_SAMPLE_U8:
 		process_byte(resample_data[0], resample_frames,
 			     monitor->channels, vol);
 		break;
-	case 2:
-		process_short(resample_data[0], resample_frames,
-			      monitor->channels, vol);
+	case PA_SAMPLE_S16LE:
+		process_s16(resample_data[0], resample_frames,
+			    monitor->channels, vol);
 		break;
-	default:
+	case PA_SAMPLE_S32LE:
+		process_s32(resample_data[0], resample_frames,
+			    monitor->channels, vol);
+		break;
+	case PA_SAMPLE_FLOAT32LE:
 		process_float(resample_data[0], resample_frames,
 			      monitor->channels, vol);
 		break;
+	default:
+		// just ignore
+		break;
 	}
 }
 
@@ -440,8 +455,6 @@ static bool audio_monitor_init(struct audio_monitor *monitor,
 		return false;
 	}
 
-	monitor->bytes_per_channel = get_audio_bytes_per_channel(
-		pulseaudio_to_obs_audio_format(monitor->format));
 	monitor->speakers = pulseaudio_channels_to_obs_speakers(spec.channels);
 	monitor->bytes_per_frame = pa_frame_size(&spec);