filename | src/aica/audio.c |
changeset | 73:0bb57e51ac9e |
prev | 66:2ec5b6eb75e5 |
next | 79:6d832137fdff |
author | nkeynes |
date | Thu Jan 12 11:30:19 2006 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Render multiple samples per shot, should be mildly faster Move timer logic down into armcore Minor tweaks |
file | annotate | diff | log | raw |
1.1 --- a/src/aica/audio.c Tue Jan 10 13:56:54 2006 +00001.2 +++ b/src/aica/audio.c Thu Jan 12 11:30:19 2006 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: audio.c,v 1.1 2006-01-10 13:56:54 nkeynes Exp $1.6 + * $Id: audio.c,v 1.2 2006-01-12 11:30:19 nkeynes Exp $1.7 *1.8 * Audio mixer core. Combines all the active streams into a single sound1.9 * buffer for output.1.10 @@ -25,7 +25,7 @@1.11 #include <string.h>1.13 #define NUM_BUFFERS 31.14 -#define MS_PER_BUFFER 40001.15 +#define MS_PER_BUFFER 5001.17 #define BUFFER_EMPTY 01.18 #define BUFFER_WRITING 11.19 @@ -71,7 +71,7 @@1.20 if( audio.output_buffers[i] != NULL )1.21 free(audio.output_buffers[i]);1.22 audio.output_buffers[i] = g_malloc0( sizeof(struct audio_buffer) + samples_per_buffer * bytes_per_sample );1.23 - audio.output_buffers[i]->length = samples_per_buffer;1.24 + audio.output_buffers[i]->length = samples_per_buffer * bytes_per_sample;1.25 audio.output_buffers[i]->posn = 0;1.26 audio.output_buffers[i]->status = BUFFER_EMPTY;1.27 }1.28 @@ -175,10 +175,12 @@1.29 /**1.30 * Mix a single output sample.1.31 */1.32 -void audio_mix_sample( )1.33 +void audio_mix_samples( int num_samples )1.34 {1.35 int i, j;1.36 - int32_t result_left = 0, result_right = 0;1.37 + int32_t result_buf[num_samples][2];1.38 +1.39 + memset( &result_buf, 0, sizeof(result_buf) );1.41 for( i=0; i < 64; i++ ) {1.42 audio_channel_t channel = &audio.channels[i];1.43 @@ -186,74 +188,113 @@1.44 int32_t sample;1.45 switch( channel->sample_format ) {1.46 case AUDIO_FMT_16BIT:1.47 - sample = *(int16_t *)(arm_mem + channel->posn + channel->start);1.48 + for( j=0; j<num_samples; j++ ) {1.49 + sample = *(int16_t *)(arm_mem + channel->posn + channel->start);1.50 + result_buf[j][0] += sample * channel->vol_left;1.51 + result_buf[j][1] += sample * channel->vol_right;1.52 +1.53 + channel->posn_left += channel->sample_rate;1.54 + while( channel->posn_left > audio.output_rate ) {1.55 + channel->posn_left -= audio.output_rate;1.56 + channel->posn++;1.57 +1.58 + if( channel->posn == channel->end ) {1.59 + if( channel->loop )1.60 + channel->posn = channel->loop_start;1.61 + else {1.62 + audio_stop_channel(i);1.63 + j = num_samples;1.64 + break;1.65 + }1.66 + }1.67 + }1.68 + }1.69 break;1.70 case AUDIO_FMT_8BIT:1.71 - sample = (*(int8_t *)(arm_mem + channel->posn + channel->start)) << 8;1.72 - break;1.73 - case AUDIO_FMT_16BIT|AUDIO_FMT_UNSIGNED:1.74 - sample = (int8_t)((*(uint16_t *)(arm_mem + channel->posn + channel->start)) - 0x8000);1.75 - break;1.76 - case AUDIO_FMT_8BIT|AUDIO_FMT_UNSIGNED:1.77 - sample = (int8_t)((*(uint8_t *)(arm_mem + channel->posn + channel->start)) - 0x80);1.78 + for( j=0; j<num_samples; j++ ) {1.79 + sample = (*(int8_t *)(arm_mem + channel->posn + channel->start)) << 8;1.80 + result_buf[j][0] += sample * channel->vol_left;1.81 + result_buf[j][1] += sample * channel->vol_right;1.82 +1.83 + channel->posn_left += channel->sample_rate;1.84 + while( channel->posn_left > audio.output_rate ) {1.85 + channel->posn_left -= audio.output_rate;1.86 + channel->posn++;1.87 +1.88 + if( channel->posn == channel->end ) {1.89 + if( channel->loop )1.90 + channel->posn = channel->loop_start;1.91 + else {1.92 + audio_stop_channel(i);1.93 + j = num_samples;1.94 + break;1.95 + }1.96 + }1.97 + }1.98 + }1.99 break;1.100 case AUDIO_FMT_ADPCM:1.101 - sample = (int16_t)channel->adpcm_predict;1.102 + for( j=0; j<num_samples; j++ ) {1.103 + sample = (int16_t)channel->adpcm_predict;1.104 + result_buf[j][0] += sample * channel->vol_left;1.105 + result_buf[j][1] += sample * channel->vol_right;1.106 + channel->posn_left += channel->sample_rate;1.107 + while( channel->posn_left > audio.output_rate ) {1.108 + channel->posn_left -= audio.output_rate;1.109 + if( channel->adpcm_nibble == 0 ) {1.110 + uint8_t data = *(uint8_t *)(arm_mem + channel->posn + channel->start);1.111 + adpcm_yamaha_decode_nibble( channel, (data >> 4) & 0x0F );1.112 + channel->adpcm_nibble = 1;1.113 + } else {1.114 + channel->posn++;1.115 + if( channel->posn == channel->end ) {1.116 + if( channel->loop )1.117 + channel->posn = channel->loop_start;1.118 + else1.119 + audio_stop_channel(i);1.120 + break;1.121 + }1.122 + uint8_t data = *(uint8_t *)(arm_mem + channel->posn + channel->start);1.123 + adpcm_yamaha_decode_nibble( channel, data & 0x0F );1.124 + channel->adpcm_nibble = 0;1.125 + }1.126 + }1.127 + }1.128 + break;1.129 default:1.130 - sample = 0; /* Unsupported */1.131 - }1.132 - result_left += sample * channel->vol_left;1.133 - result_right += sample * channel->vol_right;1.134 -1.135 - channel->posn_left += channel->sample_rate;1.136 - while( channel->posn_left > audio.output_rate ) {1.137 - channel->posn_left -= audio.output_rate;1.138 - if( channel->sample_format == AUDIO_FMT_ADPCM &&1.139 - channel->adpcm_nibble == 0 ) {1.140 - uint8_t data = *(uint8_t *)(arm_mem + channel->posn + channel->start);1.141 - adpcm_yamaha_decode_nibble( channel, (data >> 4) & 0x0F );1.142 - channel->adpcm_nibble = 1;1.143 - continue;1.144 - }1.145 -1.146 - channel->posn++;1.147 -1.148 - if( channel->loop_count != 0 &&1.149 - channel->posn >= channel->loop_end ) {1.150 - channel->posn = channel->loop_start;1.151 - if( channel->loop_count != -1 )1.152 - channel->loop_count --;1.153 - } else if( channel->posn >= channel->end ) {1.154 - audio_stop_channel( i );1.155 - break;1.156 - }1.157 -1.158 - if( channel->sample_format == AUDIO_FMT_ADPCM ) {1.159 - uint8_t data = *(uint8_t *)(arm_mem + channel->posn + channel->start);1.160 - adpcm_yamaha_decode_nibble( channel, data & 0x0F );1.161 - channel->adpcm_nibble = 0;1.162 - }1.163 + break;1.164 }1.165 }1.166 }1.167 -1.168 +1.169 /* Down-render to the final output format */1.170 - audio_buffer_t buf =1.171 - audio.output_buffers[audio.write_buffer];1.172 +1.173 if( audio.output_format & AUDIO_FMT_16BIT ) {1.174 - uint16_t *data = (uint16_t *)&buf->data[buf->posn*audio.output_sample_size];1.175 - *data++ = (int16_t)(result_left >> 8);1.176 - *data++ = (int16_t)(result_right >> 8);1.177 + audio_buffer_t buf = audio.output_buffers[audio.write_buffer];1.178 + uint16_t *data = (uint16_t *)&buf->data[buf->posn];1.179 + for( j=0; j < num_samples; j++ ) {1.180 + *data++ = (int16_t)(result_buf[j][0] >> 8);1.181 + *data++ = (int16_t)(result_buf[j][1] >> 8);1.182 + buf->posn += 4;1.183 + if( buf->posn == buf->length ) {1.184 + audio_next_write_buffer();1.185 + buf = audio.output_buffers[audio.write_buffer];1.186 + data = (uint16_t *)&buf->data[0];1.187 + }1.188 + }1.189 } else {1.190 - audio_buffer_t buf =1.191 - audio.output_buffers[audio.write_buffer];1.192 - uint8_t *data = (uint8_t *)&buf->data[buf->posn*audio.output_sample_size];1.193 - *data++ = (int8_t)(result_left >> 22);1.194 - *data++ = (int8_t)(result_right >>22);1.195 - }1.196 - buf->posn++;1.197 - if( buf->posn == buf->length ) {1.198 - audio_next_write_buffer();1.199 + audio_buffer_t buf = audio.output_buffers[audio.write_buffer];1.200 + uint8_t *data = (uint8_t *)&buf->data[buf->posn];1.201 + for( j=0; j < num_samples; j++ ) {1.202 + *data++ = (uint8_t)(result_buf[j][0] >> 16);1.203 + *data++ = (uint8_t)(result_buf[j][1] >> 16);1.204 + buf->posn += 2;1.205 + if( buf->posn == buf->length ) {1.206 + audio_next_write_buffer();1.207 + buf = audio.output_buffers[audio.write_buffer];1.208 + data = (uint8_t *)&buf->data[0];1.209 + }1.210 + }1.211 }1.212 }
.