Commit 9b3d8883 authored by sagnowski's avatar sagnowski
Browse files

Enable decoder to output float wav files

parent 0d02712f
Loading
Loading
Loading
Loading
+61 −45
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ typedef struct

#ifdef FLOAT_INTERFACE_DEC_REND
    bool useInt16Interface;
    bool outputFloatFile;
#endif

} DecArguments;
@@ -734,6 +735,7 @@ static bool parseCmdlIVAS_dec(

#ifdef FLOAT_INTERFACE_DEC_REND
    arg->useInt16Interface = false;
    arg->outputFloatFile = false;
#endif

    /*-----------------------------------------------------------------*
@@ -964,11 +966,16 @@ static bool parseCmdlIVAS_dec(
            i++;
        }
#ifdef FLOAT_INTERFACE_DEC_REND
        else if ( strcmp( argv_to_upper, "-int16_api" ) == 0 )
        else if ( strcmp( argv_to_upper, "-INT16_API" ) == 0 )
        {
            arg->useInt16Interface = true;
            i++;
        }
        else if ( strcmp( argv_to_upper, "-FLOAT_WAV" ) == 0 )
        {
            arg->outputFloatFile = true;
            i++;
        }
#endif

        /*-----------------------------------------------------------------*
@@ -1123,6 +1130,8 @@ static void usage_dec( void )
    fprintf( stdout, "                      left or l or 1->left, right or r or -1->right, center or c or  0->middle\n" );
#ifdef FLOAT_INTERFACE_DEC_REND
    fprintf( stdout, "-int16_api          : Force int16 library interface to be used\n" );
    fprintf( stdout, "-float_wav          : Output audio to a 32-bit float wav file instead of the default 16-bit integer.\n" );
    fprintf( stdout, "                      This option is incompatible with raw pcm output.\n" );
#endif
    fprintf( stdout, "-q                  : Quiet mode, no frame counter\n" );
    fprintf( stdout, "                      default is deactivated\n" );
@@ -1220,7 +1229,11 @@ static ivas_error initOnFirstGoodFrame(
    }

    /* Open audio writer and write all previously skipped bad frames now that frame size is known */
    if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels ) ) != IVAS_ERR_OK )
    if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels
    #ifdef FLOAT_INTERFACE_DEC_REND
    , arg.outputFloatFile
    #endif
     ) ) != IVAS_ERR_OK )
    {
        fprintf( stderr, "\nUnable to open output file %s\n", arg.outputWavFilename );
        return error;
@@ -1233,7 +1246,11 @@ static ivas_error initOnFirstGoodFrame(
    {
        if ( *pRemainingDelayNumSamples < numOutSamples )
        {
#ifdef FLOAT_INTERFACE_DEC_REND
            if ( ( error = AudioFileWriter_writeFromInt16( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK )
#else
            if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK )
#endif
            {
                fprintf( stderr, "\nOutput audio file writer error\n" );
                return error;
@@ -1404,8 +1421,6 @@ static ivas_error decodeG192(
    }
    nOutSamples = arg.output_Fs / 50; /* TODO(sgi): Get from API */

    bool outputFileIsFloat = false; /* TODO(sgi):  */

    if ( arg.useInt16Interface )
    {
        audioDecBufInt = malloc( nOutChannels * nOutSamples * sizeof( int16_t ) );
@@ -1415,7 +1430,7 @@ static ivas_error decodeG192(
        audioDecBufFloat = malloc( nOutChannels * nOutSamples * sizeof( float ) );
    }

    if ( outputFileIsFloat )
    if ( arg.outputFloatFile )
    {
        audioWriteBufFloat = malloc( nOutChannels * nOutSamples * sizeof( float ) );
    }
@@ -1561,14 +1576,7 @@ static ivas_error decodeG192(
            if ( delayNumSamples < nOutSamples )
            {
#ifdef FLOAT_INTERFACE_DEC_REND
                if ( outputFileIsFloat )
                {
                    error = IVAS_ERR_NOT_IMPLEMENTED;
                    goto cleanup;
                }
                else
                {
                    if ( outputFileIsFloat )
                if ( arg.outputFloatFile )
                {
                    if ( arg.useInt16Interface )
                    {
@@ -1579,15 +1587,12 @@ static ivas_error decodeG192(
                        copyBufferPackedFloatToInterleavedFloat( audioDecBufFloat, nOutSamples, audioWriteBufFloat, nOutSamples, nOutChannels );
                    }

                        error = IVAS_ERR_NOT_IMPLEMENTED;
                        // if ( ( error = AudioFileWriter_writeFloat( afWriter, &audioDecBufFloat[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
                        // {
                        //     fprintf( stderr, "\nOutput audio file writer error\n" );
                        //     goto cleanup;
                        // }

                    if ( ( error = AudioFileWriter_writeFromFloat( afWriter, &audioWriteBufFloat[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
                    {
                        fprintf( stderr, "\nOutput audio file writer error\n" );
                        goto cleanup;
                    }
                }
                else
                {
                    if ( arg.useInt16Interface )
@@ -1599,13 +1604,12 @@ static ivas_error decodeG192(
                        copyBufferPackedFloatToInterleavedInt( audioDecBufFloat, nOutSamples, audioWriteBufInt, nOutSamples, nOutChannels, float2int );
                    }

                        if ( ( error = AudioFileWriter_write( afWriter, &audioWriteBufInt[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
                    if ( ( error = AudioFileWriter_writeFromInt16( afWriter, &audioWriteBufInt[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
                    {
                        fprintf( stderr, "\nOutput audio file writer error\n" );
                        goto cleanup;
                    }
                }
                }
#else
                if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
                {
@@ -1713,15 +1717,19 @@ static ivas_error decodeG192(

    /* add zeros at the end to have equal length of synthesized signals */
#ifdef FLOAT_INTERFACE_DEC_REND
    if ( outputFileIsFloat )
    if ( arg.outputFloatFile )
    {
        memset( audioWriteBufFloat, 0, delayNumSamples_orig * nOutChannels * sizeof( float ) );
        if ( ( error = AudioFileWriter_writeFromFloat( afWriter, audioWriteBufFloat, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK )
        {
        error = IVAS_ERR_NOT_IMPLEMENTED;
            fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
            goto cleanup;
        }
    }
    else
    {
        memset( audioWriteBufInt, 0, delayNumSamples_orig * nOutChannels * sizeof( int16_t ) );
        if ( ( error = AudioFileWriter_write( afWriter, audioWriteBufInt, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK )
        if ( ( error = AudioFileWriter_writeFromInt16( afWriter, audioWriteBufInt, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK )
        {
            fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
            goto cleanup;
@@ -2153,7 +2161,11 @@ static ivas_error decodeVoIP(
        {
            if ( delayNumSamples < nOutSamples )
            {
#ifdef FLOAT_INTERFACE_DEC_REND
                if ( ( error = AudioFileWriter_writeFromInt16( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
#else
                if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK )
#endif
                {
                    fprintf( stderr, "\nOutput audio file writer error\n" );
                    goto cleanup;
@@ -2184,7 +2196,11 @@ static ivas_error decodeVoIP(

    /* add zeros at the end to have equal length of synthesized signals */
    memset( pcmBuf, 0, delayNumSamples_orig * nOutChannels * sizeof( int16_t ) );
#ifdef FLOAT_INTERFACE_DEC_REND
    if ( ( error = AudioFileWriter_writeFromInt16( afWriter, pcmBuf, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK )
#else
    if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig * nOutChannels ) ) != IVAS_ERR_OK )
#endif
    {
        fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) );
        goto cleanup;
+16 −2
Original line number Diff line number Diff line
@@ -800,7 +800,11 @@ int main(
        fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) );
        exit( -1 );
    }
    if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK )
    if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels
#ifdef FLOAT_INTERFACE_DEC_REND
, false
#endif
     ) != IVAS_ERR_OK )
    {
        fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath );
        exit( -1 );
@@ -983,7 +987,13 @@ int main(

        if ( delayNumSamples < outBufferSize )
        {
            if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK )
            if (
#ifdef FLOAT_INTERFACE_DEC_REND
                AudioFileWriter_writeFromInt16(
#else
                AudioFileWriter_write(
#endif
                audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK )
            {
                fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath );
                exit( -1 );
@@ -1011,7 +1021,11 @@ int main(

    /* add zeros at the end to have equal length of synthesized signals */
    memset( outInt16Buffer, 0, zeroPad * outBuffer.config.numChannels * sizeof( int16_t ) );
#ifdef FLOAT_INTERFACE_DEC_REND
    if ( ( error = AudioFileWriter_writeFromInt16( audioWriter, outInt16Buffer, zeroPad * outBuffer.config.numChannels ) ) != IVAS_ERR_OK )
#else
    if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPad * outBuffer.config.numChannels ) ) != IVAS_ERR_OK )
#endif
    {
        fprintf( stderr, "\nOutput audio file writer error\n" );
        exit( -1 );
+1 −1
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ typedef enum
    IVAS_ERR_FAILED_FILE_READ,
    IVAS_ERR_FAILED_FILE_PARSE,
    IVAS_ERR_END_OF_FILE,
#ifdef FLOAT_INTERFACE_ENC
#if defined FLOAT_INTERFACE_ENC || defined FLOAT_INTERFACE_DEC_REND
    IVAS_ERR_NO_FILE_OPEN,
    IVAS_ERR_INVALID_AUDIO_FORMAT,
#endif
+95 −4
Original line number Diff line number Diff line
@@ -54,9 +54,20 @@ static int8_t AudioFileWriter_open_wav(
    AudioFileWriter *self,
    const char *fileName,
    uint32_t sampleRate,
    uint32_t numChannels )
    uint32_t numChannels
#ifdef FLOAT_INTERFACE_DEC_REND
    ,
    uint32_t bitsPerSample
#endif
)
{
    self->wavFile = CreateWav( fileName, sampleRate, numChannels, 16 );
    self->wavFile = CreateWav( fileName, sampleRate, numChannels,
#ifdef FLOAT_INTERFACE_DEC_REND
                               bitsPerSample
#else
                               16
#endif
    );
    if ( !self->wavFile )
    {
        fprintf( stderr, "Failed to open output wav file: %s\n", fileName );
@@ -70,7 +81,12 @@ ivas_error AudioFileWriter_open(
    AudioFileWriter **afWriter,
    const char *fileName,
    uint32_t sampleRate,
    uint32_t numChannels )
    uint32_t numChannels
#ifdef FLOAT_INTERFACE_DEC_REND
    ,
    bool outputFloat
#endif
)
{
    AudioFileWriter *self;
    const char *wavSuffix = ".wav";
@@ -100,10 +116,23 @@ ivas_error AudioFileWriter_open(

    if ( fileNameLen > wavSuffixLen && strncmp( fileName + fileNameLen - wavSuffixLen, wavSuffix, wavSuffixLen ) == 0 )
    {
        retCode = AudioFileWriter_open_wav( self, fileName, sampleRate, numChannels );
        retCode = AudioFileWriter_open_wav( self, fileName, sampleRate, numChannels
#ifdef FLOAT_INTERFACE_DEC_REND
                                            ,
                                            outputFloat ? 32 : 16
#endif
        );
    }
    else
    {
#ifdef FLOAT_INTERFACE_DEC_REND
        /* Floating-potin output only supported with wav files */
        if ( outputFloat )
        {
            return IVAS_ERR_INVALID_AUDIO_FORMAT;
        }
#endif

        retCode = AudioFileWriter_open_raw( self, fileName );
    }

@@ -144,7 +173,68 @@ void AudioFileWriter_close(
    return;
}

#ifdef FLOAT_INTERFACE_DEC_REND
ivas_error AudioFileWriter_writeFromFloat(
    AudioFileWriter *self,
    float *samples,
    uint32_t numSamples )
{
    if ( self == NULL || samples == NULL )
    {
        return IVAS_ERR_UNEXPECTED_NULL_POINTER;
    }

    if ( self->rawFile )
    {
        return IVAS_ERR_INVALID_AUDIO_FORMAT;
    }
    else if ( self->wavFile )
    {
        if ( WriteWavFloat( self->wavFile, samples, numSamples ) != __TWO_SUCCESS )
        {
            return IVAS_ERR_FAILED_FILE_WRITE;
        }
    }
    else
    {
        return IVAS_ERR_NO_FILE_OPEN;
    }

    return IVAS_ERR_OK;
}

ivas_error AudioFileWriter_writeFromInt16(
    AudioFileWriter *self,
    int16_t *samples,
    uint32_t numSamples )
{
    if ( self == NULL || samples == NULL )
    {
        return IVAS_ERR_UNEXPECTED_NULL_POINTER;
    }

    if ( self->rawFile )
    {
        if ( fwrite( samples, sizeof( int16_t ), numSamples, self->rawFile ) != numSamples )
        {
            return IVAS_ERR_FAILED_FILE_WRITE;
        }
    }
    else if ( self->wavFile )
    {
        if ( WriteWavShort( self->wavFile, samples, numSamples ) != __TWO_SUCCESS )
        {
            return IVAS_ERR_FAILED_FILE_WRITE;
        }
    }
    else
    {
        return IVAS_ERR_NO_FILE_OPEN;
    }

    return IVAS_ERR_OK;
}
#else
ivas_error AudioFileWriter_write(
    AudioFileWriter *self,
    int16_t *samples,
@@ -170,3 +260,4 @@ ivas_error AudioFileWriter_write(

    return error;
}
#endif
+31 −0
Original line number Diff line number Diff line
@@ -36,6 +36,10 @@
#include <stdint.h>
#include "ivas_error.h"

#ifdef FLOAT_INTERFACE_DEC_REND
#include <stdbool.h>
#endif

struct AudioFileWriter;
typedef struct AudioFileWriter AudioFileWriter;

@@ -45,13 +49,40 @@ ivas_error AudioFileWriter_open(
  const char *fileName,                 /* i  : path to wav/raw pcm file            */
  uint32_t sampleRate,                  /* i  : sample rate of output file          */
  uint32_t numChannels                  /* i  : number of channels in output file   */
#ifdef FLOAT_INTERFACE_DEC_REND
  ,bool outputFloat                     /* i  : if true, output file will contain floating point values instead of int16 */
#endif
);

#ifdef FLOAT_INTERFACE_DEC_REND
/* Writes audio from a float buffer to an audio file.
 *
 * Note: the type (float/int16) of samples written to the output file does not depend on the type of
 * the input buffer, only on the options specified at the call to AudioFileWriter_open(). If the
 * output file has int16 values, the float values from input buffer will be clipped to stay within
 * range and their fractional parts will be truncated. */
ivas_error AudioFileWriter_writeFromFloat(
  AudioFileWriter *self,                /* i/o: AudioFileReader handle              */
  float *samples,                       /* i  : samples to write to output file     */
  uint32_t numSamples                   /* i  : number of samples to write          */
);

/* Writes audio from an int16_t buffer to an audio file.
 *
 * Note: the type (float/int16) of samples written to the output file does not depend on the type of
 * the input buffer, only on the options specified at the call to AudioFileWriter_open(). */
ivas_error AudioFileWriter_writeFromInt16(
  AudioFileWriter *self,                /* i/o: AudioFileReader handle              */
  int16_t *samples,                     /* i  : samples to write to output file     */
  uint32_t numSamples                   /* i  : number of samples to write          */
);
#else
ivas_error AudioFileWriter_write(
  AudioFileWriter *self,                /* i/o: AudioFileReader handle              */
  int16_t *samples,                     /* i  : samples to write to output file     */
  uint32_t numSamples                   /* i  : number of samples to write          */
);
#endif

void AudioFileWriter_close(
  AudioFileWriter **selfPtr             /* i/o: pointer to AudioFileReader handle   */
Loading