Rev 1696 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1696 | Rev 2349 | ||
---|---|---|---|
1 | #include |
1 | #include |
2 | #include |
2 | #include |
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | 5 | ||
6 | #include |
6 | #include |
7 | #include |
7 | #include |
8 | #include "sound.h" |
8 | #include "sound.h" |
9 | #include "fplay.h" |
9 | #include "fplay.h" |
10 | 10 | ||
11 | 11 | ||
12 | astream_t astream; |
12 | astream_t astream; |
13 | 13 | ||
14 | static SNDBUF hBuff; |
14 | static SNDBUF hBuff; |
15 | 15 | ||
16 | extern volatile uint32_t status; |
16 | extern uint8_t *decoder_buffer; |
17 | 17 | ||
18 | void audio_thread(void *param); |
18 | extern volatile uint32_t status; |
19 | - | ||
20 | void spinlock_lock(volatile uint32_t *val) |
- | |
21 | { |
- | |
22 | uint32_t tmp; |
- | |
23 | - | ||
24 | __asm__ __volatile__ ( |
- | |
25 | "0:\n\t" |
- | |
26 | "mov %0, %1\n\t" |
- | |
27 | "testl %1, %1\n\t" |
- | |
28 | "jz 1f\n\t" |
- | |
29 | - | ||
30 | "movl $68, %%eax\n\t" |
- | |
31 | "movl $1, %%ebx\n\t" |
- | |
32 | "int $0x40\n\t" |
- | |
33 | "jmp 0b\n\t" |
- | |
34 | "1:\n\t" |
- | |
35 | "incl %1\n\t" |
- | |
36 | "xchgl %0, %1\n\t" |
- | |
37 | "testl %1, %1\n\t" |
- | |
38 | "jnz 0b\n" |
- | |
39 | : "+m" (*val), "=&r"(tmp) |
19 | |
40 | ::"eax","ebx" ); |
20 | extern volatile uint32_t driver_lock; |
41 | } |
21 | |
42 | 22 | ||
43 | static int snd_format; |
23 | static int snd_format; |
44 | int sample_rate; |
24 | int sample_rate; |
45 | 25 | ||
46 | int init_audio(int format) |
26 | int init_audio(int format) |
47 | { |
27 | { |
48 | int err; |
28 | int err; |
49 | int version =-1; |
29 | int version =-1; |
50 | char *errstr; |
30 | char *errstr; |
51 | 31 | ||
- | 32 | mutex_lock(&driver_lock); |
|
- | 33 | ||
52 | if((err = InitSound(&version)) !=0 ) |
34 | if((err = InitSound(&version)) !=0 ) |
53 | { |
35 | { |
- | 36 | mutex_unlock(&driver_lock); |
|
54 | errstr = "Sound service not installed\n\r"; |
37 | errstr = "Sound service not installed\n\r"; |
55 | goto exit_whith_error; |
38 | goto exit_whith_error; |
56 | } |
39 | }; |
- | 40 | ||
- | 41 | mutex_unlock(&driver_lock); |
|
- | 42 | ||
57 | printf("sound version 0x%x\n", version); |
43 | printf("sound version 0x%x\n", version); |
58 | 44 | ||
59 | if( (SOUND_VERSION>(version&0xFFFF)) || |
45 | if( (SOUND_VERSION>(version&0xFFFF)) || |
60 | (SOUND_VERSION<(version >> 16))) |
46 | (SOUND_VERSION<(version >> 16))) |
61 | { |
47 | { |
62 | errstr = "Sound service version mismatch\n\r"; |
48 | errstr = "Sound service version mismatch\n\r"; |
63 | goto exit_whith_error; |
49 | goto exit_whith_error; |
64 | } |
50 | } |
65 | 51 | ||
66 | snd_format = format; |
52 | snd_format = format; |
67 | 53 | ||
68 | asm volatile ( "xchgw %bx, %bx"); |
- | |
69 | - | ||
70 | create_thread(audio_thread, 0, 163840); |
54 | create_thread(audio_thread, 0, 163840); |
71 | 55 | ||
72 | return 1; |
56 | return 1; |
73 | 57 | ||
74 | exit_whith_error: |
58 | exit_whith_error: |
75 | 59 | ||
76 | printf(errstr); |
60 | printf(errstr); |
77 | return 0; |
61 | return 0; |
78 | }; |
62 | }; |
79 | 63 | ||
80 | static uint64_t samples_lost; |
64 | static uint64_t samples_lost; |
81 | static double audio_delta; |
65 | static double audio_delta; |
82 | 66 | ||
83 | double get_master_clock() |
67 | double get_master_clock() |
84 | { |
68 | { |
85 | double tstamp; |
69 | double tstamp; |
86 | 70 | ||
87 | GetTimeStamp(hBuff, &tstamp); |
71 | GetTimeStamp(hBuff, &tstamp); |
88 | return tstamp - audio_delta; |
72 | return tstamp - audio_delta; |
89 | }; |
73 | }; |
90 | 74 | ||
- | 75 | int decode_audio(AVCodecContext *ctx, queue_t *qa) |
|
- | 76 | { |
|
- | 77 | AVPacket pkt; |
|
- | 78 | AVPacket pkt_tmp; |
|
- | 79 | ||
- | 80 | uint8_t *audio_data; |
|
- | 81 | int audio_size; |
|
- | 82 | int len; |
|
- | 83 | int data_size=0; |
|
- | 84 | ||
- | 85 | if( astream.count > AVCODEC_MAX_AUDIO_FRAME_SIZE*7) |
|
- | 86 | return 1; |
|
- | 87 | ||
- | 88 | if( get_packet(qa, &pkt) == 0 ) |
|
- | 89 | return 0; |
|
- | 90 | ||
- | 91 | // __asm__("int3"); |
|
- | 92 | ||
- | 93 | pkt_tmp = pkt; |
|
- | 94 | ||
- | 95 | while(pkt_tmp.size > 0) |
|
- | 96 | { |
|
- | 97 | data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; |
|
- | 98 | ||
- | 99 | len = avcodec_decode_audio3(ctx,(int16_t*)decoder_buffer, |
|
- | 100 | &data_size, &pkt_tmp); |
|
- | 101 | ||
- | 102 | if(len >= 0) |
|
- | 103 | { |
|
- | 104 | pkt_tmp.data += len; |
|
- | 105 | pkt_tmp.size -= len; |
|
- | 106 | ||
- | 107 | mutex_lock(&astream.lock); |
|
- | 108 | memcpy(astream.buffer+astream.count, decoder_buffer, data_size); |
|
- | 109 | astream.count += data_size; |
|
- | 110 | mutex_unlock(&astream.lock); |
|
- | 111 | } |
|
- | 112 | else pkt_tmp.size = 0; |
|
- | 113 | } |
|
- | 114 | av_free_packet(&pkt); |
|
- | 115 | return 1; |
|
- | 116 | }; |
|
- | 117 | ||
91 | 118 | ||
92 | void audio_thread(void *param) |
119 | int audio_thread(void *param) |
93 | { |
120 | { |
94 | SND_EVENT evnt; |
121 | SND_EVENT evnt; |
95 | int buffsize; |
122 | int buffsize; |
96 | int samples; |
123 | int samples; |
97 | int err; |
124 | int err; |
98 | char *errstr; |
125 | char *errstr; |
99 | 126 | ||
100 | 127 | ||
101 | if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0) |
128 | if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0) |
102 | { |
129 | { |
103 | errstr = "Cannot create sound buffer\n\r"; |
130 | errstr = "Cannot create sound buffer\n\r"; |
104 | goto exit_whith_error; |
131 | goto exit_whith_error; |
105 | }; |
132 | }; |
106 | 133 | ||
107 | SetVolume(hBuff,-1000,-1000); |
134 | SetVolume(hBuff,-1000,-1000); |
108 | 135 | ||
109 | if((err = GetBufferSize(hBuff, &buffsize)) != 0) |
136 | if((err = GetBufferSize(hBuff, &buffsize)) != 0) |
110 | { |
137 | { |
111 | errstr = "Cannot get buffer size\n\r"; |
138 | errstr = "Cannot get buffer size\n\r"; |
112 | goto exit_whith_error; |
139 | goto exit_whith_error; |
113 | }; |
140 | }; |
114 | 141 | ||
115 | buffsize = buffsize/2; |
142 | buffsize = buffsize/2; |
116 | 143 | ||
117 | samples = buffsize/4; |
144 | samples = buffsize/4; |
118 | 145 | ||
119 | while( (astream.count < buffsize*2) && |
146 | while( (astream.count < buffsize*2) && |
120 | (status != 0) ) |
147 | (status != 0) ) |
121 | yield(); |
148 | yield(); |
122 | 149 | ||
123 | spinlock_lock(&astream.lock); |
150 | mutex_lock(&astream.lock); |
124 | { |
151 | { |
125 | SetBuffer(hBuff, astream.buffer, 0, buffsize); |
152 | SetBuffer(hBuff, astream.buffer, 0, buffsize); |
126 | astream.count -= buffsize; |
153 | astream.count -= buffsize; |
127 | if(astream.count) |
154 | if(astream.count) |
128 | memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
155 | memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
129 | spinlock_unlock(&astream.lock); |
156 | mutex_unlock(&astream.lock); |
130 | }; |
157 | }; |
131 | 158 | ||
132 | if((err = PlayBuffer(hBuff, 0)) !=0 ) |
159 | if((err = PlayBuffer(hBuff, 0)) !=0 ) |
133 | { |
160 | { |
134 | errstr = "Cannot play buffer\n\r"; |
161 | errstr = "Cannot play buffer\n\r"; |
135 | goto exit_whith_error; |
162 | goto exit_whith_error; |
136 | }; |
163 | }; |
137 | 164 | ||
138 | 165 | ||
139 | #ifdef BLACK_MAGIC_SOUND |
166 | #ifdef BLACK_MAGIC_SOUND |
140 | 167 | ||
141 | while( status != 0) |
168 | while( status != 0) |
142 | { |
169 | { |
143 | uint32_t offset; |
170 | uint32_t offset; |
144 | 171 | ||
145 | GetNotify(&evnt); |
172 | GetNotify(&evnt); |
146 | 173 | ||
147 | if(evnt.code != 0xFF000001) |
174 | if(evnt.code != 0xFF000001) |
148 | { |
175 | { |
149 | printf("invalid event code %d\n\r", evnt.code); |
176 | printf("invalid event code %d\n\r", evnt.code); |
150 | continue; |
177 | continue; |
151 | } |
178 | } |
152 | 179 | ||
153 | if(evnt.stream != hBuff) |
180 | if(evnt.stream != hBuff) |
154 | { |
181 | { |
155 | printf("invalid stream %x hBuff= %x\n\r", |
182 | printf("invalid stream %x hBuff= %x\n\r", |
156 | evnt.stream, hBuff); |
183 | evnt.stream, hBuff); |
157 | continue; |
184 | continue; |
158 | } |
185 | } |
159 | 186 | ||
160 | GetTimeStamp(hBuff, &audio_delta); |
187 | GetTimeStamp(hBuff, &audio_delta); |
161 | samples_lost = audio_delta*sample_rate/1000; |
188 | samples_lost = audio_delta*sample_rate/1000; |
162 | 189 | ||
163 | offset = evnt.offset; |
190 | offset = evnt.offset; |
164 | 191 | ||
165 | spinlock_lock(&astream.lock); |
192 | mutex_lock(&astream.lock); |
166 | { |
193 | { |
167 | SetBuffer(hBuff, astream.buffer, offset, buffsize); |
194 | SetBuffer(hBuff, astream.buffer, offset, buffsize); |
168 | astream.count -= buffsize; |
195 | astream.count -= buffsize; |
169 | if(astream.count) |
196 | if(astream.count) |
170 | memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
197 | memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
171 | spinlock_unlock(&astream.lock); |
198 | mutex_unlock(&astream.lock); |
172 | }; |
199 | }; |
173 | break; |
200 | break; |
174 | }; |
201 | }; |
175 | #endif |
202 | #endif |
176 | 203 | ||
177 | printf("initial audio delta %f\n", audio_delta); |
204 | printf("initial audio delta %f\n", audio_delta); |
178 | 205 | ||
179 | while( status != 0) |
206 | while( status != 0) |
180 | { |
207 | { |
181 | uint32_t offset; |
208 | uint32_t offset; |
182 | double event_stamp, wait_stamp; |
209 | double event_stamp, wait_stamp; |
183 | int too_late = 0; |
210 | int too_late = 0; |
184 | 211 | ||
185 | GetNotify(&evnt); |
212 | GetNotify(&evnt); |
186 | 213 | ||
187 | if(evnt.code != 0xFF000001) |
214 | if(evnt.code != 0xFF000001) |
188 | { |
215 | { |
189 | printf("invalid event code %d\n\r", evnt.code); |
216 | printf("invalid event code %d\n\r", evnt.code); |
190 | continue; |
217 | continue; |
191 | } |
218 | } |
192 | 219 | ||
193 | if(evnt.stream != hBuff) |
220 | if(evnt.stream != hBuff) |
194 | { |
221 | { |
195 | printf("invalid stream %x hBuff= %x\n\r", |
222 | printf("invalid stream %x hBuff= %x\n\r", |
196 | evnt.stream, hBuff); |
223 | evnt.stream, hBuff); |
197 | continue; |
224 | continue; |
198 | }; |
225 | }; |
199 | 226 | ||
200 | GetTimeStamp(hBuff, &event_stamp); |
227 | GetTimeStamp(hBuff, &event_stamp); |
201 | 228 | ||
202 | offset = evnt.offset; |
229 | offset = evnt.offset; |
203 | 230 | ||
204 | while( (astream.count < buffsize) && |
231 | while( (astream.count < buffsize) && |
205 | (status != 0) ) |
232 | (status != 0) ) |
206 | { |
233 | { |
207 | yield(); |
234 | yield(); |
208 | GetTimeStamp(hBuff, &wait_stamp); |
235 | GetTimeStamp(hBuff, &wait_stamp); |
209 | if( (wait_stamp - event_stamp) > |
236 | if( (wait_stamp - event_stamp) > |
210 | samples*1500/sample_rate ) |
237 | samples*1500/sample_rate ) |
211 | { |
238 | { |
212 | samples_lost+= samples; |
239 | samples_lost+= samples; |
213 | audio_delta = (double)samples_lost*1000/sample_rate; |
240 | audio_delta = (double)samples_lost*1000/sample_rate; |
214 | // printf("audio delta %f\n", audio_delta); |
241 | // printf("audio delta %f\n", audio_delta); |
215 | too_late = 1; |
242 | too_late = 1; |
216 | break; |
243 | break; |
217 | } |
244 | } |
218 | }; |
245 | }; |
219 | 246 | ||
220 | if((too_late == 1) || (status == 0)) |
247 | if((too_late == 1) || (status == 0)) |
221 | continue; |
248 | continue; |
222 | 249 | ||
223 | spinlock_lock(&astream.lock); |
250 | mutex_lock(&astream.lock); |
224 | SetBuffer(hBuff, astream.buffer, offset, buffsize); |
251 | SetBuffer(hBuff, astream.buffer, offset, buffsize); |
225 | astream.count -= buffsize; |
252 | astream.count -= buffsize; |
226 | if(astream.count) |
253 | if(astream.count) |
227 | memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
254 | memcpy(astream.buffer, astream.buffer+buffsize, astream.count); |
228 | spinlock_unlock(&astream.lock); |
255 | mutex_unlock(&astream.lock); |
229 | } |
256 | } |
230 | 257 | ||
- | 258 | StopBuffer(hBuff); |
|
- | 259 | DestroyBuffer(hBuff); |
|
- | 260 | ||
231 | return; |
261 | return 0; |
232 | 262 | ||
233 | exit_whith_error: |
263 | exit_whith_error: |
234 | 264 | ||
235 | printf(errstr); |
265 | printf(errstr); |
236 | return ; |
266 | return -1; |
237 | 267 | ||
238 | };>>(version> |
268 | };>>(version> |