diff --git a/apps/encoder.c b/apps/encoder.c index 09baa814aef7be0e841531f81f9127eaaf28578f..474f73bf84b97968abbf46b75fb940646b9b78db 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -214,6 +214,7 @@ int main( goto cleanup; } +#ifndef FIX_94_VERIFY_WAV_NUM_CHANNELS /*------------------------------------------------------------------------------------------* * Open input audio file *------------------------------------------------------------------------------------------*/ @@ -229,6 +230,7 @@ int main( fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", arg.inputFs, inFileSampleRate, arg.inputWavFilename ); goto cleanup; } +#endif /*------------------------------------------------------------------------------------------* * Open output bitstream file @@ -451,6 +453,67 @@ int main( goto cleanup; } +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS + /*------------------------------------------------------------------------------------------* + * Open input audio file + *------------------------------------------------------------------------------------------*/ + + if ( AudioFileReader_open( &audioReader, arg.inputWavFilename ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nCan't open %s\n\n", arg.inputWavFilename ); + goto cleanup; + } + + /* Validate input sampling rate */ + int32_t inFileSampleRate = 0; + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + switch ( error ) + { + case IVAS_ERR_OK: + if ( inFileSampleRate != arg.inputFs ) + { + fprintf( stderr, "\nSampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n\n", arg.inputFs, inFileSampleRate, arg.inputWavFilename ); + goto cleanup; + } + break; + case IVAS_ERR_SAMPLING_RATE_UNKNOWN: + /* IVAS_ERR_SAMPLING_RATE_UNKNOWN will be returned for raw PCM files. + * Nothing to check here */ + break; + default: + fprintf( stderr, "\nError: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } + + + /* Validate number of channels */ + int16_t encInNumChannels = 0; + if ( ( error = IVAS_ENC_GetNumInChannels( hIvasEnc, &encInNumChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } + int16_t inFileNumChannels = 0; + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + switch ( error ) + { + case IVAS_ERR_OK: + if ( inFileNumChannels != encInNumChannels ) + { + fprintf( stderr, "\nNumber of input audio channels mismatch: %d accepted by encoder, but %d found in file %s\n\n", encInNumChannels, inFileNumChannels, arg.inputWavFilename ); + goto cleanup; + } + break; + case IVAS_ERR_NUM_CHANNELS_UNKNOWN: + /* IVAS_ERR_NUM_CHANNELS_UNKNOWN will be returned for raw PCM files. + * Nothing to check here */ + break; + default: + fprintf( stderr, "\nError: %s\n", ivas_error_to_string( error ) ); + goto cleanup; + } +#endif + /*------------------------------------------------------------------------------------------* * Open input metadata files *------------------------------------------------------------------------------------------*/ diff --git a/apps/renderer.c b/apps/renderer.c index 66a1d666e3c27ea6fd6ae2cd55b83960b8fd470a..c7b297da4b010f87ca1224d015e1f440f6aacf6b 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -568,6 +568,45 @@ int main( setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders ); } +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); + } + + int32_t inFileSampleRate = 0; + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + switch ( error ) + { + case IVAS_ERR_OK: + if ( inFileSampleRate != args.sampleRate ) + { + fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", args.sampleRate, inFileSampleRate, args.inputFilePath ); + exit( -1 ); + } + break; + case IVAS_ERR_SAMPLING_RATE_UNKNOWN: /* Returned when input is raw PCM */ + if ( args.sampleRate == 0 ) + { + fprintf( stderr, "Sampling rate must be specified on command line when using raw PCM input\n" ); + exit( -1 ); + } + args.sampleRate = inFileSampleRate; + break; + default: + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + int16_t inFileNumChannels = 0; + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } +#else int32_t inFileSampleRate = 0; if ( AudioFileReader_open( &audioReader, audioFilePath, &inFileSampleRate ) != IVAS_ERR_OK ) { @@ -588,6 +627,7 @@ int main( { args.sampleRate = inFileSampleRate; } +#endif const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; @@ -755,8 +795,12 @@ int main( const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds ); +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS + if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) +#else if ( AudioFileReader_getNumChannels( audioReader ) != 0 /* If input file is raw PCM, audio reader has no info about number of channels */ && totalNumInChannels != AudioFileReader_getNumChannels( audioReader ) ) +#endif { fprintf( stderr, "Number of channels in input file does not match selected configuration\n" ); exit( -1 ); diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 6503249b342eb0f063865d7d3de97a75e686bb3b..735086a7c14c79dc80e6b4d748155890738548db 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -120,6 +120,10 @@ typedef enum IVAS_ERR_BITSTREAM_WRITER_INVALID_FORMAT, IVAS_ERR_BITSTREAM_READER_INVALID_DATA, IVAS_ERR_BITSTREAM_READER_INVALID_FORMAT, +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS + IVAS_ERR_NO_FILE_OPEN, + IVAS_ERR_SAMPLING_RATE_UNKNOWN, +#endif /*----------------------------------------* * renderer (lib_rend only) * diff --git a/lib_com/options.h b/lib_com/options.h index 61b96cd1ee187786fa1e962d90d9778634427b17..e9b04f07c722785452cee82edf86b425b980e53d 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -162,6 +162,8 @@ #define BINAURALIZATION_DELAY_REPORT /* VA: Issue 255 - Changes the way the decoder delay is reported */ +#define FIX_94_VERIFY_WAV_NUM_CHANNELS /* FhG: Issue 94 - Check if number of channels in input wav file matches encoder/renderer configuration */ + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index f56dd0d9e3c1c243374a7c6768cfae1c428c11bf..85de203f10034de387dc77d9e5a3b725d11045b5 100755 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -994,6 +994,33 @@ static int16_t getInputBufferSize( return (int16_t) ( st_ivas->hEncoderConfig->input_Fs * st_ivas->hEncoderConfig->nchan_inp / FRAMES_PER_SEC ); } +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS +/*---------------------------------------------------------------------* + * IVAS_ENC_GetNumInChannels() + * + * + *---------------------------------------------------------------------*/ +ivas_error IVAS_ENC_GetNumInChannels( + const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ + int16_t *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ +) +{ + if ( hIvasEnc == NULL || numInChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( !hIvasEnc->isConfigured ) + { + return IVAS_ERR_NOT_CONFIGURED; + } + + *numInChannels = hIvasEnc->st_ivas->hEncoderConfig->nchan_inp; + + return IVAS_ERR_OK; +} +#endif + /*---------------------------------------------------------------------* * IVAS_ENC_GetInputBufferSize() diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index be4d67359665a975f0a86d7de51e6417e9348802..4aef1df1fd02055909afc72a4e7386528a9a4330 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -300,6 +300,14 @@ ivas_error IVAS_ENC_GetDelay( int16_t *delay /* o : encoder delay */ ); +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS +/*! r: encoder error code */ +ivas_error IVAS_ENC_GetNumInChannels( + const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ + int16_t *numInChannels /* o : total number of samples expected in the input buffer for current encoder configuration */ +); +#endif + /*! r: encoder error code */ ivas_error IVAS_ENC_GetInputBufferSize( const IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ diff --git a/lib_util/audio_file_reader.c b/lib_util/audio_file_reader.c index 9599cff16930e503340e7f3ef894229291234195..c7feefd7b7d58ae04de932265d9d1e6c18104094 100644 --- a/lib_util/audio_file_reader.c +++ b/lib_util/audio_file_reader.c @@ -40,6 +40,9 @@ struct AudioFileReader { FILE *rawFile; WAVEFILEIN *wavFile; +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS + uint32_t samplingRate; +#endif int16_t numChannels; }; @@ -54,14 +57,26 @@ static int8_t AudioFileReader_open_raw( static int8_t AudioFileReader_open_wav( AudioFileReader *self, - const char *fileName, - int32_t *sampleRate ) + const char *fileName +#ifndef FIX_94_VERIFY_WAV_NUM_CHANNELS + , + int32_t *sampleRate +#endif +) { +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS + uint32_t samplesInFile; +#else uint32_t sampleRate_, samplesInFile; +#endif int16_t bps; +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS + self->wavFile = OpenWav( fileName, &self->samplingRate, &self->numChannels, &samplesInFile, &bps ); +#else self->wavFile = OpenWav( fileName, &sampleRate_, &self->numChannels, &samplesInFile, &bps ); *sampleRate = sampleRate_; +#endif if ( !self->wavFile ) { @@ -76,8 +91,11 @@ static int8_t AudioFileReader_open_wav( /*! r: AudioFileReader handle */ ivas_error AudioFileReader_open( AudioFileReader **audioReader, /* o : AudioFileReader handle */ - const char *fileName, /* i : path to wav/raw pcm file */ - int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ + const char *fileName /* i : path to wav/raw pcm file */ +#ifndef FIX_94_VERIFY_WAV_NUM_CHANNELS + , + int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ +#endif ) { AudioFileReader *self; @@ -100,11 +118,19 @@ ivas_error AudioFileReader_open( return IVAS_ERR_FAILED_FILE_OPEN; } self = calloc( sizeof( AudioFileReader ), 1 ); +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS + self->samplingRate = 0; +#endif self->numChannels = 0; if ( fileNameLen > wavSuffixLen && strncmp( fileName + fileNameLen - wavSuffixLen, wavSuffix, wavSuffixLen ) == 0 ) { - retCode = AudioFileReader_open_wav( self, fileName, sampleRate ); + retCode = AudioFileReader_open_wav( self, fileName +#ifndef FIX_94_VERIFY_WAV_NUM_CHANNELS + , + sampleRate +#endif + ); } else { @@ -180,6 +206,58 @@ ivas_error AudioFileReader_read( return error; } +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS +ivas_error AudioFileReader_getSamplingRate( + AudioFileReader *self, + int32_t *samplingRate ) +{ + if ( self == NULL || samplingRate == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( self->rawFile ) + { + return IVAS_ERR_SAMPLING_RATE_UNKNOWN; + } + else if ( self->wavFile ) + { + *samplingRate = self->samplingRate; + } + else + { + return IVAS_ERR_NO_FILE_OPEN; + } + + return IVAS_ERR_OK; +} + + +ivas_error AudioFileReader_getNumChannels( + AudioFileReader *self, + int16_t *numChannels ) +{ + if ( self == NULL || numChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( self->rawFile ) + { + return IVAS_ERR_NUM_CHANNELS_UNKNOWN; + } + else if ( self->wavFile ) + { + *numChannels = self->numChannels; + } + else + { + return IVAS_ERR_NO_FILE_OPEN; + } + + return IVAS_ERR_OK; +} +#else /*! r: number of channels of the opened file */ int16_t AudioFileReader_getNumChannels( AudioFileReader *self /* i/o: AudioFileReader handle */ @@ -192,3 +270,4 @@ int16_t AudioFileReader_getNumChannels( return 0; } +#endif diff --git a/lib_util/audio_file_reader.h b/lib_util/audio_file_reader.h index 46c458e646a79653c316d4805fe5ba723caab8c1..2f20be8b7bc60f8d9c8431d9d3afe20b542499c2 100644 --- a/lib_util/audio_file_reader.h +++ b/lib_util/audio_file_reader.h @@ -43,11 +43,12 @@ typedef struct AudioFileReader AudioFileReader; ivas_error AudioFileReader_open( AudioFileReader **audioReader, /* o : AudioFileReader handle */ - const char *fileName, /* i : path to wav/raw pcm file */ - int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ + const char *fileName /* i : path to wav/raw pcm file */ +#ifndef FIX_94_VERIFY_WAV_NUM_CHANNELS + ,int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ +#endif ); -/*! r: number of read samples */ ivas_error AudioFileReader_read( AudioFileReader *self, /* i/o: AudioFileReader handle */ int16_t *samples, /* o : samples read from the opened file */ @@ -55,10 +56,24 @@ ivas_error AudioFileReader_read( int16_t *numSamplesRead /* i : number of samples actualy read */ ); +#ifdef FIX_94_VERIFY_WAV_NUM_CHANNELS +/*! r: ivas error - in particular, IVAS_ERR_SAMPLING_RATE_UNKNOWN if the opened file has no sampling rate metadata */ +ivas_error AudioFileReader_getSamplingRate( + AudioFileReader *self, /* i/o: AudioFileReader handle */ + int32_t* samplingRate /* o : sampling rate of opened audio file */ +); + +/*! r: ivas error - in particular, IVAS_ERR_NUM_CHANNELS_UNKNOWN if the opened file has no metadata specifying number of channels */ +ivas_error AudioFileReader_getNumChannels( + AudioFileReader *self, /* i/o: AudioFileReader handle */ + int16_t * numChannels /* o : number fo channels in opened audio file */ +); +#else /*! r: number of channels of the opened file */ int16_t AudioFileReader_getNumChannels( AudioFileReader *self /* i/o: AudioFileReader handle */ ); +#endif void AudioFileReader_close( AudioFileReader **selfPtr /* i/o: pointer to AudioFileReader handle */