Search
lxdream.org :: lxdream/src/aica/audio.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/audio.c
changeset 73:0bb57e51ac9e
prev66:2ec5b6eb75e5
next79: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 +0000
1.2 +++ b/src/aica/audio.c Thu Jan 12 11:30:19 2006 +0000
1.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 sound
1.9 * buffer for output.
1.10 @@ -25,7 +25,7 @@
1.11 #include <string.h>
1.12
1.13 #define NUM_BUFFERS 3
1.14 -#define MS_PER_BUFFER 4000
1.15 +#define MS_PER_BUFFER 500
1.16
1.17 #define BUFFER_EMPTY 0
1.18 #define BUFFER_WRITING 1
1.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.40
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 + else
1.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 }
1.213
.