Search
lxdream.org :: lxdream/src/aica/audio.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/audio.c
changeset 531:f0fee3ba71d1
prev465:3bd7be575792
next561:533f6b478071
author nkeynes
date Mon Nov 19 08:47:39 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Move name-to-driver mappings to display.c and audio.c respectively
Move responsibility for invoking texcache_gl_init() to the driver
view annotate diff log raw
     1 /**
     2  * $Id: audio.c,v 1.11 2007-10-27 05:47:21 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 audio_driver_t audio_driver_list[] = { 
    28 #ifdef HAVE_ESOUND
    29 				       &audio_esd_driver,
    30 #endif
    31 				       &audio_null_driver,
    32 				       NULL };
    34 #define NUM_BUFFERS 3
    35 #define MS_PER_BUFFER 100
    37 #define BUFFER_EMPTY   0
    38 #define BUFFER_WRITING 1
    39 #define BUFFER_FULL    2
    41 struct audio_state {
    42     audio_buffer_t output_buffers[NUM_BUFFERS];
    43     int write_buffer;
    44     int read_buffer;
    45     uint32_t output_format;
    46     uint32_t output_rate;
    47     uint32_t output_sample_size;
    48     struct audio_channel channels[AUDIO_CHANNEL_COUNT];
    49 } audio;
    51 audio_driver_t audio_driver = NULL;
    53 #define NEXT_BUFFER() ((audio.write_buffer == NUM_BUFFERS-1) ? 0 : audio.write_buffer+1)
    55 extern char *arm_mem;
    57 /**
    58  * Preserve audio channel state only - don't bother saving the buffers
    59  */
    60 void audio_save_state( FILE *f )
    61 {
    62     fwrite( &audio.channels[0], sizeof(struct audio_channel), AUDIO_CHANNEL_COUNT, f );
    63 }
    65 int audio_load_state( FILE *f )
    66 {
    67     int read = fread( &audio.channels[0], sizeof(struct audio_channel), AUDIO_CHANNEL_COUNT, f );
    68     return (read == AUDIO_CHANNEL_COUNT ? 0 : -1 );
    69 }
    71 audio_driver_t get_audio_driver_by_name( const char *name )
    72 {
    73     int i;
    74     if( name == NULL ) {
    75 	return audio_driver_list[0];
    76     }
    77     for( i=0; audio_driver_list[i] != NULL; i++ ) {
    78 	if( strcasecmp( audio_driver_list[i]->name, name ) == 0 ) {
    79 	    return audio_driver_list[i];
    80 	}
    81     }
    83     return NULL;
    84 }
    86 /**
    87  * Set the output driver, sample rate and format. Also initializes the 
    88  * output buffers, flushing any current data and reallocating as 
    89  * necessary.
    90  */
    91 gboolean audio_set_driver( audio_driver_t driver, 
    92 			   uint32_t samplerate, int format )
    93 {
    94     uint32_t bytes_per_sample = 1;
    95     uint32_t samples_per_buffer;
    96     int i;
    98     if( audio_driver == NULL || driver != NULL ) {
    99 	if( driver == NULL  )
   100 	    driver = &audio_null_driver;
   101 	if( driver != audio_driver ) {	
   102 	    if( !driver->set_output_format( samplerate, format ) )
   103 		return FALSE;
   104 	    audio_driver = driver;
   105 	}
   106     }
   108     if( format & AUDIO_FMT_16BIT )
   109 	bytes_per_sample = 2;
   110     if( format & AUDIO_FMT_STEREO )
   111 	bytes_per_sample <<= 1;
   112     if( samplerate == audio.output_rate &&
   113 	bytes_per_sample == audio.output_sample_size )
   114 	return TRUE;
   115     samples_per_buffer = (samplerate * MS_PER_BUFFER / 1000);
   116     for( i=0; i<NUM_BUFFERS; i++ ) {
   117 	if( audio.output_buffers[i] != NULL )
   118 	    free(audio.output_buffers[i]);
   119 	audio.output_buffers[i] = g_malloc0( sizeof(struct audio_buffer) + samples_per_buffer * bytes_per_sample );
   120 	audio.output_buffers[i]->length = samples_per_buffer * bytes_per_sample;
   121 	audio.output_buffers[i]->posn = 0;
   122 	audio.output_buffers[i]->status = BUFFER_EMPTY;
   123     }
   124     audio.output_format = format;
   125     audio.output_rate = samplerate;
   126     audio.output_sample_size = bytes_per_sample;
   127     audio.write_buffer = 0;
   128     audio.read_buffer = 0;
   130     return TRUE;
   131 }
   133 /**
   134  * Mark the current write buffer as full and prepare the next buffer for
   135  * writing. Returns the next buffer to write to.
   136  * If all buffers are full, returns NULL.
   137  */
   138 audio_buffer_t audio_next_write_buffer( )
   139 {
   140     audio_buffer_t result = NULL;
   141     audio_buffer_t current = audio.output_buffers[audio.write_buffer];
   142     current->status = BUFFER_FULL;
   143     if( audio.read_buffer == audio.write_buffer &&
   144 	audio_driver->process_buffer( current ) ) {
   145 	audio_next_read_buffer();
   146     }
   147     audio.write_buffer = NEXT_BUFFER();
   148     result = audio.output_buffers[audio.write_buffer];
   149     if( result->status == BUFFER_FULL )
   150 	return NULL;
   151     else {
   152 	result->status = BUFFER_WRITING;
   153 	return result;
   154     }
   155 }
   157 /**
   158  * Mark the current read buffer as empty and return the next buffer for
   159  * reading. If there is no next buffer yet, returns NULL.
   160  */
   161 audio_buffer_t audio_next_read_buffer( )
   162 {
   163     audio_buffer_t current = audio.output_buffers[audio.read_buffer];
   164     assert( current->status == BUFFER_FULL );
   165     current->status = BUFFER_EMPTY;
   166     current->posn = 0;
   167     audio.read_buffer++;
   168     if( audio.read_buffer == NUM_BUFFERS )
   169 	audio.read_buffer = 0;
   171     current = audio.output_buffers[audio.read_buffer];
   172     if( current->status == BUFFER_FULL )
   173 	return current;
   174     else return NULL;
   175 }
   177 /*************************** ADPCM ***********************************/
   179 /**
   180  * The following section borrows heavily from ffmpeg, which is
   181  * copyright (c) 2001-2003 by the fine folks at the ffmpeg project,
   182  * distributed under the GPL version 2 or later.
   183  */
   185 #define CLAMP_TO_SHORT(value) \
   186 if (value > 32767) \
   187     value = 32767; \
   188 else if (value < -32768) \
   189     value = -32768; \
   191 static const int yamaha_indexscale[] = {
   192     230, 230, 230, 230, 307, 409, 512, 614,
   193     230, 230, 230, 230, 307, 409, 512, 614
   194 };
   196 static const int yamaha_difflookup[] = {
   197     1, 3, 5, 7, 9, 11, 13, 15,
   198     -1, -3, -5, -7, -9, -11, -13, -15
   199 };
   201 static inline short adpcm_yamaha_decode_nibble( audio_channel_t c, 
   202 						unsigned char nibble )
   203 {
   204     if( c->adpcm_step == 0 ) {
   205         c->adpcm_predict = 0;
   206         c->adpcm_step = 127;
   207     }
   209     c->adpcm_predict += (c->adpcm_step * yamaha_difflookup[nibble]) >> 3;
   210     CLAMP_TO_SHORT(c->adpcm_predict);
   211     c->adpcm_step = (c->adpcm_step * yamaha_indexscale[nibble]) >> 8;
   212     c->adpcm_step = CLAMP(c->adpcm_step, 127, 24567);
   213     return c->adpcm_predict;
   214 }
   216 /*************************** Sample mixer *****************************/
   218 /**
   219  * Mix a single output sample.
   220  */
   221 void audio_mix_samples( int num_samples )
   222 {
   223     int i, j;
   224     int32_t result_buf[num_samples][2];
   226     memset( &result_buf, 0, sizeof(result_buf) );
   228     for( i=0; i < AUDIO_CHANNEL_COUNT; i++ ) {
   229 	audio_channel_t channel = &audio.channels[i];
   230 	if( channel->active ) {
   231 	    int32_t sample;
   232 	    int vol_left = (channel->vol * (32 - channel->pan)) >> 5;
   233 	    int vol_right = (channel->vol * (channel->pan + 1)) >> 5;
   234 	    switch( channel->sample_format ) {
   235 	    case AUDIO_FMT_16BIT:
   236 		for( j=0; j<num_samples; j++ ) {
   237 		    sample = ((int16_t *)(arm_mem + channel->start))[channel->posn];
   238 		    result_buf[j][0] += sample * vol_left;
   239 		    result_buf[j][1] += sample * vol_right;
   241 		    channel->posn_left += channel->sample_rate;
   242 		    while( channel->posn_left > audio.output_rate ) {
   243 			channel->posn_left -= audio.output_rate;
   244 			channel->posn++;
   246 			if( channel->posn == channel->end ) {
   247 			    if( channel->loop ) {
   248 				channel->posn = channel->loop_start;
   249 				channel->loop = LOOP_LOOPED;
   250 			    } else {
   251 				audio_stop_channel(i);
   252 				j = num_samples;
   253 				break;
   254 			    }
   255 			}
   256 		    }
   257 		}
   258 		break;
   259 	    case AUDIO_FMT_8BIT:
   260 		for( j=0; j<num_samples; j++ ) {
   261 		    sample = ((int8_t *)(arm_mem + channel->start))[channel->posn] << 8;
   262 		    result_buf[j][0] += sample * vol_left;
   263 		    result_buf[j][1] += sample * vol_right;
   265 		    channel->posn_left += channel->sample_rate;
   266 		    while( channel->posn_left > audio.output_rate ) {
   267 			channel->posn_left -= audio.output_rate;
   268 			channel->posn++;
   270 			if( channel->posn == channel->end ) {
   271 			    if( channel->loop ) {
   272 				channel->posn = channel->loop_start;
   273 				channel->loop = LOOP_LOOPED;
   274 			    } else {
   275 				audio_stop_channel(i);
   276 				j = num_samples;
   277 				break;
   278 			    }
   279 			}
   280 		    }
   281 		}
   282 		break;
   283 	    case AUDIO_FMT_ADPCM:
   284 		for( j=0; j<num_samples; j++ ) {
   285 		    sample = (int16_t)channel->adpcm_predict;
   286 		    result_buf[j][0] += sample * vol_left;
   287 		    result_buf[j][1] += sample * vol_right;
   288 		    channel->posn_left += channel->sample_rate;
   289 		    while( channel->posn_left > audio.output_rate ) {
   290 			channel->posn_left -= audio.output_rate;
   291 			channel->posn++;
   292 			if( channel->posn == channel->end ) {
   293 			    if( channel->loop ) {
   294 				channel->posn = channel->loop_start;
   295 				channel->loop = LOOP_LOOPED;
   296 				channel->adpcm_predict = 0;
   297 				channel->adpcm_step = 0;
   298 			    } else {
   299 				audio_stop_channel(i);
   300 				j = num_samples;
   301 				break;
   302 			    }
   303 			}
   304 			uint8_t data = ((uint8_t *)(arm_mem + channel->start))[channel->posn>>1];
   305 			if( channel->posn&1 ) {
   306 			    adpcm_yamaha_decode_nibble( channel, (data >> 4) & 0x0F );
   307 			} else {
   308 			    adpcm_yamaha_decode_nibble( channel, data & 0x0F );
   309 			}
   310 		    }
   311 		}
   312 		break;
   313 	    default:
   314 		break;
   315 	    }
   316 	}
   317     }
   319     /* Down-render to the final output format */
   321     if( audio.output_format & AUDIO_FMT_16BIT ) {
   322 	audio_buffer_t buf = audio.output_buffers[audio.write_buffer];
   323 	uint16_t *data = (uint16_t *)&buf->data[buf->posn];
   324 	for( j=0; j < num_samples; j++ ) {
   325 	    *data++ = (int16_t)(result_buf[j][0] >> 6);
   326 	    *data++ = (int16_t)(result_buf[j][1] >> 6);	
   327 	    buf->posn += 4;
   328 	    if( buf->posn == buf->length ) {
   329 		audio_next_write_buffer();
   330 		buf = audio.output_buffers[audio.write_buffer];
   331 		data = (uint16_t *)&buf->data[0];
   332 	    }
   333 	}
   334     } else {
   335 	audio_buffer_t buf = audio.output_buffers[audio.write_buffer];
   336 	uint8_t *data = (uint8_t *)&buf->data[buf->posn];
   337 	for( j=0; j < num_samples; j++ ) {
   338 	    *data++ = (uint8_t)(result_buf[j][0] >> 16);
   339 	    *data++ = (uint8_t)(result_buf[j][1] >> 16);	
   340 	    buf->posn += 2;
   341 	    if( buf->posn == buf->length ) {
   342 		audio_next_write_buffer();
   343 		buf = audio.output_buffers[audio.write_buffer];
   344 		data = (uint8_t *)&buf->data[0];
   345 	    }
   346 	}
   347     }
   348 }
   350 /********************** Internal AICA calls ***************************/
   352 audio_channel_t audio_get_channel( int channel ) 
   353 {
   354     return &audio.channels[channel];
   355 }
   357 void audio_start_stop_channel( int channel, gboolean start )
   358 {
   359     if( audio.channels[channel].active ) {
   360 	if( !start ) {
   361 	    audio_stop_channel(channel);
   362 	}
   363     } else if( start ) {
   364 	audio_start_channel(channel);
   365     }
   366 }
   368 void audio_stop_channel( int channel ) 
   369 {
   370     audio.channels[channel].active = FALSE;
   371 }
   374 void audio_start_channel( int channel )
   375 {
   376     audio.channels[channel].posn = 0;
   377     audio.channels[channel].posn_left = 0;
   378     audio.channels[channel].active = TRUE;
   379     if( audio.channels[channel].sample_format == AUDIO_FMT_ADPCM ) {
   380 	audio.channels[channel].adpcm_step = 0;
   381 	audio.channels[channel].adpcm_predict = 0;
   382 	uint8_t data = ((uint8_t *)(arm_mem + audio.channels[channel].start))[0];
   383 	adpcm_yamaha_decode_nibble( &audio.channels[channel], data & 0x0F );
   384     }
   385 }
.