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