Engine/lib/sdl/src/audio/SDL_audiocvt.c
/* Creates a set of audio filters to convert from one format to another.
   Returns -1 if the format conversion is not supported, 0 if there's
   no conversion needed, or 1 if the audio filter is set up.
*/
Creates a set of audio filters to convert from one format to another.
Returns -1 if the format conversion is not supported, 0 if there's
no conversion needed, or 1 if the audio filter is set up.
Creates a set of audio filters to convert from one format to another . Returns - 1 if the format conversion is not supported 0 if there ' s no conversion needed or 1 if the audio filter is set up .
int
SDL_BuildAudioCVT(SDL_AudioCVT * cvt,
                  SDL_AudioFormat src_fmt, Uint8 src_channels, int src_rate,
                  SDL_AudioFormat dst_fmt, Uint8 dst_channels, int dst_rate)
{
    if (cvt == NULL) {
        return SDL_InvalidParamError("cvt");
    }
    if ((SDL_AUDIO_BITSIZE(src_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(src_fmt))) {
        return SDL_SetError("Invalid source format");
    }
    if ((SDL_AUDIO_BITSIZE(dst_fmt) > 16) && (!SDL_AUDIO_ISSIGNED(dst_fmt))) {
        return SDL_SetError("Invalid destination format");
    }
    if ((src_channels == 0) || (dst_channels == 0)) {
        return SDL_SetError("Source or destination channels is zero");
    }
    if ((src_rate == 0) || (dst_rate == 0)) {
        return SDL_SetError("Source or destination rate is zero");
    }
#ifdef DEBUG_CONVERT
    printf("Build format %04x->%04x, channels %u->%u, rate %d->%d\n",
           src_fmt, dst_fmt, src_channels, dst_channels, src_rate, dst_rate);
#endif
    SDL_zerop(cvt);
    cvt->src_format = src_fmt;
    cvt->dst_format = dst_fmt;
    cvt->needed = 0;
    cvt->filter_index = 0;
    cvt->filters[0] = NULL;
    cvt->len_mult = 1;
    cvt->len_ratio = 1.0;
    cvt->rate_incr = ((double) dst_rate) / ((double) src_rate);
    if (SDL_BuildAudioTypeCVT(cvt, src_fmt, dst_fmt) == -1) {
        return -1;              
    }
    if (src_channels != dst_channels) {
        if ((src_channels == 1) && (dst_channels > 1)) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
            cvt->len_mult *= 2;
            src_channels = 2;
            cvt->len_ratio *= 2;
        }
        if ((src_channels == 2) && (dst_channels == 6)) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertSurround;
            src_channels = 6;
            cvt->len_mult *= 3;
            cvt->len_ratio *= 3;
        }
        if ((src_channels == 2) && (dst_channels == 4)) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertSurround_4;
            src_channels = 4;
            cvt->len_mult *= 2;
            cvt->len_ratio *= 2;
        }
        while ((src_channels * 2) <= dst_channels) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertStereo;
            cvt->len_mult *= 2;
            src_channels *= 2;
            cvt->len_ratio *= 2;
        }
        if ((src_channels == 6) && (dst_channels <= 2)) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertStrip;
            src_channels = 2;
            cvt->len_ratio /= 3;
        }
        if ((src_channels == 6) && (dst_channels == 4)) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertStrip_2;
            src_channels = 4;
            cvt->len_ratio /= 2;
        }
        while (((src_channels % 2) == 0) &&
               ((src_channels / 2) >= dst_channels)) {
            cvt->filters[cvt->filter_index++] = SDL_ConvertMono;
            src_channels /= 2;
            cvt->len_ratio /= 2;
        }
        if (src_channels != dst_channels) {
             ;
        }
    }
    if (SDL_BuildAudioResampleCVT(cvt, dst_channels, src_rate, dst_rate) ==
        -1) {
        return -1;              
    }
    if (cvt->filter_index != 0) {
        cvt->needed = 1;
        cvt->src_format = src_fmt;
        cvt->dst_format = dst_fmt;
        cvt->len = 0;
        cvt->buf = NULL;
        cvt->filters[cvt->filter_index] = NULL;
    }
    return (cvt->needed);
}
int SDL_BuildAudioCVT ( SDL_AudioCVT * cvt , SDL_AudioFormat src_fmt , Uint8 src_channels , int src_rate , SDL_AudioFormat dst_fmt , Uint8 dst_channels , int dst_rate ) { if ( cvt == NULL ) { return SDL_InvalidParamError ( " " ) ; } if ( ( SDL_AUDIO_BITSIZE ( src_fmt ) > 16 ) && ( ! SDL_AUDIO_ISSIGNED ( src_fmt ) ) ) { return SDL_SetError ( " " ) ; } if ( ( SDL_AUDIO_BITSIZE ( dst_fmt ) > 16 ) && ( ! SDL_AUDIO_ISSIGNED ( dst_fmt ) ) ) { return SDL_SetError ( " " ) ; } if ( ( src_channels == 0 ) || ( dst_channels == 0 ) ) { return SDL_SetError ( " " ) ; } if ( ( src_rate == 0 ) || ( dst_rate == 0 ) ) { return SDL_SetError ( " " ) ; } #ifdef DEBUG_CONVERT printf ( " \n " , src_fmt , dst_fmt , src_channels , dst_channels , src_rate , dst_rate ) ; #endif SDL_zerop ( cvt ) ; cvt -> src_format = src_fmt ; cvt -> dst_format = dst_fmt ; cvt -> needed = 0 ; cvt -> filter_index = 0 ; cvt -> filters [ 0 ] = NULL ; cvt -> len_mult = 1 ; cvt -> len_ratio = 1.0 ; cvt -> rate_incr = ( ( double ) dst_rate ) / ( ( double ) src_rate ) ; if ( SDL_BuildAudioTypeCVT ( cvt , src_fmt , dst_fmt ) == -1 ) { return -1 ; } if ( src_channels != dst_channels ) { if ( ( src_channels == 1 ) && ( dst_channels > 1 ) ) { cvt -> filters [ cvt -> filter_index ++ ] = SDL_ConvertStereo ; cvt -> len_mult *= 2 ; src_channels = 2 ; cvt -> len_ratio *= 2 ; } if ( ( src_channels == 2 ) && ( dst_channels == 6 ) ) { cvt -> filters [ cvt -> filter_index ++ ] = SDL_ConvertSurround ; src_channels = 6 ; cvt -> len_mult *= 3 ; cvt -> len_ratio *= 3 ; } if ( ( src_channels == 2 ) && ( dst_channels == 4 ) ) { cvt -> filters [ cvt -> filter_index ++ ] = SDL_ConvertSurround_4 ; src_channels = 4 ; cvt -> len_mult *= 2 ; cvt -> len_ratio *= 2 ; } while ( ( src_channels * 2 ) <= dst_channels ) { cvt -> filters [ cvt -> filter_index ++ ] = SDL_ConvertStereo ; cvt -> len_mult *= 2 ; src_channels *= 2 ; cvt -> len_ratio *= 2 ; } if ( ( src_channels == 6 ) && ( dst_channels <= 2 ) ) { cvt -> filters [ cvt -> filter_index ++ ] = SDL_ConvertStrip ; src_channels = 2 ; cvt -> len_ratio /= 3 ; } if ( ( src_channels == 6 ) && ( dst_channels == 4 ) ) { cvt -> filters [ cvt -> filter_index ++ ] = SDL_ConvertStrip_2 ; src_channels = 4 ; cvt -> len_ratio /= 2 ; } while ( ( ( src_channels % 2 ) == 0 ) && ( ( src_channels / 2 ) >= dst_channels ) ) { cvt -> filters [ cvt -> filter_index ++ ] = SDL_ConvertMono ; src_channels /= 2 ; cvt -> len_ratio /= 2 ; } if ( src_channels != dst_channels ) { ; } } if ( SDL_BuildAudioResampleCVT ( cvt , dst_channels , src_rate , dst_rate ) == -1 ) { return -1 ; } if ( cvt -> filter_index != 0 ) { cvt -> needed = 1 ; cvt -> src_format = src_fmt ; cvt -> dst_format = dst_fmt ; cvt -> len = 0 ; cvt -> buf = NULL ; cvt -> filters [ cvt -> filter_index ] = NULL ; } return ( cvt -> needed ) ; }
Creates a set of audio filters to convert from one format to another.
Creates a set of audio filters to convert from one format to another .
/*
     * !!! FIXME: reorder filters based on which grow/shrink the buffer.
     * !!! FIXME: ideally, we should do everything that shrinks the buffer
     * !!! FIXME: first, so we don't have to process as many bytes in a given
     * !!! FIXME: filter and abuse the CPU cache less. This might not be as
     * !!! FIXME: good in practice as it sounds in theory, though.
     */ /* Sanity check target pointer */ /* there are no unsigned types over 16 bits, so catch this up front. */ /* prevent possible divisions by zero, etc. */ /* Start off with no conversion necessary */ /* Convert data types, if necessary. Updates (cvt). */ /* shouldn't happen, but just in case... */ /* Channel conversion */ /* This assumes that 4 channel audio is in the format:
           Left {front/back} + Right {front/back}
           so converting to L/R stereo works properly.
         */ /* Uh oh.. */ /* Do rate conversion, if necessary. Updates (cvt). */ /* shouldn't happen, but just in case... */ /* Set up the filter information */