Search
lxdream.org :: lxdream/src/aica/audio.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/aica/audio.c
changeset 759:f16975739abc
prev736:a02d1475ccfd
next779:a60e47313e7b
author nkeynes
date Mon Jul 21 01:01:39 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Fix batch of -Wall warnings
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_driver = &audio_null_driver;
   122         audio_set_driver( &audio_null_driver );
   123     }
   124     return audio_driver;
   125 }
   127 /**
   128  * Set the output driver, sample rate and format. Also initializes the 
   129  * output buffers, flushing any current data and reallocating as 
   130  * necessary.
   131  */
   132 gboolean audio_set_driver( audio_driver_t driver )
   133 {
   134     uint32_t bytes_per_sample = 1;
   135     uint32_t samples_per_buffer;
   136     int i;
   138     if( audio_driver == NULL || driver != NULL ) {
   139         if( driver == NULL  )
   140             driver = &audio_null_driver;
   141         if( driver != audio_driver ) {	
   142             if( !driver->init() )
   143                 return FALSE;
   144             audio_driver = driver;
   145         }
   146     }
   148     switch( driver->sample_format & AUDIO_FMT_SAMPLE_MASK ) {
   149     case AUDIO_FMT_8BIT:
   150         bytes_per_sample = 1;
   151         break;
   152     case AUDIO_FMT_16BIT:
   153         bytes_per_sample = 2;
   154         break;
   155     case AUDIO_FMT_FLOAT:
   156         bytes_per_sample = 4;
   157         break;
   158     }
   160     if( driver->sample_format & AUDIO_FMT_STEREO )
   161         bytes_per_sample <<= 1;
   162     if( driver->sample_rate == audio.output_rate &&
   163             bytes_per_sample == audio.output_sample_size )
   164         return TRUE;
   165     samples_per_buffer = (driver->sample_rate * MS_PER_BUFFER / 1000);
   166     for( i=0; i<NUM_BUFFERS; i++ ) {
   167         if( audio.output_buffers[i] != NULL )
   168             free(audio.output_buffers[i]);
   169         audio.output_buffers[i] = g_malloc0( sizeof(struct audio_buffer) + samples_per_buffer * bytes_per_sample );
   170         audio.output_buffers[i]->length = samples_per_buffer * bytes_per_sample;
   171         audio.output_buffers[i]->posn = 0;
   172         audio.output_buffers[i]->status = BUFFER_EMPTY;
   173     }
   174     audio.output_format = driver->sample_format;
   175     audio.output_rate = driver->sample_rate;
   176     audio.output_sample_size = bytes_per_sample;
   177     audio.write_buffer = 0;
   178     audio.read_buffer = 0;
   180     return TRUE;
   181 }
   183 /**
   184  * Mark the current write buffer as full and prepare the next buffer for
   185  * writing. Returns the next buffer to write to.
   186  * If all buffers are full, returns NULL.
   187  */
   188 audio_buffer_t audio_next_write_buffer( )
   189 {
   190     audio_buffer_t result = NULL;
   191     audio_buffer_t current = audio.output_buffers[audio.write_buffer];
   192     current->status = BUFFER_FULL;
   193     if( audio.read_buffer == audio.write_buffer &&
   194             audio_driver->process_buffer( current ) ) {
   195         audio_next_read_buffer();
   196     }
   197     int next_buffer = NEXT_BUFFER();
   198     result = audio.output_buffers[next_buffer];
   199     if( result->status == BUFFER_FULL )
   200         return NULL;
   201     else {
   202         audio.write_buffer = next_buffer;
   203         result->status = BUFFER_WRITING;
   204         return result;
   205     }
   206 }
   208 /**
   209  * Mark the current read buffer as empty and return the next buffer for
   210  * reading. If there is no next buffer yet, returns NULL.
   211  */
   212 audio_buffer_t audio_next_read_buffer( )
   213 {
   214     audio_buffer_t current = audio.output_buffers[audio.read_buffer];
   215     if( current->status == BUFFER_FULL ) {
   216         // Current read buffer has data, which we've just emptied
   217         current->status = BUFFER_EMPTY;
   218         current->posn = 0;
   219         audio.read_buffer++;
   220         if( audio.read_buffer == NUM_BUFFERS )
   221             audio.read_buffer = 0;
   223         current = audio.output_buffers[audio.read_buffer];
   224         if( current->status == BUFFER_FULL ) {
   225             current->posn = 0;
   226             return current;
   227         }
   228         else return NULL;
   229     } else {
   230         return NULL;
   231     }
   233 }
   235 /*************************** ADPCM ***********************************/
   237 /**
   238  * The following section borrows heavily from ffmpeg, which is
   239  * copyright (c) 2001-2003 by the fine folks at the ffmpeg project,
   240  * distributed under the GPL version 2 or later.
   241  */
   243 #define CLAMP_TO_SHORT(value) \
   244     if (value > 32767) \
   245     value = 32767; \
   246     else if (value < -32768) \
   247     value = -32768; \
   249 static const int yamaha_indexscale[] = {
   250         230, 230, 230, 230, 307, 409, 512, 614,
   251         230, 230, 230, 230, 307, 409, 512, 614
   252 };
   254 static const int yamaha_difflookup[] = {
   255         1, 3, 5, 7, 9, 11, 13, 15,
   256         -1, -3, -5, -7, -9, -11, -13, -15
   257 };
   259 static inline short adpcm_yamaha_decode_nibble( audio_channel_t c, 
   260                                                 unsigned char nibble )
   261 {
   262     if( c->adpcm_step == 0 ) {
   263         c->adpcm_predict = 0;
   264         c->adpcm_step = 127;
   265     }
   267     c->adpcm_predict += (c->adpcm_step * yamaha_difflookup[nibble]) >> 3;
   268     CLAMP_TO_SHORT(c->adpcm_predict);
   269     c->adpcm_step = (c->adpcm_step * yamaha_indexscale[nibble]) >> 8;
   270     c->adpcm_step = CLAMP(c->adpcm_step, 127, 24567);
   271     return c->adpcm_predict;
   272 }
   274 /*************************** Sample mixer *****************************/
   276 /**
   277  * Mix a single output sample.
   278  */
   279 void audio_mix_samples( int num_samples )
   280 {
   281     int i, j;
   282     int32_t result_buf[num_samples][2];
   284     memset( &result_buf, 0, sizeof(result_buf) );
   286     for( i=0; i < AUDIO_CHANNEL_COUNT; i++ ) {
   287         audio_channel_t channel = &audio.channels[i];
   288         if( channel->active ) {
   289             int32_t sample;
   290             int vol_left = (channel->vol * (32 - channel->pan)) >> 5;
   291             int vol_right = (channel->vol * (channel->pan + 1)) >> 5;
   292             switch( channel->sample_format ) {
   293             case AUDIO_FMT_16BIT:
   294                 for( j=0; j<num_samples; j++ ) {
   295                     sample = ((int16_t *)(arm_mem + channel->start))[channel->posn];
   296                     result_buf[j][0] += sample * vol_left;
   297                     result_buf[j][1] += sample * vol_right;
   299                     channel->posn_left += channel->sample_rate;
   300                     while( channel->posn_left > audio.output_rate ) {
   301                         channel->posn_left -= audio.output_rate;
   302                         channel->posn++;
   304                         if( channel->posn == channel->end ) {
   305                             if( channel->loop ) {
   306                                 channel->posn = channel->loop_start;
   307                                 channel->loop = LOOP_LOOPED;
   308                             } else {
   309                                 audio_stop_channel(i);
   310                                 j = num_samples;
   311                                 break;
   312                             }
   313                         }
   314                     }
   315                 }
   316                 break;
   317             case AUDIO_FMT_8BIT:
   318                 for( j=0; j<num_samples; j++ ) {
   319                     sample = ((int8_t *)(arm_mem + channel->start))[channel->posn] << 8;
   320                     result_buf[j][0] += sample * vol_left;
   321                     result_buf[j][1] += sample * vol_right;
   323                     channel->posn_left += channel->sample_rate;
   324                     while( channel->posn_left > audio.output_rate ) {
   325                         channel->posn_left -= audio.output_rate;
   326                         channel->posn++;
   328                         if( channel->posn == channel->end ) {
   329                             if( channel->loop ) {
   330                                 channel->posn = channel->loop_start;
   331                                 channel->loop = LOOP_LOOPED;
   332                             } else {
   333                                 audio_stop_channel(i);
   334                                 j = num_samples;
   335                                 break;
   336                             }
   337                         }
   338                     }
   339                 }
   340                 break;
   341             case AUDIO_FMT_ADPCM:
   342                 for( j=0; j<num_samples; j++ ) {
   343                     sample = (int16_t)channel->adpcm_predict;
   344                     result_buf[j][0] += sample * vol_left;
   345                     result_buf[j][1] += sample * vol_right;
   346                     channel->posn_left += channel->sample_rate;
   347                     while( channel->posn_left > audio.output_rate ) {
   348                         channel->posn_left -= audio.output_rate;
   349                         channel->posn++;
   350                         if( channel->posn == channel->end ) {
   351                             if( channel->loop ) {
   352                                 channel->posn = channel->loop_start;
   353                                 channel->loop = LOOP_LOOPED;
   354                                 channel->adpcm_predict = 0;
   355                                 channel->adpcm_step = 0;
   356                             } else {
   357                                 audio_stop_channel(i);
   358                                 j = num_samples;
   359                                 break;
   360                             }
   361                         }
   362                         uint8_t data = ((uint8_t *)(arm_mem + channel->start))[channel->posn>>1];
   363                         if( channel->posn&1 ) {
   364                             adpcm_yamaha_decode_nibble( channel, (data >> 4) & 0x0F );
   365                         } else {
   366                             adpcm_yamaha_decode_nibble( channel, data & 0x0F );
   367                         }
   368                     }
   369                 }
   370                 break;
   371             default:
   372                 break;
   373             }
   374         }
   375     }
   377     /* Down-render to the final output format */
   378     audio_buffer_t buf = audio.output_buffers[audio.write_buffer];
   379     if( buf->status == BUFFER_FULL ) {
   380         buf = audio_next_write_buffer();
   381         if( buf == NULL ) { // no available space
   382             return;
   383         }
   384     }
   386     switch( audio.output_format & AUDIO_FMT_SAMPLE_MASK ) {
   387     case AUDIO_FMT_FLOAT: {
   388         float scale = 1.0/SHRT_MAX;
   389         float *data = (float *)&buf->data[buf->posn];
   390         for( j=0; j<num_samples; j++ ) {
   391             *data++ = scale * (result_buf[j][0] >> 6);
   392             *data++ = scale * (result_buf[j][1] >> 6);
   393             buf->posn += 8;
   394             if( buf->posn == buf->length ) {
   395                 buf = audio_next_write_buffer();
   396                 if( buf == NULL ) {
   397                     break;
   398                 }
   399                 data = (float *)&buf->data[0];
   400             }
   401         }
   402         break;
   403     }
   404     case AUDIO_FMT_16BIT: {
   405         int16_t *data = (int16_t *)&buf->data[buf->posn];
   406         for( j=0; j < num_samples; j++ ) {
   407             *data++ = (int16_t)(result_buf[j][0] >> 6);
   408             *data++ = (int16_t)(result_buf[j][1] >> 6);	
   409             buf->posn += 4;
   410             if( buf->posn == buf->length ) {
   411                 buf = audio_next_write_buffer();
   412                 if( buf == NULL ) {
   413                     // All buffers are full
   414                     break;
   415                 }
   416                 data = (int16_t *)&buf->data[0];
   417             }
   418         }
   419         break;
   420     }
   421     case AUDIO_FMT_8BIT: {
   422         int8_t *data = (int8_t *)&buf->data[buf->posn];
   423         for( j=0; j < num_samples; j++ ) {
   424             *data++ = (int8_t)(result_buf[j][0] >> 16);
   425             *data++ = (int8_t)(result_buf[j][1] >> 16);	
   426             buf->posn += 2;
   427             if( buf->posn == buf->length ) {
   428                 buf = audio_next_write_buffer();
   429                 if( buf == NULL ) {
   430                     // All buffers are full
   431                     break;
   432                 }
   433                 buf = audio.output_buffers[audio.write_buffer];
   434                 data = (int8_t *)&buf->data[0];
   435             }
   436         }
   437         break;
   438     }
   439     }
   440 }
   442 /********************** Internal AICA calls ***************************/
   444 audio_channel_t audio_get_channel( int channel ) 
   445 {
   446     return &audio.channels[channel];
   447 }
   449 void audio_start_stop_channel( int channel, gboolean start )
   450 {
   451     if( audio.channels[channel].active ) {
   452         if( !start ) {
   453             audio_stop_channel(channel);
   454         }
   455     } else if( start ) {
   456         audio_start_channel(channel);
   457     }
   458 }
   460 void audio_stop_channel( int channel ) 
   461 {
   462     audio.channels[channel].active = FALSE;
   463 }
   466 void audio_start_channel( int channel )
   467 {
   468     audio.channels[channel].posn = 0;
   469     audio.channels[channel].posn_left = 0;
   470     audio.channels[channel].active = TRUE;
   471     if( audio.channels[channel].sample_format == AUDIO_FMT_ADPCM ) {
   472         audio.channels[channel].adpcm_step = 0;
   473         audio.channels[channel].adpcm_predict = 0;
   474         uint8_t data = ((uint8_t *)(arm_mem + audio.channels[channel].start))[0];
   475         adpcm_yamaha_decode_nibble( &audio.channels[channel], data & 0x0F );
   476     }
   477 }
.