summarylogtreecommitdiffstats
path: root/pa_fix_monitor_s32.patch
blob: fb03d139203c38420ed5a426bdbca1b4a49f363d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From 2d1ba361d4a267a9fcd85479311d428cba361be5 Mon Sep 17 00:00:00 2001
From: Norihiro Kamae <norihiro@nagater.net>
Date: Mon, 11 Oct 2021 13:59:56 +0900
Subject: [PATCH 1/2] linux-pulseaudio: Fix 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.
---
 .../pulse/pulseaudio-output.c                 | 37 +++++++++++++------
 1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/libobs/audio-monitoring/pulse/pulseaudio-output.c b/libobs/audio-monitoring/pulse/pulseaudio-output.c
index 9abfcd78b4e..788b579a4d6 100644
--- a/libobs/audio-monitoring/pulse/pulseaudio-output.c
+++ b/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);
 

From 933c251604d71946b92941cf96c4965c3ac5853b Mon Sep 17 00:00:00 2001
From: Norihiro Kamae <norihiro@nagater.net>
Date: Tue, 12 Oct 2021 09:37:09 +0900
Subject: [PATCH 2/2] linux-pulseaudio: Fix monitoring volume for u8 format

Change `char` to `uint8_t` in `process_byte` because the type is
expected unsigned 8-bit.
---
 libobs/audio-monitoring/pulse/pulseaudio-output.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/libobs/audio-monitoring/pulse/pulseaudio-output.c b/libobs/audio-monitoring/pulse/pulseaudio-output.c
index 788b579a4d6..4346c22d435 100644
--- a/libobs/audio-monitoring/pulse/pulseaudio-output.c
+++ b/libobs/audio-monitoring/pulse/pulseaudio-output.c
@@ -126,11 +126,11 @@ static pa_channel_map pulseaudio_channel_map(enum speaker_layout layout)
 
 static void process_byte(void *p, size_t frames, size_t channels, float vol)
 {
-	register char *cur = (char *)p;
-	register char *end = cur + frames * channels;
+	register uint8_t *cur = (uint8_t *)p;
+	register uint8_t *end = cur + frames * channels;
 
-	while (cur < end)
-		*(cur++) *= vol;
+	for (; cur < end; cur++)
+		*cur = ((int)*cur - 128) * vol + 128;
 }
 
 static void process_s16(void *p, size_t frames, size_t channels, float vol)