filename | src/aica/audio.c |
changeset | 242:04f5cdb68d8e |
prev | 111:230243c2b520 |
next | 431:248dd77a9e44 |
author | nkeynes |
date | Wed Jan 17 21:27:20 2007 +0000 (17 years ago) |
permissions | -rw-r--r-- |
last change | Rename SPUDMA to G2DMA (following KOS's lead) Remove sh4r.icount (obsolete) Rewrite G2 fifo status in terms of slice cycles |
view | annotate | diff | log | raw |
1 /**
2 * $Id: audio.c,v 1.7 2006-12-15 10:19:49 nkeynes Exp $
3 *
4 * Audio mixer core. Combines all the active streams into a single sound
5 * buffer for output.
6 *
7 * Copyright (c) 2005 Nathan Keynes.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
20 #include "aica/aica.h"
21 #include "aica/audio.h"
22 #include "glib/gmem.h"
23 #include "dream.h"
24 #include <assert.h>
25 #include <string.h>
27 #define NUM_BUFFERS 3
28 #define MS_PER_BUFFER 50
30 #define BUFFER_EMPTY 0
31 #define BUFFER_WRITING 1
32 #define BUFFER_FULL 2
34 struct audio_state {
35 audio_buffer_t output_buffers[NUM_BUFFERS];
36 int write_buffer;
37 int read_buffer;
38 uint32_t output_format;
39 uint32_t output_rate;
40 uint32_t output_sample_size;
41 struct audio_channel channels[64];
42 } audio;
44 audio_driver_t audio_driver = NULL;
46 #define NEXT_BUFFER() ((audio.write_buffer == NUM_BUFFERS-1) ? 0 : audio.write_buffer+1)
48 extern char *arm_mem;
50 /**
51 * Set the output driver, sample rate and format. Also initializes the
52 * output buffers, flushing any current data and reallocating as
53 * necessary.
54 */
55 gboolean audio_set_driver( audio_driver_t driver,
56 uint32_t samplerate, int format )
57 {
58 uint32_t bytes_per_sample = 1;
59 uint32_t samples_per_buffer;
60 int i;
62 if( audio_driver == NULL || driver != NULL ) {
63 if( driver == NULL )
64 driver = &audio_null_driver;
65 if( driver != audio_driver ) {
66 if( !driver->set_output_format( samplerate, format ) )
67 return FALSE;
68 audio_driver = driver;
69 }
70 }
72 if( format & AUDIO_FMT_16BIT )
73 bytes_per_sample = 2;
74 if( format & AUDIO_FMT_STEREO )
75 bytes_per_sample <<= 1;
76 if( samplerate == audio.output_rate &&
77 bytes_per_sample == audio.output_sample_size )
78 return;
79 samples_per_buffer = (samplerate * MS_PER_BUFFER / 1000);
80 for( i=0; i<NUM_BUFFERS; i++ ) {
81 if( audio.output_buffers[i] != NULL )
82 free(audio.output_buffers[i]);
83 audio.output_buffers[i] = g_malloc0( sizeof(struct audio_buffer) + samples_per_buffer * bytes_per_sample );
84 audio.output_buffers[i]->length = samples_per_buffer * bytes_per_sample;
85 audio.output_buffers[i]->posn = 0;
86 audio.output_buffers[i]->status = BUFFER_EMPTY;
87 }
88 audio.output_format = format;
89 audio.output_rate = samplerate;
90 audio.output_sample_size = bytes_per_sample;
91 audio.write_buffer = 0;
92 audio.read_buffer = 0;
94 return TRUE;
95 }
97 /**
98 * Mark the current write buffer as full and prepare the next buffer for
99 * writing. Returns the next buffer to write to.
100 * If all buffers are full, returns NULL.
101 */
102 audio_buffer_t audio_next_write_buffer( )
103 {
104 audio_buffer_t result = NULL;
105 audio_buffer_t current = audio.output_buffers[audio.write_buffer];
106 current->status = BUFFER_FULL;
107 if( audio.read_buffer == audio.write_buffer &&
108 audio_driver->process_buffer( current ) ) {
109 audio_next_read_buffer();
110 }
111 audio.write_buffer = NEXT_BUFFER();
112 result = audio.output_buffers[audio.write_buffer];
113 if( result->status == BUFFER_FULL )
114 return NULL;
115 else {
116 result->status = BUFFER_WRITING;
117 return result;
118 }
119 }
121 /**
122 * Mark the current read buffer as empty and return the next buffer for
123 * reading. If there is no next buffer yet, returns NULL.
124 */
125 audio_buffer_t audio_next_read_buffer( )
126 {
127 audio_buffer_t current = audio.output_buffers[audio.read_buffer];
128 assert( current->status == BUFFER_FULL );
129 current->status = BUFFER_EMPTY;
130 current->posn = 0;
131 audio.read_buffer++;
132 if( audio.read_buffer == NUM_BUFFERS )
133 audio.read_buffer = 0;
135 current = audio.output_buffers[audio.read_buffer];
136 if( current->status == BUFFER_FULL )
137 return current;
138 else return NULL;
139 }
141 /*************************** ADPCM ***********************************/
143 /**
144 * The following section borrows heavily from ffmpeg, which is
145 * copyright (c) 2001-2003 by the fine folks at the ffmpeg project,
146 * distributed under the GPL version 2 or later.
147 */
149 #define CLAMP_TO_SHORT(value) \
150 if (value > 32767) \
151 value = 32767; \
152 else if (value < -32768) \
153 value = -32768; \
155 static const int yamaha_indexscale[] = {
156 230, 230, 230, 230, 307, 409, 512, 614,
157 230, 230, 230, 230, 307, 409, 512, 614
158 };
160 static const int yamaha_difflookup[] = {
161 1, 3, 5, 7, 9, 11, 13, 15,
162 -1, -3, -5, -7, -9, -11, -13, -15
163 };
165 static inline short adpcm_yamaha_decode_nibble( audio_channel_t c,
166 unsigned char nibble )
167 {
168 if( c->adpcm_step == 0 ) {
169 c->adpcm_predict = 0;
170 c->adpcm_step = 127;
171 }
173 c->adpcm_predict += (c->adpcm_step * yamaha_difflookup[nibble]) >> 3;
174 CLAMP_TO_SHORT(c->adpcm_predict);
175 c->adpcm_step = (c->adpcm_step * yamaha_indexscale[nibble]) >> 8;
176 c->adpcm_step = CLAMP(c->adpcm_step, 127, 24567);
177 return c->adpcm_predict;
178 }
180 /*************************** Sample mixer *****************************/
182 /**
183 * Mix a single output sample.
184 */
185 void audio_mix_samples( int num_samples )
186 {
187 int i, j;
188 int32_t result_buf[num_samples][2];
190 memset( &result_buf, 0, sizeof(result_buf) );
192 for( i=0; i < 64; i++ ) {
193 audio_channel_t channel = &audio.channels[i];
194 if( channel->active ) {
195 int32_t sample;
196 int vol_left = (channel->vol * (32 - channel->pan)) >> 5;
197 int vol_right = (channel->vol * (channel->pan + 1)) >> 5;
198 switch( channel->sample_format ) {
199 case AUDIO_FMT_16BIT:
200 for( j=0; j<num_samples; j++ ) {
201 sample = *(int16_t *)(arm_mem + channel->posn + channel->start);
202 result_buf[j][0] += sample * vol_left;
203 result_buf[j][1] += sample * vol_right;
205 channel->posn_left += channel->sample_rate;
206 while( channel->posn_left > audio.output_rate ) {
207 channel->posn_left -= audio.output_rate;
208 channel->posn++;
210 if( channel->posn == channel->end ) {
211 if( channel->loop )
212 channel->posn = channel->loop_start;
213 else {
214 audio_stop_channel(i);
215 j = num_samples;
216 break;
217 }
218 }
219 }
220 }
221 break;
222 case AUDIO_FMT_8BIT:
223 for( j=0; j<num_samples; j++ ) {
224 sample = (*(int8_t *)(arm_mem + channel->posn + channel->start)) << 8;
225 result_buf[j][0] += sample * vol_left;
226 result_buf[j][1] += sample * vol_right;
228 channel->posn_left += channel->sample_rate;
229 while( channel->posn_left > audio.output_rate ) {
230 channel->posn_left -= audio.output_rate;
231 channel->posn++;
233 if( channel->posn == channel->end ) {
234 if( channel->loop )
235 channel->posn = channel->loop_start;
236 else {
237 audio_stop_channel(i);
238 j = num_samples;
239 break;
240 }
241 }
242 }
243 }
244 break;
245 case AUDIO_FMT_ADPCM:
246 for( j=0; j<num_samples; j++ ) {
247 sample = (int16_t)channel->adpcm_predict;
248 result_buf[j][0] += sample * vol_left;
249 result_buf[j][1] += sample * vol_right;
250 channel->posn_left += channel->sample_rate;
251 while( channel->posn_left > audio.output_rate ) {
252 channel->posn_left -= audio.output_rate;
253 if( channel->adpcm_nibble == 0 ) {
254 uint8_t data = *(uint8_t *)(arm_mem + channel->posn + channel->start);
255 adpcm_yamaha_decode_nibble( channel, (data >> 4) & 0x0F );
256 channel->adpcm_nibble = 1;
257 } else {
258 channel->posn++;
259 if( channel->posn == channel->end ) {
260 if( channel->loop )
261 channel->posn = channel->loop_start;
262 else
263 audio_stop_channel(i);
264 break;
265 }
266 uint8_t data = *(uint8_t *)(arm_mem + channel->posn + channel->start);
267 adpcm_yamaha_decode_nibble( channel, data & 0x0F );
268 channel->adpcm_nibble = 0;
269 }
270 }
271 }
272 break;
273 default:
274 break;
275 }
276 }
277 }
279 /* Down-render to the final output format */
281 if( audio.output_format & AUDIO_FMT_16BIT ) {
282 audio_buffer_t buf = audio.output_buffers[audio.write_buffer];
283 uint16_t *data = (uint16_t *)&buf->data[buf->posn];
284 for( j=0; j < num_samples; j++ ) {
285 *data++ = (int16_t)(result_buf[j][0] >> 6);
286 *data++ = (int16_t)(result_buf[j][1] >> 6);
287 buf->posn += 4;
288 if( buf->posn == buf->length ) {
289 audio_next_write_buffer();
290 buf = audio.output_buffers[audio.write_buffer];
291 data = (uint16_t *)&buf->data[0];
292 }
293 }
294 } else {
295 audio_buffer_t buf = audio.output_buffers[audio.write_buffer];
296 uint8_t *data = (uint8_t *)&buf->data[buf->posn];
297 for( j=0; j < num_samples; j++ ) {
298 *data++ = (uint8_t)(result_buf[j][0] >> 16);
299 *data++ = (uint8_t)(result_buf[j][1] >> 16);
300 buf->posn += 2;
301 if( buf->posn == buf->length ) {
302 audio_next_write_buffer();
303 buf = audio.output_buffers[audio.write_buffer];
304 data = (uint8_t *)&buf->data[0];
305 }
306 }
307 }
308 }
310 /********************** Internal AICA calls ***************************/
312 audio_channel_t audio_get_channel( int channel )
313 {
314 return &audio.channels[channel];
315 }
317 void audio_stop_channel( int channel )
318 {
319 audio.channels[channel].active = FALSE;
320 }
323 void audio_start_channel( int channel )
324 {
325 audio.channels[channel].posn = 0;
326 audio.channels[channel].posn_left = 0;
327 audio.channels[channel].adpcm_nibble = 0;
328 audio.channels[channel].adpcm_step = 0;
329 audio.channels[channel].adpcm_predict = 0;
330 audio.channels[channel].active = TRUE;
331 }
.