filename | src/aica/audio.c |
changeset | 82:81a4acf75f10 |
prev | 79:6d832137fdff |
next | 106:9048bac046c3 |
author | nkeynes |
date | Wed Feb 15 13:11:50 2006 +0000 (18 years ago) |
permissions | -rw-r--r-- |
last change | Split pvr2.c out to separate files for TA and renderer, minor renames change pvrdma to use mem_copy_to_sh4 |
view | annotate | diff | log | raw |
1 /**
2 * $Id: audio.c,v 1.4 2006-01-17 12:54:02 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 1000
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 void audio_set_output( 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( format & AUDIO_FMT_16BIT )
63 bytes_per_sample = 2;
64 if( format & AUDIO_FMT_STEREO )
65 bytes_per_sample <<= 1;
66 if( samplerate == audio.output_rate &&
67 bytes_per_sample == audio.output_sample_size )
68 return;
69 samples_per_buffer = (samplerate * MS_PER_BUFFER / 1000);
70 for( i=0; i<NUM_BUFFERS; i++ ) {
71 if( audio.output_buffers[i] != NULL )
72 free(audio.output_buffers[i]);
73 audio.output_buffers[i] = g_malloc0( sizeof(struct audio_buffer) + samples_per_buffer * bytes_per_sample );
74 audio.output_buffers[i]->length = samples_per_buffer * bytes_per_sample;
75 audio.output_buffers[i]->posn = 0;
76 audio.output_buffers[i]->status = BUFFER_EMPTY;
77 }
78 audio.output_format = format;
79 audio.output_rate = samplerate;
80 audio.output_sample_size = bytes_per_sample;
81 audio.write_buffer = 0;
82 audio.read_buffer = 0;
84 if( driver == NULL )
85 driver = &null_audio_driver;
86 audio_driver = driver;
87 audio_driver->set_output_format( samplerate, format );
88 }
90 /**
91 * Mark the current write buffer as full and prepare the next buffer for
92 * writing. Returns the next buffer to write to.
93 * If all buffers are full, returns NULL.
94 */
95 audio_buffer_t audio_next_write_buffer( )
96 {
97 audio_buffer_t result = NULL;
98 audio_buffer_t current = audio.output_buffers[audio.write_buffer];
99 current->status = BUFFER_FULL;
100 if( audio.read_buffer == audio.write_buffer &&
101 audio_driver->process_buffer( current ) ) {
102 audio_next_read_buffer();
103 }
104 audio.write_buffer = NEXT_BUFFER();
105 result = audio.output_buffers[audio.write_buffer];
106 if( result->status == BUFFER_FULL )
107 return NULL;
108 else {
109 result->status = BUFFER_WRITING;
110 return result;
111 }
112 }
114 /**
115 * Mark the current read buffer as empty and return the next buffer for
116 * reading. If there is no next buffer yet, returns NULL.
117 */
118 audio_buffer_t audio_next_read_buffer( )
119 {
120 audio_buffer_t current = audio.output_buffers[audio.read_buffer];
121 assert( current->status == BUFFER_FULL );
122 current->status = BUFFER_EMPTY;
123 current->posn = 0;
124 audio.read_buffer++;
125 if( audio.read_buffer == NUM_BUFFERS )
126 audio.read_buffer = 0;
128 current = audio.output_buffers[audio.read_buffer];
129 if( current->status == BUFFER_FULL )
130 return current;
131 else return NULL;
132 }
134 /*************************** ADPCM ***********************************/
136 /**
137 * The following section borrows heavily from ffmpeg, which is
138 * copyright (c) 2001-2003 by the fine folks at the ffmpeg project,
139 * distributed under the GPL version 2 or later.
140 */
142 #define CLAMP_TO_SHORT(value) \
143 if (value > 32767) \
144 value = 32767; \
145 else if (value < -32768) \
146 value = -32768; \
148 static const int yamaha_indexscale[] = {
149 230, 230, 230, 230, 307, 409, 512, 614,
150 230, 230, 230, 230, 307, 409, 512, 614
151 };
153 static const int yamaha_difflookup[] = {
154 1, 3, 5, 7, 9, 11, 13, 15,
155 -1, -3, -5, -7, -9, -11, -13, -15
156 };
158 static inline short adpcm_yamaha_decode_nibble( audio_channel_t c,
159 unsigned char nibble )
160 {
161 if( c->adpcm_step == 0 ) {
162 c->adpcm_predict = 0;
163 c->adpcm_step = 127;
164 }
166 c->adpcm_predict += (c->adpcm_step * yamaha_difflookup[nibble]) >> 3;
167 CLAMP_TO_SHORT(c->adpcm_predict);
168 c->adpcm_step = (c->adpcm_step * yamaha_indexscale[nibble]) >> 8;
169 c->adpcm_step = CLAMP(c->adpcm_step, 127, 24567);
170 return c->adpcm_predict;
171 }
173 /*************************** Sample mixer *****************************/
175 /**
176 * Mix a single output sample.
177 */
178 void audio_mix_samples( int num_samples )
179 {
180 int i, j;
181 int32_t result_buf[num_samples][2];
183 memset( &result_buf, 0, sizeof(result_buf) );
185 for( i=0; i < 64; i++ ) {
186 audio_channel_t channel = &audio.channels[i];
187 if( channel->active ) {
188 int32_t sample;
189 int vol_left = (channel->vol * (32 - channel->pan)) >> 5;
190 int vol_right = (channel->vol * (channel->pan + 1)) >> 5;
191 switch( channel->sample_format ) {
192 case AUDIO_FMT_16BIT:
193 for( j=0; j<num_samples; j++ ) {
194 sample = *(int16_t *)(arm_mem + channel->posn + channel->start);
195 result_buf[j][0] += sample * vol_left;
196 result_buf[j][1] += sample * vol_right;
198 channel->posn_left += channel->sample_rate;
199 while( channel->posn_left > audio.output_rate ) {
200 channel->posn_left -= audio.output_rate;
201 channel->posn++;
203 if( channel->posn == channel->end ) {
204 if( channel->loop )
205 channel->posn = channel->loop_start;
206 else {
207 audio_stop_channel(i);
208 j = num_samples;
209 break;
210 }
211 }
212 }
213 }
214 break;
215 case AUDIO_FMT_8BIT:
216 for( j=0; j<num_samples; j++ ) {
217 sample = (*(int8_t *)(arm_mem + channel->posn + channel->start)) << 8;
218 result_buf[j][0] += sample * vol_left;
219 result_buf[j][1] += sample * vol_right;
221 channel->posn_left += channel->sample_rate;
222 while( channel->posn_left > audio.output_rate ) {
223 channel->posn_left -= audio.output_rate;
224 channel->posn++;
226 if( channel->posn == channel->end ) {
227 if( channel->loop )
228 channel->posn = channel->loop_start;
229 else {
230 audio_stop_channel(i);
231 j = num_samples;
232 break;
233 }
234 }
235 }
236 }
237 break;
238 case AUDIO_FMT_ADPCM:
239 for( j=0; j<num_samples; j++ ) {
240 sample = (int16_t)channel->adpcm_predict;
241 result_buf[j][0] += sample * vol_left;
242 result_buf[j][1] += sample * vol_right;
243 channel->posn_left += channel->sample_rate;
244 while( channel->posn_left > audio.output_rate ) {
245 channel->posn_left -= audio.output_rate;
246 if( channel->adpcm_nibble == 0 ) {
247 uint8_t data = *(uint8_t *)(arm_mem + channel->posn + channel->start);
248 adpcm_yamaha_decode_nibble( channel, (data >> 4) & 0x0F );
249 channel->adpcm_nibble = 1;
250 } else {
251 channel->posn++;
252 if( channel->posn == channel->end ) {
253 if( channel->loop )
254 channel->posn = channel->loop_start;
255 else
256 audio_stop_channel(i);
257 break;
258 }
259 uint8_t data = *(uint8_t *)(arm_mem + channel->posn + channel->start);
260 adpcm_yamaha_decode_nibble( channel, data & 0x0F );
261 channel->adpcm_nibble = 0;
262 }
263 }
264 }
265 break;
266 default:
267 break;
268 }
269 }
270 }
272 /* Down-render to the final output format */
274 if( audio.output_format & AUDIO_FMT_16BIT ) {
275 audio_buffer_t buf = audio.output_buffers[audio.write_buffer];
276 uint16_t *data = (uint16_t *)&buf->data[buf->posn];
277 for( j=0; j < num_samples; j++ ) {
278 *data++ = (int16_t)(result_buf[j][0] >> 6);
279 *data++ = (int16_t)(result_buf[j][1] >> 6);
280 buf->posn += 4;
281 if( buf->posn == buf->length ) {
282 audio_next_write_buffer();
283 buf = audio.output_buffers[audio.write_buffer];
284 data = (uint16_t *)&buf->data[0];
285 }
286 }
287 } else {
288 audio_buffer_t buf = audio.output_buffers[audio.write_buffer];
289 uint8_t *data = (uint8_t *)&buf->data[buf->posn];
290 for( j=0; j < num_samples; j++ ) {
291 *data++ = (uint8_t)(result_buf[j][0] >> 16);
292 *data++ = (uint8_t)(result_buf[j][1] >> 16);
293 buf->posn += 2;
294 if( buf->posn == buf->length ) {
295 audio_next_write_buffer();
296 buf = audio.output_buffers[audio.write_buffer];
297 data = (uint8_t *)&buf->data[0];
298 }
299 }
300 }
301 }
303 /********************** Internal AICA calls ***************************/
305 audio_channel_t audio_get_channel( int channel )
306 {
307 return &audio.channels[channel];
308 }
310 void audio_stop_channel( int channel )
311 {
312 audio.channels[channel].active = FALSE;
313 }
316 void audio_start_channel( int channel )
317 {
318 audio.channels[channel].posn = 0;
319 audio.channels[channel].posn_left = 0;
320 audio.channels[channel].adpcm_nibble = 0;
321 audio.channels[channel].adpcm_step = 0;
322 audio.channels[channel].adpcm_predict = 0;
323 audio.channels[channel].active = TRUE;
324 }
.