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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
|
From ff5414990645653bf43bf64adfc1ca77ffb9edcb Mon Sep 17 00:00:00 2001
From: malc <av1474@comtv.ru>
Date: Sun, 17 Jan 2010 00:25:29 +0300
Subject: [PATCH] Revert "sdlaudio: make it suck less"
This reverts commit 4839abe78fd466a3cf06faa7c362154afd5404f1.
The commit was badly broken, Gentoo has sdl as the default driver,
consequently 5 gentoo users have hit the breakage and were kind enough
to report, so thank you:
Claes Gyllenswrd
vekin
Chris
But above all thanks to Toralf Foerster who actually provied enough
information to pinpoint the breakage to sdlaudio.
http://bugs.gentoo.org/show_bug.cgi?id=294269
---
audio/sdlaudio.c | 80 +++++++++++++++++++++++++++++++++--------------------
1 files changed, 50 insertions(+), 30 deletions(-)
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index aa39c33..8e7e5cb 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -41,8 +41,8 @@
typedef struct SDLVoiceOut {
HWVoiceOut hw;
int live;
+ int rpos;
int decr;
- int pending;
} SDLVoiceOut;
static struct {
@@ -225,10 +225,6 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
HWVoiceOut *hw = &sdl->hw;
int samples = len >> hw->info.shift;
- if (sdl_lock (s, "sdl_callback")) {
- return;
- }
-
if (s->exit) {
return;
}
@@ -236,34 +232,49 @@ static void sdl_callback (void *opaque, Uint8 *buf, int len)
while (samples) {
int to_mix, decr;
- while (!sdl->pending) {
- if (sdl_unlock (s, "sdl_callback")) {
- return;
- }
-
- sdl_wait (s, "sdl_callback");
- if (s->exit) {
- return;
- }
-
- if (sdl_lock (s, "sdl_callback")) {
- return;
- }
- sdl->pending += sdl->live;
- sdl->live = 0;
+ /* dolog ("in callback samples=%d\n", samples); */
+ sdl_wait (s, "sdl_callback");
+ if (s->exit) {
+ return;
+ }
+
+ if (sdl_lock (s, "sdl_callback")) {
+ return;
+ }
+
+ if (audio_bug (AUDIO_FUNC, sdl->live < 0 || sdl->live > hw->samples)) {
+ dolog ("sdl->live=%d hw->samples=%d\n",
+ sdl->live, hw->samples);
+ return;
+ }
+
+ if (!sdl->live) {
+ goto again;
}
- to_mix = audio_MIN (samples, sdl->pending);
- decr = audio_pcm_hw_clip_out (hw, buf, to_mix, 0);
- buf += decr << hw->info.shift;
+ /* dolog ("in callback live=%d\n", live); */
+ to_mix = audio_MIN (samples, sdl->live);
+ decr = to_mix;
+ while (to_mix) {
+ int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
+ struct st_sample *src = hw->mix_buf + hw->rpos;
+
+ /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
+ hw->clip (buf, src, chunk);
+ sdl->rpos = (sdl->rpos + chunk) % hw->samples;
+ to_mix -= chunk;
+ buf += chunk << hw->info.shift;
+ }
samples -= decr;
+ sdl->live -= decr;
sdl->decr += decr;
- sdl->pending -= decr;
- }
- if (sdl_unlock (s, "sdl_callback")) {
- return;
+ again:
+ if (sdl_unlock (s, "sdl_callback")) {
+ return;
+ }
}
+ /* dolog ("done len=%d\n", len); */
}
static int sdl_write_out (SWVoiceOut *sw, void *buf, int len)
@@ -281,9 +292,18 @@ static int sdl_run_out (HWVoiceOut *hw, int live)
return 0;
}
- sdl->live = live;
- decr = sdl->decr;
- sdl->decr = 0;
+ if (sdl->decr > live) {
+ ldebug ("sdl->decr %d live %d sdl->live %d\n",
+ sdl->decr,
+ live,
+ sdl->live);
+ }
+
+ decr = audio_MIN (sdl->decr, live);
+ sdl->decr -= decr;
+
+ sdl->live = live - decr;
+ hw->rpos = sdl->rpos;
if (sdl->live > 0) {
sdl_unlock_and_post (s, "sdl_run_out");
--
1.7.0.4
|