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