Search
lxdream.org :: lxdream/src/aica/audio.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/audio.c
changeset 1089:a3984d242909
prev1024:c67f2d61ab97
next1296:30ecee61f811
author nkeynes
date Mon Dec 07 08:59:50 2009 +1000 (14 years ago)
permissions -rw-r--r--
last change Mask audio RAM accesses from the mixer to ensure they're in bounds. Uncertain if
this is correct (vs eg zero-fill), but it's at least consistent with the masking
of the channel start position.
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 #define MAX_AUDIO_DRIVERS 16
    28 extern struct audio_driver audio_null_driver;
    29 extern struct audio_driver audio_osx_driver;
    30 extern struct audio_driver audio_pulse_driver;
    31 extern struct audio_driver audio_esd_driver;
    32 extern struct audio_driver audio_alsa_driver;
    33 extern struct audio_driver audio_sdl_driver;
    35 static int audio_driver_count = 0;
    36 static audio_driver_t audio_driver_list[MAX_AUDIO_DRIVERS] = {};
    38 #define NUM_BUFFERS 3
    39 #define MS_PER_BUFFER 100
    41 #define BUFFER_EMPTY   0
    42 #define BUFFER_WRITING 1
    43 #define BUFFER_FULL    2
    45 struct audio_state {
    46     audio_buffer_t output_buffers[NUM_BUFFERS];
    47     int write_buffer;
    48     int read_buffer;
    49     uint32_t output_format;
    50     uint32_t output_rate;
    51     uint32_t output_sample_size;
    52     struct audio_channel channels[AUDIO_CHANNEL_COUNT];
    53 } audio;
    55 audio_driver_t audio_driver = NULL;
    57 #define NEXT_BUFFER() ((audio.write_buffer == NUM_BUFFERS-1) ? 0 : audio.write_buffer+1)
    59 /**
    60  * Preserve audio channel state only - don't bother saving the buffers
    61  */
    62 void audio_save_state( FILE *f )
    63 {
    64     fwrite( &audio.channels[0], sizeof(struct audio_channel), AUDIO_CHANNEL_COUNT, f );
    65 }
    67 int audio_load_state( FILE *f )
    68 {
    69     int read = fread( &audio.channels[0], sizeof(struct audio_channel), AUDIO_CHANNEL_COUNT, f );
    70     return (read == AUDIO_CHANNEL_COUNT ? 0 : -1 );
    71 }
    73 static int audio_driver_priority_compare(const void *a, const void *b)
    74 {
    75     audio_driver_t ada = *(audio_driver_t *)a;
    76     audio_driver_t adb = *(audio_driver_t *)b;
    77     return ada->priority - adb->priority;
    78 }
    80 static int audio_driver_name_compare(const void *a, const void *b)
    81 {
    82     audio_driver_t ada = *(audio_driver_t *)a;
    83     audio_driver_t adb = *(audio_driver_t *)b;
    84     return strcasecmp( ada->name, adb->name );
    85 }
    89 gboolean audio_register_driver( audio_driver_t driver )
    90 {
    91     if( audio_driver_count >= MAX_AUDIO_DRIVERS ) {
    92         return FALSE;
    93     }
    94     audio_driver_list[audio_driver_count++] = driver;
    95     qsort( audio_driver_list, audio_driver_count, sizeof( audio_driver_t ), audio_driver_priority_compare );
    96     return TRUE;
    97 }
    99 audio_driver_t get_audio_driver_by_name( const char *name )
   100 {
   101     int i;
   102     if( name == NULL ) {
   103         return audio_driver_list[0];
   104     }
   105     for( i=0; i < audio_driver_count; i++ ) {
   106         if( strcasecmp( audio_driver_list[i]->name, name ) == 0 ) {
   107             return audio_driver_list[i];
   108         }
   109     }
   111     return NULL;
   112 }
   114 void print_audio_drivers( FILE * out )
   115 {
   116     int i;
   117     audio_driver_t temp_list[MAX_AUDIO_DRIVERS];
   118     memcpy( temp_list, audio_driver_list, audio_driver_count*sizeof(audio_driver_t) );
   119     qsort( temp_list, audio_driver_count, sizeof(audio_driver_t), audio_driver_name_compare );
   120     fprintf( out, "Available audio drivers:\n" );
   121     for( i=0; i < audio_driver_count; i++ ) {
   122         fprintf( out, "  %-8s %s\n", temp_list[i]->name,
   123                 gettext(temp_list[i]->description) );
   124     }
   125 }
   127 audio_driver_t audio_init_driver( const char *preferred_driver )
   128 {
   129     audio_driver_t audio_driver = get_audio_driver_by_name(preferred_driver);
   130     if( audio_driver == NULL ) {
   131         ERROR( "Audio driver '%s' not found, aborting.", preferred_driver );
   132         exit(2);
   133     } else if( audio_set_driver( audio_driver ) == FALSE ) {
   134         int i;
   135         for( i=0; i < audio_driver_count; i++ ) {
   136             if( audio_driver_list[i] != audio_driver &&
   137                 audio_set_driver( audio_driver_list[i] ) ) {
   138                 ERROR( "Failed to initialize audio driver %s, falling back to %s", 
   139                        audio_driver->name, audio_driver_list[i]->name );
   140                 return audio_driver_list[i];
   141             }
   142         }
   143         ERROR( "Unable to intialize any audio driver, aborting." );
   144         exit(2);
   145     }
   146     return audio_driver;
   147 }
   149 void audio_start_driver(void)
   150 {
   151     if( audio_driver != NULL && audio_driver->start != NULL ) {
   152         audio_driver->start();
   153     }
   154 }
   156 void audio_stop_driver(void)
   157 {
   158     if( audio_driver != NULL && audio_driver->stop != NULL ) {
   159         audio_driver->stop();
   160     }
   161 }
   163 /**
   164  * Set the output driver, sample rate and format. Also initializes the 
   165  * output buffers, flushing any current data and reallocating as 
   166  * necessary.
   167  */
   168 gboolean audio_set_driver( audio_driver_t driver )
   169 {
   170     uint32_t bytes_per_sample = 1;
   171     uint32_t samples_per_buffer;
   172     int i;
   174     if( audio_driver == NULL || driver != NULL ) {
   175         if( driver == NULL  )
   176             driver = &audio_null_driver;
   177         if( driver != audio_driver ) {	
   178             if( !driver->init() )
   179                 return FALSE;
   180             audio_driver = driver;
   181         }
   182     }
   184     switch( driver->sample_format & AUDIO_FMT_SAMPLE_MASK ) {
   185     case AUDIO_FMT_8BIT:
   186         bytes_per_sample = 1;
   187         break;
   188     case AUDIO_FMT_16BIT:
   189         bytes_per_sample = 2;
   190         break;
   191     case AUDIO_FMT_FLOAT:
   192         bytes_per_sample = 4;
   193         break;
   194     }
   196     if( driver->sample_format & AUDIO_FMT_STEREO )
   197         bytes_per_sample <<= 1;
   198     if( driver->sample_rate == audio.output_rate &&
   199             bytes_per_sample == audio.output_sample_size )
   200         return TRUE;
   201     samples_per_buffer = (driver->sample_rate * MS_PER_BUFFER / 1000);
   202     for( i=0; i<NUM_BUFFERS; i++ ) {
   203         if( audio.output_buffers[i] != NULL )
   204             free(audio.output_buffers[i]);
   205         audio.output_buffers[i] = g_malloc0( sizeof(struct audio_buffer) + samples_per_buffer * bytes_per_sample );
   206         audio.output_buffers[i]->length = samples_per_buffer * bytes_per_sample;
   207         audio.output_buffers[i]->posn = 0;
   208         audio.output_buffers[i]->status = BUFFER_EMPTY;
   209     }
   210     audio.output_format = driver->sample_format;
   211     audio.output_rate = driver->sample_rate;
   212     audio.output_sample_size = bytes_per_sample;
   213     audio.write_buffer = 0;
   214     audio.read_buffer = 0;
   216     return TRUE;
   217 }
   219 /**
   220  * Mark the current write buffer as full and prepare the next buffer for
   221  * writing. Returns the next buffer to write to.
   222  * If all buffers are full, returns NULL.
   223  */
   224 audio_buffer_t audio_next_write_buffer( )
   225 {
   226     audio_buffer_t result = NULL;
   227     audio_buffer_t current = audio.output_buffers[audio.write_buffer];
   228     current->status = BUFFER_FULL;
   229     if( audio.read_buffer == audio.write_buffer &&
   230             audio_driver->process_buffer( current ) ) {
   231         audio_next_read_buffer();
   232     }
   233     int next_buffer = NEXT_BUFFER();
   234     result = audio.output_buffers[next_buffer];
   235     if( result->status == BUFFER_FULL )
   236         return NULL;
   237     else {
   238         audio.write_buffer = next_buffer;
   239         result->status = BUFFER_WRITING;
   240         return result;
   241     }
   242 }
   244 /**
   245  * Mark the current read buffer as empty and return the next buffer for
   246  * reading. If there is no next buffer yet, returns NULL.
   247  */
   248 audio_buffer_t audio_next_read_buffer( )
   249 {
   250     audio_buffer_t current = audio.output_buffers[audio.read_buffer];
   251     if( current->status == BUFFER_FULL ) {
   252         // Current read buffer has data, which we've just emptied
   253         current->status = BUFFER_EMPTY;
   254         current->posn = 0;
   255         audio.read_buffer++;
   256         if( audio.read_buffer == NUM_BUFFERS )
   257             audio.read_buffer = 0;
   259         current = audio.output_buffers[audio.read_buffer];
   260         if( current->status == BUFFER_FULL ) {
   261             current->posn = 0;
   262             return current;
   263         }
   264         else return NULL;
   265     } else {
   266         return NULL;
   267     }
   269 }
   271 /*************************** ADPCM ***********************************/
   273 /**
   274  * The following section borrows heavily from ffmpeg, which is
   275  * copyright (c) 2001-2003 by the fine folks at the ffmpeg project,
   276  * distributed under the GPL version 2 or later.
   277  */
   279 #define CLAMP_TO_SHORT(value) \
   280     if (value > 32767) \
   281     value = 32767; \
   282     else if (value < -32768) \
   283     value = -32768; \
   285 static const int yamaha_indexscale[] = {
   286         230, 230, 230, 230, 307, 409, 512, 614,
   287         230, 230, 230, 230, 307, 409, 512, 614
   288 };
   290 static const int yamaha_difflookup[] = {
   291         1, 3, 5, 7, 9, 11, 13, 15,
   292         -1, -3, -5, -7, -9, -11, -13, -15
   293 };
   295 static inline short adpcm_yamaha_decode_nibble( audio_channel_t c, 
   296                                                 unsigned char nibble )
   297 {
   298     if( c->adpcm_step == 0 ) {
   299         c->adpcm_predict = 0;
   300         c->adpcm_step = 127;
   301     }
   303     c->adpcm_predict += (c->adpcm_step * yamaha_difflookup[nibble]) >> 3;
   304     CLAMP_TO_SHORT(c->adpcm_predict);
   305     c->adpcm_step = (c->adpcm_step * yamaha_indexscale[nibble]) >> 8;
   306     c->adpcm_step = CLAMP(c->adpcm_step, 127, 24567);
   307     return c->adpcm_predict;
   308 }
   310 /*************************** Sample mixer *****************************/
   312 /**
   313  * Mix a single output sample.
   314  */
   315 void audio_mix_samples( int num_samples )
   316 {
   317     int i, j;
   318     int32_t result_buf[num_samples][2];
   320     memset( &result_buf, 0, sizeof(result_buf) );
   322     for( i=0; i < AUDIO_CHANNEL_COUNT; i++ ) {
   323         audio_channel_t channel = &audio.channels[i];
   324         if( channel->active ) {
   325             int32_t sample;
   326             int vol_left = (channel->vol * (32 - channel->pan)) >> 5;
   327             int vol_right = (channel->vol * (channel->pan + 1)) >> 5;
   328             switch( channel->sample_format ) {
   329             case AUDIO_FMT_16BIT:
   330                 for( j=0; j<num_samples; j++ ) {
   331                     sample = *(int16_t *)(aica_main_ram + ((channel->start + channel->posn*2)&AUDIO_MEM_MASK));
   332                     result_buf[j][0] += sample * vol_left;
   333                     result_buf[j][1] += sample * vol_right;
   335                     channel->posn_left += channel->sample_rate;
   336                     while( channel->posn_left > audio.output_rate ) {
   337                         channel->posn_left -= audio.output_rate;
   338                         channel->posn++;
   340                         if( channel->posn == channel->end ) {
   341                             if( channel->loop ) {
   342                                 channel->posn = channel->loop_start;
   343                                 channel->loop = LOOP_LOOPED;
   344                             } else {
   345                                 audio_stop_channel(i);
   346                                 j = num_samples;
   347                                 break;
   348                             }
   349                         }
   350                     }
   351                 }
   352                 break;
   353             case AUDIO_FMT_8BIT:
   354                 for( j=0; j<num_samples; j++ ) {
   355                     sample = (*(int8_t *)(aica_main_ram + ((channel->start + channel->posn)&AUDIO_MEM_MASK))) << 8;
   356                     result_buf[j][0] += sample * vol_left;
   357                     result_buf[j][1] += sample * vol_right;
   359                     channel->posn_left += channel->sample_rate;
   360                     while( channel->posn_left > audio.output_rate ) {
   361                         channel->posn_left -= audio.output_rate;
   362                         channel->posn++;
   364                         if( channel->posn == channel->end ) {
   365                             if( channel->loop ) {
   366                                 channel->posn = channel->loop_start;
   367                                 channel->loop = LOOP_LOOPED;
   368                             } else {
   369                                 audio_stop_channel(i);
   370                                 j = num_samples;
   371                                 break;
   372                             }
   373                         }
   374                     }
   375                 }
   376                 break;
   377             case AUDIO_FMT_ADPCM:
   378                 for( j=0; j<num_samples; j++ ) {
   379                     sample = (int16_t)channel->adpcm_predict;
   380                     result_buf[j][0] += sample * vol_left;
   381                     result_buf[j][1] += sample * vol_right;
   382                     channel->posn_left += channel->sample_rate;
   383                     while( channel->posn_left > audio.output_rate ) {
   384                         channel->posn_left -= audio.output_rate;
   385                         channel->posn++;
   386                         if( channel->posn == channel->end ) {
   387                             if( channel->loop ) {
   388                                 channel->posn = channel->loop_start;
   389                                 channel->loop = LOOP_LOOPED;
   390                                 channel->adpcm_predict = 0;
   391                                 channel->adpcm_step = 0;
   392                             } else {
   393                                 audio_stop_channel(i);
   394                                 j = num_samples;
   395                                 break;
   396                             }
   397                         }
   398                         uint8_t data = *(uint8_t *)(aica_main_ram + ((channel->start + (channel->posn>>1))&AUDIO_MEM_MASK));
   399                         if( channel->posn&1 ) {
   400                             adpcm_yamaha_decode_nibble( channel, (data >> 4) & 0x0F );
   401                         } else {
   402                             adpcm_yamaha_decode_nibble( channel, data & 0x0F );
   403                         }
   404                     }
   405                 }
   406                 break;
   407             default:
   408                 break;
   409             }
   410         }
   411     }
   413     /* Down-render to the final output format */
   414     audio_buffer_t buf = audio.output_buffers[audio.write_buffer];
   415     if( buf->status == BUFFER_FULL ) {
   416         buf = audio_next_write_buffer();
   417         if( buf == NULL ) { // no available space
   418             return;
   419         }
   420     }
   422     switch( audio.output_format & AUDIO_FMT_SAMPLE_MASK ) {
   423     case AUDIO_FMT_FLOAT: {
   424         float scale = 1.0/SHRT_MAX;
   425         float *data = (float *)&buf->data[buf->posn];
   426         for( j=0; j<num_samples; j++ ) {
   427             *data++ = scale * (result_buf[j][0] >> 6);
   428             *data++ = scale * (result_buf[j][1] >> 6);
   429             buf->posn += 8;
   430             if( buf->posn == buf->length ) {
   431                 buf = audio_next_write_buffer();
   432                 if( buf == NULL ) {
   433                     break;
   434                 }
   435                 data = (float *)&buf->data[0];
   436             }
   437         }
   438         break;
   439     }
   440     case AUDIO_FMT_16BIT: {
   441         int16_t *data = (int16_t *)&buf->data[buf->posn];
   442         for( j=0; j < num_samples; j++ ) {
   443             *data++ = (int16_t)(result_buf[j][0] >> 6);
   444             *data++ = (int16_t)(result_buf[j][1] >> 6);	
   445             buf->posn += 4;
   446             if( buf->posn == buf->length ) {
   447                 buf = audio_next_write_buffer();
   448                 if( buf == NULL ) {
   449                     // All buffers are full
   450                     break;
   451                 }
   452                 data = (int16_t *)&buf->data[0];
   453             }
   454         }
   455         break;
   456     }
   457     case AUDIO_FMT_8BIT: {
   458         int8_t *data = (int8_t *)&buf->data[buf->posn];
   459         for( j=0; j < num_samples; j++ ) {
   460             *data++ = (int8_t)(result_buf[j][0] >> 16);
   461             *data++ = (int8_t)(result_buf[j][1] >> 16);	
   462             buf->posn += 2;
   463             if( buf->posn == buf->length ) {
   464                 buf = audio_next_write_buffer();
   465                 if( buf == NULL ) {
   466                     // All buffers are full
   467                     break;
   468                 }
   469                 buf = audio.output_buffers[audio.write_buffer];
   470                 data = (int8_t *)&buf->data[0];
   471             }
   472         }
   473         break;
   474     }
   475     }
   476 }
   478 /********************** Internal AICA calls ***************************/
   480 audio_channel_t audio_get_channel( int channel ) 
   481 {
   482     return &audio.channels[channel];
   483 }
   485 void audio_start_stop_channel( int channel, gboolean start )
   486 {
   487     if( audio.channels[channel].active ) {
   488         if( !start ) {
   489             audio_stop_channel(channel);
   490         }
   491     } else if( start ) {
   492         audio_start_channel(channel);
   493     }
   494 }
   496 void audio_stop_channel( int channel ) 
   497 {
   498     audio.channels[channel].active = FALSE;
   499 }
   502 void audio_start_channel( int channel )
   503 {
   504     audio.channels[channel].posn = 0;
   505     audio.channels[channel].posn_left = 0;
   506     audio.channels[channel].active = TRUE;
   507     if( audio.channels[channel].sample_format == AUDIO_FMT_ADPCM ) {
   508         audio.channels[channel].adpcm_step = 0;
   509         audio.channels[channel].adpcm_predict = 0;
   510         uint8_t data = ((uint8_t *)(aica_main_ram + audio.channels[channel].start))[0];
   511         adpcm_yamaha_decode_nibble( &audio.channels[channel], data & 0x0F );
   512     }
   513 }
.