Search
lxdream.org :: lxdream/src/aica/audio.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/audio.c
changeset 700:4650d0c7f6f9
prev697:479b8c213f61
next736:a02d1475ccfd
author nkeynes
date Mon Jul 14 00:09:51 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Fix version number in configure.in
Remove obsolete x86_64 AM conditional
Add --disable-translator option for testing purposes
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>
    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;
    34 audio_driver_t audio_driver_list[] = {
    35 #ifdef HAVE_CORE_AUDIO
    36       &audio_osx_driver,
    37 #endif
    38 #ifdef HAVE_PULSE
    39       &audio_pulse_driver,
    40 #endif
    41 #ifdef HAVE_ESOUND
    42       &audio_esd_driver,
    43 #endif
    44 #ifdef HAVE_ALSA
    45       &audio_alsa_driver,
    46 #endif
    47       &audio_null_driver,
    48       NULL };
    50 #define NUM_BUFFERS 3
    51 #define MS_PER_BUFFER 100
    53 #define BUFFER_EMPTY   0
    54 #define BUFFER_WRITING 1
    55 #define BUFFER_FULL    2
    57 struct audio_state {
    58     audio_buffer_t output_buffers[NUM_BUFFERS];
    59     int write_buffer;
    60     int read_buffer;
    61     uint32_t output_format;
    62     uint32_t output_rate;
    63     uint32_t output_sample_size;
    64     struct audio_channel channels[AUDIO_CHANNEL_COUNT];
    65 } audio;
    67 audio_driver_t audio_driver = NULL;
    69 #define NEXT_BUFFER() ((audio.write_buffer == NUM_BUFFERS-1) ? 0 : audio.write_buffer+1)
    71 extern char *arm_mem;
    73 /**
    74  * Preserve audio channel state only - don't bother saving the buffers
    75  */
    76 void audio_save_state( FILE *f )
    77 {
    78     fwrite( &audio.channels[0], sizeof(struct audio_channel), AUDIO_CHANNEL_COUNT, f );
    79 }
    81 int audio_load_state( FILE *f )
    82 {
    83     int read = fread( &audio.channels[0], sizeof(struct audio_channel), AUDIO_CHANNEL_COUNT, f );
    84     return (read == AUDIO_CHANNEL_COUNT ? 0 : -1 );
    85 }
    87 audio_driver_t get_audio_driver_by_name( const char *name )
    88 {
    89     int i;
    90     if( name == NULL ) {
    91         return audio_driver_list[0];
    92     }
    93     for( i=0; audio_driver_list[i] != NULL; i++ ) {
    94         if( strcasecmp( audio_driver_list[i]->name, name ) == 0 ) {
    95             return audio_driver_list[i];
    96         }
    97     }
    99     return NULL;
   100 }
   102 void print_audio_drivers( FILE * out )
   103 {
   104     int i;
   105     fprintf( out, "Available audio drivers:\n" );
   106     for( i=0; audio_driver_list[i] != NULL; i++ ) {
   107         fprintf( out, "  %-8s %s\n", audio_driver_list[i]->name,
   108                  gettext(audio_driver_list[i]->description) );
   109     }
   110 }
   112 audio_driver_t audio_init_driver( const char *preferred_driver )
   113 {
   114     audio_driver_t audio_driver = get_audio_driver_by_name(preferred_driver);
   115     if( audio_driver == NULL ) {
   116         ERROR( "Audio driver '%s' not found, aborting.", preferred_driver );
   117         exit(2);
   118     } else if( audio_set_driver( audio_driver ) == FALSE ) {
   119         ERROR( "Failed to initialize audio driver '%s', using null driver", 
   120                 audio_driver->name );
   121         audio_set_driver( &audio_null_driver );
   122     }    
   123 }
   125 /**
   126  * Set the output driver, sample rate and format. Also initializes the 
   127  * output buffers, flushing any current data and reallocating as 
   128  * necessary.
   129  */
   130 gboolean audio_set_driver( audio_driver_t driver )
   131 {
   132     uint32_t bytes_per_sample = 1;
   133     uint32_t samples_per_buffer;
   134     int i;
   136     if( audio_driver == NULL || driver != NULL ) {
   137         if( driver == NULL  )
   138             driver = &audio_null_driver;
   139         if( driver != audio_driver ) {	
   140             if( !driver->init() )
   141                 return FALSE;
   142             audio_driver = driver;
   143         }
   144     }
   146     switch( driver->sample_format & AUDIO_FMT_SAMPLE_MASK ) {
   147     case AUDIO_FMT_8BIT:
   148         bytes_per_sample = 1;
   149         break;
   150     case AUDIO_FMT_16BIT:
   151         bytes_per_sample = 2;
   152         break;
   153     case AUDIO_FMT_FLOAT:
   154         bytes_per_sample = 4;
   155         break;
   156     }
   158     if( driver->sample_format & AUDIO_FMT_STEREO )
   159         bytes_per_sample <<= 1;
   160     if( driver->sample_rate == audio.output_rate &&
   161             bytes_per_sample == audio.output_sample_size )
   162         return TRUE;
   163     samples_per_buffer = (driver->sample_rate * MS_PER_BUFFER / 1000);
   164     for( i=0; i<NUM_BUFFERS; i++ ) {
   165         if( audio.output_buffers[i] != NULL )
   166             free(audio.output_buffers[i]);
   167         audio.output_buffers[i] = g_malloc0( sizeof(struct audio_buffer) + samples_per_buffer * bytes_per_sample );
   168         audio.output_buffers[i]->length = samples_per_buffer * bytes_per_sample;
   169         audio.output_buffers[i]->posn = 0;
   170         audio.output_buffers[i]->status = BUFFER_EMPTY;
   171     }
   172     audio.output_format = driver->sample_format;
   173     audio.output_rate = driver->sample_rate;
   174     audio.output_sample_size = bytes_per_sample;
   175     audio.write_buffer = 0;
   176     audio.read_buffer = 0;
   178     return TRUE;
   179 }
   181 /**
   182  * Mark the current write buffer as full and prepare the next buffer for
   183  * writing. Returns the next buffer to write to.
   184  * If all buffers are full, returns NULL.
   185  */
   186 audio_buffer_t audio_next_write_buffer( )
   187 {
   188     audio_buffer_t result = NULL;
   189     audio_buffer_t current = audio.output_buffers[audio.write_buffer];
   190     current->status = BUFFER_FULL;
   191     if( audio.read_buffer == audio.write_buffer &&
   192             audio_driver->process_buffer( current ) ) {
   193         audio_next_read_buffer();
   194     }
   195     int next_buffer = NEXT_BUFFER();
   196     result = audio.output_buffers[next_buffer];
   197     if( result->status == BUFFER_FULL )
   198         return NULL;
   199     else {
   200         audio.write_buffer = next_buffer;
   201         result->status = BUFFER_WRITING;
   202         return result;
   203     }
   204 }
   206 /**
   207  * Mark the current read buffer as empty and return the next buffer for
   208  * reading. If there is no next buffer yet, returns NULL.
   209  */
   210 audio_buffer_t audio_next_read_buffer( )
   211 {
   212     audio_buffer_t current = audio.output_buffers[audio.read_buffer];
   213     if( current->status == BUFFER_FULL ) {
   214         // Current read buffer has data, which we've just emptied
   215         current->status = BUFFER_EMPTY;
   216         current->posn = 0;
   217         audio.read_buffer++;
   218         if( audio.read_buffer == NUM_BUFFERS )
   219             audio.read_buffer = 0;
   221         current = audio.output_buffers[audio.read_buffer];
   222         if( current->status == BUFFER_FULL ) {
   223             current->posn = 0;
   224             return current;
   225         }
   226         else return NULL;
   227     } else {
   228         return NULL;
   229     }
   231 }
   233 /*************************** ADPCM ***********************************/
   235 /**
   236  * The following section borrows heavily from ffmpeg, which is
   237  * copyright (c) 2001-2003 by the fine folks at the ffmpeg project,
   238  * distributed under the GPL version 2 or later.
   239  */
   241 #define CLAMP_TO_SHORT(value) \
   242 if (value > 32767) \
   243     value = 32767; \
   244 else if (value < -32768) \
   245     value = -32768; \
   247 static const int yamaha_indexscale[] = {
   248     230, 230, 230, 230, 307, 409, 512, 614,
   249     230, 230, 230, 230, 307, 409, 512, 614
   250 };
   252 static const int yamaha_difflookup[] = {
   253     1, 3, 5, 7, 9, 11, 13, 15,
   254     -1, -3, -5, -7, -9, -11, -13, -15
   255 };
   257 static inline short adpcm_yamaha_decode_nibble( audio_channel_t c, 
   258 						unsigned char nibble )
   259 {
   260     if( c->adpcm_step == 0 ) {
   261         c->adpcm_predict = 0;
   262         c->adpcm_step = 127;
   263     }
   265     c->adpcm_predict += (c->adpcm_step * yamaha_difflookup[nibble]) >> 3;
   266     CLAMP_TO_SHORT(c->adpcm_predict);
   267     c->adpcm_step = (c->adpcm_step * yamaha_indexscale[nibble]) >> 8;
   268     c->adpcm_step = CLAMP(c->adpcm_step, 127, 24567);
   269     return c->adpcm_predict;
   270 }
   272 /*************************** Sample mixer *****************************/
   274 /**
   275  * Mix a single output sample.
   276  */
   277 void audio_mix_samples( int num_samples )
   278 {
   279     int i, j;
   280     int32_t result_buf[num_samples][2];
   282     memset( &result_buf, 0, sizeof(result_buf) );
   284     for( i=0; i < AUDIO_CHANNEL_COUNT; i++ ) {
   285         audio_channel_t channel = &audio.channels[i];
   286         if( channel->active ) {
   287             int32_t sample;
   288             int vol_left = (channel->vol * (32 - channel->pan)) >> 5;
   289             int vol_right = (channel->vol * (channel->pan + 1)) >> 5;
   290             switch( channel->sample_format ) {
   291             case AUDIO_FMT_16BIT:
   292                 for( j=0; j<num_samples; j++ ) {
   293                     sample = ((int16_t *)(arm_mem + channel->start))[channel->posn];
   294                     result_buf[j][0] += sample * vol_left;
   295                     result_buf[j][1] += sample * vol_right;
   297                     channel->posn_left += channel->sample_rate;
   298                     while( channel->posn_left > audio.output_rate ) {
   299                         channel->posn_left -= audio.output_rate;
   300                         channel->posn++;
   302                         if( channel->posn == channel->end ) {
   303                             if( channel->loop ) {
   304                                 channel->posn = channel->loop_start;
   305                                 channel->loop = LOOP_LOOPED;
   306                             } else {
   307                                 audio_stop_channel(i);
   308                                 j = num_samples;
   309                                 break;
   310                             }
   311                         }
   312                     }
   313                 }
   314                 break;
   315             case AUDIO_FMT_8BIT:
   316                 for( j=0; j<num_samples; j++ ) {
   317                     sample = ((int8_t *)(arm_mem + channel->start))[channel->posn] << 8;
   318                     result_buf[j][0] += sample * vol_left;
   319                     result_buf[j][1] += sample * vol_right;
   321                     channel->posn_left += channel->sample_rate;
   322                     while( channel->posn_left > audio.output_rate ) {
   323                         channel->posn_left -= audio.output_rate;
   324                         channel->posn++;
   326                         if( channel->posn == channel->end ) {
   327                             if( channel->loop ) {
   328                                 channel->posn = channel->loop_start;
   329                                 channel->loop = LOOP_LOOPED;
   330                             } else {
   331                                 audio_stop_channel(i);
   332                                 j = num_samples;
   333                                 break;
   334                             }
   335                         }
   336                     }
   337                 }
   338                 break;
   339             case AUDIO_FMT_ADPCM:
   340                 for( j=0; j<num_samples; j++ ) {
   341                     sample = (int16_t)channel->adpcm_predict;
   342                     result_buf[j][0] += sample * vol_left;
   343                     result_buf[j][1] += sample * vol_right;
   344                     channel->posn_left += channel->sample_rate;
   345                     while( channel->posn_left > audio.output_rate ) {
   346                         channel->posn_left -= audio.output_rate;
   347                         channel->posn++;
   348                         if( channel->posn == channel->end ) {
   349                             if( channel->loop ) {
   350                                 channel->posn = channel->loop_start;
   351                                 channel->loop = LOOP_LOOPED;
   352                                 channel->adpcm_predict = 0;
   353                                 channel->adpcm_step = 0;
   354                             } else {
   355                                 audio_stop_channel(i);
   356                                 j = num_samples;
   357                                 break;
   358                             }
   359                         }
   360                         uint8_t data = ((uint8_t *)(arm_mem + channel->start))[channel->posn>>1];
   361                         if( channel->posn&1 ) {
   362                             adpcm_yamaha_decode_nibble( channel, (data >> 4) & 0x0F );
   363                         } else {
   364                             adpcm_yamaha_decode_nibble( channel, data & 0x0F );
   365                         }
   366                     }
   367                 }
   368                 break;
   369             default:
   370                 break;
   371             }
   372         }
   373     }
   375     /* Down-render to the final output format */
   376     audio_buffer_t buf = audio.output_buffers[audio.write_buffer];
   377     if( buf->status == BUFFER_FULL ) {
   378         buf = audio_next_write_buffer();
   379         if( buf == NULL ) { // no available space
   380             return;
   381         }
   382     }
   384     switch( audio.output_format & AUDIO_FMT_SAMPLE_MASK ) {
   385     case AUDIO_FMT_FLOAT: {
   386         float scale = 1.0/SHRT_MAX;
   387         float *data = (float *)&buf->data[buf->posn];
   388         for( j=0; j<num_samples; j++ ) {
   389             *data++ = scale * (result_buf[j][0] >> 6);
   390             *data++ = scale * (result_buf[j][1] >> 6);
   391             buf->posn += 8;
   392             if( buf->posn == buf->length ) {
   393                 buf = audio_next_write_buffer();
   394                 if( buf == NULL ) {
   395                     break;
   396                 }
   397                 data = (float *)&buf->data[0];
   398             }
   399         }
   400         break;
   401     }
   402     case AUDIO_FMT_16BIT: {
   403         int16_t *data = (int16_t *)&buf->data[buf->posn];
   404         for( j=0; j < num_samples; j++ ) {
   405             *data++ = (int16_t)(result_buf[j][0] >> 6);
   406             *data++ = (int16_t)(result_buf[j][1] >> 6);	
   407             buf->posn += 4;
   408             if( buf->posn == buf->length ) {
   409                 buf = audio_next_write_buffer();
   410                 if( buf == NULL ) {
   411                     // All buffers are full
   412                     break;
   413                 }
   414                 data = (int16_t *)&buf->data[0];
   415             }
   416         }
   417         break;
   418     }
   419     case AUDIO_FMT_8BIT: {
   420         int8_t *data = (int8_t *)&buf->data[buf->posn];
   421         for( j=0; j < num_samples; j++ ) {
   422             *data++ = (int8_t)(result_buf[j][0] >> 16);
   423             *data++ = (int8_t)(result_buf[j][1] >> 16);	
   424             buf->posn += 2;
   425             if( buf->posn == buf->length ) {
   426                 buf = audio_next_write_buffer();
   427                 if( buf == NULL ) {
   428                     // All buffers are full
   429                     break;
   430                 }
   431                 buf = audio.output_buffers[audio.write_buffer];
   432                 data = (int8_t *)&buf->data[0];
   433             }
   434         }
   435         break;
   436     }
   437     }
   438 }
   440 /********************** Internal AICA calls ***************************/
   442 audio_channel_t audio_get_channel( int channel ) 
   443 {
   444     return &audio.channels[channel];
   445 }
   447 void audio_start_stop_channel( int channel, gboolean start )
   448 {
   449     if( audio.channels[channel].active ) {
   450 	if( !start ) {
   451 	    audio_stop_channel(channel);
   452 	}
   453     } else if( start ) {
   454 	audio_start_channel(channel);
   455     }
   456 }
   458 void audio_stop_channel( int channel ) 
   459 {
   460     audio.channels[channel].active = FALSE;
   461 }
   464 void audio_start_channel( int channel )
   465 {
   466     audio.channels[channel].posn = 0;
   467     audio.channels[channel].posn_left = 0;
   468     audio.channels[channel].active = TRUE;
   469     if( audio.channels[channel].sample_format == AUDIO_FMT_ADPCM ) {
   470 	audio.channels[channel].adpcm_step = 0;
   471 	audio.channels[channel].adpcm_predict = 0;
   472 	uint8_t data = ((uint8_t *)(arm_mem + audio.channels[channel].start))[0];
   473 	adpcm_yamaha_decode_nibble( &audio.channels[channel], data & 0x0F );
   474     }
   475 }
.