From 7efd9a504c74b0f656ef1f8c059d5ad13c0c528c Mon Sep 17 00:00:00 2001 From: Ludovic Malfait Date: Tue, 26 May 2026 16:14:28 +0100 Subject: [PATCH 1/7] Add WAV file I/O support to all audio-processing tools Introduce wav_io library (src/utl/wav_io.c, wav_io.h) providing transparent WAV and raw PCM file handling for all STL tools. Features: - Auto-detect WAV input via RIFF header magic bytes - Output format determined by filename extension (.wav = WAV, else raw) - Supports 8-bit, 16-bit, 24-bit, 32-bit PCM and 32-bit IEEE float - Multi-channel WAV: extracts channel 1 with warning - Parameter validation: expected sample rate, channels, and bit depth - Full backward compatibility: raw PCM workflows unchanged Integrated into 28 tools across all categories: - Codecs: g711demo, g711iplc, g722demo, encg722, decg722, g726demo, vbr-g726, g727demo, rpedemo - Filters: firdemo, filter, cirsdemo, pcmdemo, c712demo - Measurement: sv56demo, actlevel, bs1770demo, mnrudemo, calc-snr, esdru, freqresp - Processing: reverb, stereoop - Utilities: scaldemo, signal-diff, astrip, fdelay, measure, oper Includes unit tests (test_wav_io) and LaTeX manual documentation. --- doc/manual/utl.tex | 154 +++++++++++++ src/bs1770demo/CMakeLists.txt | 4 +- src/bs1770demo/bs1770demo.c | 29 +-- src/esdru/CMakeLists.txt | 2 +- src/esdru/esdru.c | 23 +- src/fir/CMakeLists.txt | 4 +- src/fir/filter.c | 21 +- src/fir/firdemo.c | 18 +- src/freqresp/CMakeLists.txt | 2 +- src/freqresp/freqresp.c | 19 +- src/g711/CMakeLists.txt | 2 +- src/g711/g711demo.c | 40 ++-- src/g711iplc/CMakeLists.txt | 2 +- src/g711iplc/g711iplc.c | 21 +- src/g722/CMakeLists.txt | 6 +- src/g722/decg722.c | 12 +- src/g722/encg722.c | 10 +- src/g722/g722demo.c | 15 +- src/g726/CMakeLists.txt | 4 +- src/g726/g726demo.c | 20 +- src/g726/vbr-g726.c | 20 +- src/g727/CMakeLists.txt | 2 +- src/g727/g727demo.c | 20 +- src/iir/CMakeLists.txt | 6 +- src/iir/c712demo.c | 15 +- src/iir/cirsdemo.c | 15 +- src/iir/pcmdemo.c | 15 +- src/mnru/CMakeLists.txt | 4 +- src/mnru/calc-snr.c | 18 +- src/mnru/mnru.c | 2 +- src/mnru/mnrudemo.c | 20 +- src/reverb/CMakeLists.txt | 2 +- src/reverb/reverb.c | 19 +- src/rpeltp/CMakeLists.txt | 2 +- src/rpeltp/rpedemo.c | 27 +-- src/stereoop/CMakeLists.txt | 2 +- src/stereoop/stereoop.c | 29 +-- src/sv56/CMakeLists.txt | 4 +- src/sv56/actlevel.c | 11 +- src/sv56/sv56demo.c | 21 +- src/unsup/CMakeLists.txt | 8 +- src/unsup/astrip.c | 17 +- src/unsup/fdelay.c | 29 +-- src/unsup/measure.c | 21 +- src/unsup/oper.c | 36 ++-- src/utl/CMakeLists.txt | 7 +- src/utl/scaldemo.c | 17 +- src/utl/signal-diff.c | 24 +-- src/utl/test_wav_io.c | 262 ++++++++++++++++++++++ src/utl/wav_io.c | 396 ++++++++++++++++++++++++++++++++++ src/utl/wav_io.h | 63 ++++++ 51 files changed, 1219 insertions(+), 323 deletions(-) create mode 100644 src/utl/test_wav_io.c create mode 100644 src/utl/wav_io.c create mode 100644 src/utl/wav_io.h diff --git a/doc/manual/utl.tex b/doc/manual/utl.tex index b8ec63d9..68ed8e29 100644 --- a/doc/manual/utl.tex +++ b/doc/manual/utl.tex @@ -534,6 +534,160 @@ \subsection{{\tt parallelize\_*\_justified}} parallel sample buffer. +%-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. +\section{WAV file I/O} \label{Utl-wav-io} + +The {\tt wav\_io} module provides transparent reading and writing of WAV +files alongside the traditional raw (headerless) PCM format used throughout +the STL. All tools that process audio PCM signals use this module to +auto-detect the input format and to select the output format based on the +output filename extension. + +\subsection{Design} + +\begin{itemize} +\item {\bf Input auto-detection:} When opening a file for reading, the first + four bytes are checked for the RIFF magic number ({\tt 0x52494646}). If + found, the file is parsed as a WAV file; otherwise it is treated as raw + PCM (legacy behavior). +\item {\bf Output format:} Determined solely by the output filename extension. + If the filename ends in {\tt .wav} (case-insensitive), a WAV file with a + canonical 44-byte header is written. Any other extension produces raw PCM + output, preserving full backward compatibility. +\item {\bf Supported formats:} 8-bit unsigned PCM, 16-bit signed PCM, 24-bit + signed PCM, 32-bit signed PCM, and 32-bit IEEE~754 float (format tags~1 + and~3). +\item {\bf Parameter validation:} The caller specifies expected sample rate, + channel count, and bit depth. If any expected value is non-zero and does not + match the WAV header, the file is rejected with an error. +\item {\bf Multi-channel:} When a multi-channel WAV file is opened by a mono + tool, channel~1 is extracted and a warning is printed to {\tt stderr}. +\end{itemize} + +\subsection{{\tt audio\_open\_read}} + +Opens a file for reading with automatic format detection. + +{\small +\begin{verbatim} +AUDIO_FILE *audio_open_read( + const char *filename, /* File to open */ + long expected_rate, /* Expected sample rate (0 = don't check) */ + int expected_channels, /* Expected channels (0 = don't check) */ + int expected_bits /* Expected bits/sample (0 = don't check) */ +); +\end{verbatim} +} + +Returns a pointer to an {\tt AUDIO\_FILE} structure, or {\tt NULL} on error. +For raw files, the file pointer is positioned at byte~0. For WAV files, it is +positioned at the start of the PCM data chunk. + +\subsection{{\tt audio\_open\_write}} + +Opens a file for writing. The format is determined by the filename extension. + +{\small +\begin{verbatim} +AUDIO_FILE *audio_open_write( + const char *filename, /* File to create */ + long sample_rate, /* Sample rate for WAV header */ + int channels, /* Channel count for WAV header */ + int bits_per_sample /* Bits per sample (8, 16, 24, or 32) */ +); +\end{verbatim} +} + +For WAV output, a 44-byte placeholder header is written on open and updated +with the correct data size on close. + +\subsection{{\tt audio\_read} and {\tt audio\_write}} + +Read and write samples in the native bit depth of the file: + +{\small +\begin{verbatim} +long audio_read(AUDIO_FILE *af, void *buffer, long nsamples); +long audio_write(AUDIO_FILE *af, void *buffer, long nsamples); +\end{verbatim} +} + +The buffer type must match the file's bit depth: + +\begin{center} +\begin{tabular}{lll} +\hline +{\bf Bit depth} & {\bf Buffer type} & {\bf Bytes/sample} \\ +\hline +8-bit PCM & {\tt unsigned char *} & 1 \\ +16-bit PCM & {\tt short *} & 2 \\ +24-bit PCM & {\tt long *} (sign-extended) & 3 on disk, 4 in memory \\ +32-bit PCM & {\tt long *} & 4 \\ +32-bit float & {\tt float *} & 4 \\ +\hline +\end{tabular} +\end{center} + +For multi-channel WAV input, {\tt audio\_read} de-interleaves and returns only +channel~1. Both functions return the number of samples actually read or +written. + +\subsection{{\tt audio\_close}} + +Closes the file. For WAV output, seeks back to the header and writes the +final data size and file size fields. + +{\small +\begin{verbatim} +void audio_close(AUDIO_FILE *af); +\end{verbatim} +} + +\subsection{Accessor functions} + +{\small +\begin{verbatim} +int audio_is_wav(AUDIO_FILE *af); /* 1 if WAV, 0 if raw */ +long audio_get_sample_rate(AUDIO_FILE *af); /* From WAV header, 0 if raw */ +int audio_get_channels(AUDIO_FILE *af); /* From WAV header, 0 if raw */ +\end{verbatim} +} + +\subsection{Usage example} + +The following fragment shows a 16-bit tool reading and writing WAV or raw: + +{\small +\begin{verbatim} +#include "wav_io.h" + +AUDIO_FILE *in, *out; +short buf[256]; +long n; + +in = audio_open_read("input.wav", 8000, 1, 16); +out = audio_open_write("output.wav", 8000, 1, 16); + +while ((n = audio_read(in, buf, 256)) > 0) { + /* process buf[] */ + audio_write(out, buf, n); +} + +audio_close(out); +audio_close(in); +\end{verbatim} +} + +A 24-bit tool would use {\tt long} buffers and pass 24 for {\tt expected\_bits}: + +{\small +\begin{verbatim} +AUDIO_FILE *in = audio_open_read("hires.wav", 48000, 1, 24); +long buf[256]; +audio_read(in, buf, 256); /* 24-bit values sign-extended into long */ +\end{verbatim} +} + %-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. \section{Portability and compliance} \label{Utl-port} diff --git a/src/bs1770demo/CMakeLists.txt b/src/bs1770demo/CMakeLists.txt index daba5f89..619dbd5a 100644 --- a/src/bs1770demo/CMakeLists.txt +++ b/src/bs1770demo/CMakeLists.txt @@ -1,4 +1,6 @@ -add_executable(bs1770demo bs1770demo.c) +include_directories(../utl) + +add_executable(bs1770demo bs1770demo.c ../utl/wav_io.c) target_link_libraries(bs1770demo ${M_LIBRARY}) diff --git a/src/bs1770demo/bs1770demo.c b/src/bs1770demo/bs1770demo.c index 84ec2f77..d9093286 100644 --- a/src/bs1770demo/bs1770demo.c +++ b/src/bs1770demo/bs1770demo.c @@ -10,6 +10,7 @@ #include #include #include +#include "wav_io.h" #define BLOCK_SIZE 19200 /* 400 ms in 48000 Hz sample rate */ #define STEP_SIZE 4800 /* 100 ms in 48000 Hz sample rate (75% overlap of 400 ms gating blocks) */ @@ -387,8 +388,8 @@ long parse_conf( /* o: 0:success, -1:fail */ int main(int argc, char **argv ) { - FILE* f_input; - FILE* f_output; + AUDIO_FILE* f_input; + AUDIO_FILE* f_output; char *input_filename; char *output_filename; double *input; @@ -477,7 +478,7 @@ int main(int argc, char **argv ) } input_filename = argv[i++]; - if( (f_input = fopen( input_filename, "rb" )) == NULL ) + if( (f_input = audio_open_read (input_filename, 0, 0, 16)) == NULL ) { fprintf( stderr, "*** Could not open input file %s, exiting..\n\n", input_filename ); usage(); @@ -489,7 +490,7 @@ int main(int argc, char **argv ) else { output_filename = argv[i]; - if( (f_output = fopen( output_filename, "wb" )) == NULL ) + if( (f_output = audio_open_write( output_filename, 0, 1, 16 )) == NULL ) { fprintf( stderr, "*** Could not open output file %s, exiting..\n\n", output_filename ); usage(); @@ -541,9 +542,9 @@ int main(int argc, char **argv ) fprintf( stdout, "nchan: %ld\n", nchan ); /* Find length of input file */ - fseek( f_input, 0L, SEEK_END ); - length_total = ftell( f_input ) / (2*nchan); /* 2 bytes per sample (16 bits), nchan channels */ - if( (ftell( f_input ) % (2 * nchan)) != 0 ) + fseek( f_input->fp, 0L, SEEK_END ); + length_total = ftell( f_input->fp ) / (2*nchan); /* 2 bytes per sample (16 bits), nchan channels */ + if( (ftell( f_input->fp ) % (2 * nchan)) != 0 ) { fprintf( stderr, "*** Number of samples not divisible into number of channels, exiting..\n" ); exit( -1 ); @@ -553,7 +554,7 @@ int main(int argc, char **argv ) fprintf( stderr, "*** Input file must be longer than 400 ms to use bs1770demo, exiting..\n" ); exit( -1 ); } - rewind( f_input ); + rewind( f_input->fp ); n_gating_blocks = 4 * (length_total - BLOCK_SIZE) / (BLOCK_SIZE); /* Allocate input buffers */ @@ -572,7 +573,7 @@ int main(int argc, char **argv ) for( n = 0, j = -3; j < n_gating_blocks; n++, j++ ) { /* Read next sub-block */ - fread( input_short, sizeof( short ), STEP_SIZE * nchan, f_input ); + fread( input_short, sizeof( short ), STEP_SIZE * nchan, f_input->fp ); deinterleave_short2double( input_short, input, STEP_SIZE * nchan, nchan ); @@ -610,16 +611,16 @@ int main(int argc, char **argv ) fac = find_scaling_factor( gating_block_energy, n_gating_blocks, lev_target, rms_flag, &lev_input, &lev_obtained ); /* Apply scaling */ - rewind( f_input ); + rewind( f_input->fp ); length_total = 0; clip = 0; - while( (length = (long)fread( input_short, sizeof( short ), STEP_SIZE * nchan, f_input ) ) ) + while( (length = (long)fread( input_short, sizeof( short ), STEP_SIZE * nchan, f_input->fp ) ) ) { deinterleave_short2double( input_short, input, STEP_SIZE * nchan, nchan ); scale(input, fac, input, STEP_SIZE * nchan ); clip += interleave_double2short( input, input_short, STEP_SIZE * nchan, nchan ); length_total += length / nchan; - fwrite( input_short, sizeof( short ), length, f_output ); + fwrite( input_short, sizeof( short ), length, f_output->fp ); } fprintf( stdout, "Input level: %.6f\n", lev_input ); @@ -633,7 +634,7 @@ int main(int argc, char **argv ) fprintf( stderr, "*** Warning: %ld samples clipped\n", clip ); } - fclose( f_output ); + audio_close( f_output ); } else { @@ -666,7 +667,7 @@ int main(int argc, char **argv ) } /* Close files */ - fclose( f_input ); + audio_close( f_input ); /* Deallocate memory */ free( input ); diff --git a/src/esdru/CMakeLists.txt b/src/esdru/CMakeLists.txt index da2dddcc..56bcbc76 100644 --- a/src/esdru/CMakeLists.txt +++ b/src/esdru/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(../utl) -add_executable(esdru esdru.c ../utl/ugst-utl.c) +add_executable(esdru esdru.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(esdru ${M_LIBRARY}) diff --git a/src/esdru/esdru.c b/src/esdru/esdru.c index da62b7f0..d4d4c7d1 100644 --- a/src/esdru/esdru.c +++ b/src/esdru/esdru.c @@ -9,6 +9,7 @@ #include #include #include "ugst-utl.h" /* for ran16_32c */ +#include "wav_io.h" #define LOCAL_PI 3.14159265358979323846 @@ -271,8 +272,8 @@ void apply_spatial_dist( int main(int argc, char **argv ) { - FILE* f_input; - FILE* f_output; + AUDIO_FILE* f_input; + AUDIO_FILE* f_output; FILE* f_energy; char *input_filename; char *output_filename; @@ -398,12 +399,12 @@ int main(int argc, char **argv ) } input_filename = argv[i++]; output_filename = argv[i]; - if( (f_input = fopen( input_filename, "rb" )) == NULL ) + if( (f_input = audio_open_read (input_filename, 0, 0, 16)) == NULL ) { fprintf( stderr, "Could not open input file %s, exiting..\n\n", input_filename ); usage(); } - if( (f_output = fopen( output_filename, "wb" )) == NULL ) + if( (f_output = audio_open_write( output_filename, 0, 1, 16 )) == NULL ) { fprintf( stderr, "Could not open output file %s, exiting..\n\n", output_filename ); usage(); @@ -421,13 +422,13 @@ int main(int argc, char **argv ) fseed = (float) intseed; /* Load input file */ - fseek( f_input, 0L, SEEK_END ); - length = ftell( f_input ) / 4; /* 2 bytes per sample, 2 channels */ - rewind( f_input ); + fseek( f_input->fp, 0L, SEEK_END ); + length = ftell( f_input->fp ) / 4; /* 2 bytes per sample, 2 channels */ + rewind( f_input->fp ); input = malloc(sizeof(double) * length * 2); input_short = malloc( sizeof( short ) * length * 2 ); m = malloc( sizeof( double ) * length ); - fread( input_short, sizeof(short), length * 2, f_input); + fread( input_short, sizeof(short), length * 2, f_input->fp); convert_short2double( input_short, input, length * 2); step = (long) (1.5 * fs / 50.0); @@ -437,7 +438,7 @@ int main(int argc, char **argv ) clip = convert_double2short(input, input_short, length * 2); - fwrite( input_short, sizeof( short ), length * 2, f_output ); + fwrite( input_short, sizeof( short ), length * 2, f_output->fp ); fprintf( stdout, "--> Done processing %ld samples\n", length ); if (clip > 0) @@ -449,8 +450,8 @@ int main(int argc, char **argv ) { fclose( f_energy ); } - fclose( f_input ); - fclose( f_output ); + audio_close( f_input ); + audio_close( f_output ); free( input ); free( input_short ); free( m ); diff --git a/src/fir/CMakeLists.txt b/src/fir/CMakeLists.txt index b064f32e..6d67e648 100644 --- a/src/fir/CMakeLists.txt +++ b/src/fir/CMakeLists.txt @@ -2,13 +2,13 @@ include_directories(../iir) include_directories(../utl) -add_executable(filter filter.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c ../utl/ugst-utl.c) +add_executable(filter filter.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(filter ${M_LIBRARY}) add_executable(flt fltresp.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c) target_link_libraries(flt ${M_LIBRARY}) -add_executable(firdemo firdemo.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c ../utl/ugst-utl.c) +add_executable(firdemo firdemo.c fir-dsm.c fir-flat.c fir-irs.c fir-lib.c fir-pso.c fir-tia.c fir-hirs.c fir-wb.c fir-msin.c fir-LP.c ../iir/iir-lib.c ../iir/iir-g712.c ../iir/iir-dir.c ../iir/iir-flat.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(firdemo ${M_LIBRARY}) #Test: FIR diff --git a/src/fir/filter.c b/src/fir/filter.c index 6708d091..1208eba9 100644 --- a/src/fir/filter.c +++ b/src/fir/filter.c @@ -171,6 +171,7 @@ #include "iirflt.h" #include "firflt.h" #include "ugst-utl.h" +#include "wav_io.h" /* LOCAL DEFINITIONS */ #ifndef max @@ -327,7 +328,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; + AUDIO_FILE *Fi, *Fo; long start_byte; #ifdef VMS char mrs[15]; @@ -759,15 +760,15 @@ int main (int argc, char *argv[]) { #endif /* Opening input file; abort if there's any problem */ - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); /* Creates output file */ - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0)) + if (fseek (Fi->fp, start_byte, 0)) KILL (FileIn, 4); @@ -775,7 +776,7 @@ int main (int argc, char *argv[]) { /* One-time delay of output signal, if appropriate */ if (async && delay > 0) - if ((smpno = fwrite (zero, sizeof (short), delay, Fo)) == 0 && ferror (Fo)) + if ((smpno = audio_write (Fo, zero, delay)) == 0) KILL (FileOut, 6); /* Process regular frames */ @@ -788,7 +789,7 @@ int main (int argc, char *argv[]) { memset (OutBuff, '\0', out_size * sizeof (float)); /* Read a block of samples */ - if ((smpno = fread (TmpBuff, sizeof (short), N, Fi)) == 0) + if ((smpno = audio_read (Fi, TmpBuff, N)) == 0) KILL (FileIn, 5); /* ... and convert short to float, normalizing */ @@ -830,12 +831,12 @@ int main (int argc, char *argv[]) { skip -= smpno; continue; } else if (skip > 0) { - if ((smpno = fwrite (&TmpBuff[skip], sizeof (short), (smpno - skip), Fo)) == 0 && ferror (Fo)) + if ((smpno = audio_write (Fo, &TmpBuff[skip], (smpno - skip))) == 0) KILL (FileOut, 6); total += smpno; skip = 0; } else { - if ((smpno = fwrite (TmpBuff, sizeof (short), smpno, Fo)) == 0 && ferror (Fo)) + if ((smpno = audio_write (Fo, TmpBuff, smpno)) == 0) KILL (FileOut, 6); total += smpno; } @@ -846,8 +847,8 @@ int main (int argc, char *argv[]) { fprintf (stderr, "\n"); /* Close open files */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); /* Release some memory */ free (TmpBuff); diff --git a/src/fir/firdemo.c b/src/fir/firdemo.c index af6e4303..2ca7b432 100644 --- a/src/fir/firdemo.c +++ b/src/fir/firdemo.c @@ -207,6 +207,7 @@ #include "ugstdemo.h" /* private defines for user interface */ #include "ugst-utl.h" /* conversion from float -> short */ #include "firflt.h" /* definitions for high quality filter */ +#include "wav_io.h" /* WAV file I/O support */ /* Specific Includes */ @@ -332,8 +333,7 @@ int main (int argc, char *argv[]) { /* ......... File related variables ......... */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *inpfilptr, *outfilptr; - int inp, out; + AUDIO_FILE *inpfilptr, *outfilptr; #if defined(VMS) char mrs[15]; #endif @@ -416,14 +416,12 @@ int main (int argc, char *argv[]) { #endif GET_PAR_S (1, "_BIN-File to be filtered: ................ ", inpfil); - if ((inpfilptr = fopen (inpfil, RB)) == NULL) + if ((inpfilptr = audio_open_read (inpfil, 0, 0, 16)) == NULL) error_terminate ("Error opening input file\n", 1); - inp = fileno (inpfilptr); GET_PAR_S (2, "_BIN-Output File: ........................ ", outfil); - if ((outfilptr = fopen (outfil, WB)) == NULL) + if ((outfilptr = audio_open_write (outfil, audio_get_sample_rate (inpfilptr), 1, 16)) == NULL) error_terminate ("Error opening output file\n", 1); - out = fileno (outfilptr); GET_PAR_L (3, "_IRS Filter (0, 8, 16, 48): ........ ", irs); if ((irs != 0) && (irs != 8) && (irs != 16) && (irs != 48)) @@ -613,7 +611,7 @@ int main (int argc, char *argv[]) { lsegx = lseg; while (lsegx == lseg) { /* Read data from file in a short array ... */ - lsegx = fread (sh_buff, sizeof (short), lseg, inpfilptr); + lsegx = audio_read (inpfilptr, sh_buff, lseg); /* ... and convert short to float, normalizing */ sh2fl_16bit (lsegx, sh_buff, fl_buff, 1); @@ -744,7 +742,7 @@ int main (int argc, char *argv[]) { /* * ......... WRITE SAMPLES TO OUTPUT FILE ......... */ - nsam += fwrite (sh_buff, sizeof (short), lsegdown2, outfilptr); + nsam += audio_write (outfilptr, sh_buff, lsegdown2); } @@ -790,8 +788,8 @@ int main (int argc, char *argv[]) { free (sh_buff); /* Close files */ - fclose (outfilptr); - fclose (inpfilptr); + audio_close (outfilptr); + audio_close (inpfilptr); #ifndef VMS return (0); diff --git a/src/freqresp/CMakeLists.txt b/src/freqresp/CMakeLists.txt index b4ad7bcf..1b6f8d37 100644 --- a/src/freqresp/CMakeLists.txt +++ b/src/freqresp/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(../utl) -add_executable(freqresp freqresp.c bmp_utils.c export.c fft.c) +add_executable(freqresp freqresp.c bmp_utils.c export.c fft.c ../utl/wav_io.c) target_link_libraries(freqresp ${M_LIBRARY}) diff --git a/src/freqresp/freqresp.c b/src/freqresp/freqresp.c index 60e46cbd..b9fd21d4 100644 --- a/src/freqresp/freqresp.c +++ b/src/freqresp/freqresp.c @@ -49,6 +49,7 @@ #include "fft.h" #include "export.h" #include "bmp_utils.h" +#include "wav_io.h" /* UGST modules */ #include "ugstdemo.h" @@ -114,7 +115,7 @@ int main (int argc, char *argv[]) { float avg2PowSp[NFFT_MAX / 2]; /* Average Power spectrum vector for the second input file */ /* file variables */ - FILE *fp; /* file pointer */ + AUDIO_FILE *fp; /* file pointer */ char in1FileName[MAX_STRLEN]; /* name of the first input file (input of the codec) */ char in2FileName[MAX_STRLEN]; /* name of the second input file (output of the codec) */ char asciiFileName[MAX_STRLEN]; /* name of the output ASCII file */ @@ -279,14 +280,14 @@ int main (int argc, char *argv[]) { /* ..... First File ..... */ /* open first input file */ - fp = fopen (in1FileName, "rb"); + fp = audio_open_read (in1FileName, 0, 0, 16); if (fp == NULL) { fprintf (stderr, "Error: Can't open input file %s", in1FileName); exit (-1); } /* loop over first input file */ - while ((nbread = fread (frame_sh, sizeof (short), nfft, fp)) == nfft) { + while ((nbread = audio_read (fp, frame_sh, nfft)) == nfft) { /* increment the number of processed frames */ nbFrame++; @@ -313,16 +314,16 @@ int main (int argc, char *argv[]) { } /* For overlapping, reposition the file pointer nb_samples_ov samples before its current position */ - fseek (fp, -nb_samples_ov * 2, SEEK_CUR); + fseek (fp->fp, -nb_samples_ov * 2, SEEK_CUR); } /* close input file */ - fclose (fp); + audio_close (fp); /* ..... Second File ..... */ /* open second input file */ - fp = fopen (in2FileName, "rb"); + fp = audio_open_read (in2FileName, 0, 0, 16); if (fp == NULL) { fprintf (stderr, "Error: Can't open input file %s", in2FileName); exit (-1); @@ -330,7 +331,7 @@ int main (int argc, char *argv[]) { nbFrame = 0; /* loop over first input file */ - while ((nbread = fread (frame_sh, sizeof (short), nfft, fp)) == nfft) { + while ((nbread = audio_read (fp, frame_sh, nfft)) == nfft) { /* increment the number of processed frames */ nbFrame++; @@ -356,10 +357,10 @@ int main (int argc, char *argv[]) { } /* For overlapping, reposition the file pointer nb_samples_ov samples before its current position */ - fseek (fp, -nb_samples_ov * 2, SEEK_CUR); + fseek (fp->fp, -nb_samples_ov * 2, SEEK_CUR); } /* close input file */ - fclose (fp); + audio_close (fp); /* .... Save Average Power Spectrum .... */ diff --git a/src/g711/CMakeLists.txt b/src/g711/CMakeLists.txt index ebb229eb..c9d53d2b 100644 --- a/src/g711/CMakeLists.txt +++ b/src/g711/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(../utl) -add_executable(g711demo g711demo.c g711.c) +add_executable(g711demo g711demo.c g711.c ../utl/wav_io.c) target_link_libraries(g711demo ${M_LIBRARY}) add_executable(shiftbit shiftbit.c) diff --git a/src/g711/g711demo.c b/src/g711/g711demo.c index f61731d4..1ce4cf69 100644 --- a/src/g711/g711demo.c +++ b/src/g711/g711demo.c @@ -166,6 +166,7 @@ /* G711 module functions */ #include "g711.h" +#include "wav_io.h" /* @@ -231,8 +232,7 @@ int main (int argc, char *argv[]) { short *log_buff; /* compressed data */ short *lon_buff; /* quantized output samples */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *Fi, *Fo; - int inp, out; + AUDIO_FILE *Fi, *Fo; char law[MAX_STRLEN], lilo[MAX_STRLEN]; short inp_type, out_type; char revert_even_bits = 1; @@ -327,20 +327,18 @@ int main (int argc, char *argv[]) { #endif /* Open input file */ - if ((Fi = fopen (inpfil, RB)) == NULL) + if ((Fi = audio_open_read (inpfil, 0, 0, 16)) == NULL) KILL (inpfil, 2); - inp = fileno (Fi); /* Open (create) output file */ - if ((Fo = fopen (outfil, WB)) == NULL) + if ((Fo = audio_open_write (outfil, 0, 1, 16)) == NULL) KILL (outfil, 3); - out = fileno (Fo); /* Define starting byte in file */ start_byte = (N1 * N + skip) * sizeof (short); /* ... and move file's pointer to 1st desired block */ - if (fseek (Fi, (N1 * N + skip) * sizeof (short), 0) < 0l) + if (fseek (Fi->fp, (N1 * N + skip) * sizeof (short), 0) < 0l) KILL (inpfil, 4); /* Check whether is to process til end-of-file */ @@ -365,38 +363,38 @@ int main (int argc, char *argv[]) { /* Input: LINEAR | Output: LOG */ if (inp_type == IS_LIN && out_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - if ((smpno = fread (lin_buff, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, lin_buff, N)) < 0) KILL (inpfil, 5); alaw_compress (smpno, lin_buff, log_buff); if (!revert_even_bits) for (i = 0; i < smpno; i++) log_buff[i] ^= 0x0055; - if ((smpno = fwrite (log_buff, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, log_buff, smpno)) < 0) KILL (outfil, 6); } /* Input: LINEAR | Output: LINEAR */ else if (inp_type == IS_LIN && out_type == IS_LIN) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - if ((smpno = fread (lin_buff, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, lin_buff, N)) < 0) KILL (inpfil, 5); alaw_compress (smpno, lin_buff, log_buff); alaw_expand (smpno, log_buff, lon_buff); - if ((smpno = fwrite (lon_buff, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, lon_buff, smpno)) < 0) KILL (outfil, 6); } /* Input: LOG | Output: LINEAR */ else if (inp_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - if ((smpno = fread (log_buff, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, log_buff, N)) < 0) KILL (inpfil, 5); if (!revert_even_bits) for (i = 0; i < smpno; i++) log_buff[i] ^= 0x0055; alaw_expand (smpno, log_buff, lon_buff); - if ((smpno = fwrite (lon_buff, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, lon_buff, smpno)) < 0) KILL (outfil, 6); } break; @@ -407,26 +405,26 @@ int main (int argc, char *argv[]) { /* Input: LINEAR | Output: LOG */ if (inp_type == IS_LIN && out_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - smpno = fread (lin_buff, sizeof (short), N, Fi); + smpno = audio_read (Fi, lin_buff, N); ulaw_compress (smpno, lin_buff, log_buff); - smpno = fwrite (log_buff, sizeof (short), smpno, Fo); + smpno = audio_write (Fo, log_buff, smpno); } /* Input: LINEAR | Output: LINEAR */ else if (inp_type == IS_LIN && out_type == IS_LIN) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - smpno = fread (lin_buff, sizeof (short), N, Fi); + smpno = audio_read (Fi, lin_buff, N); ulaw_compress (smpno, lin_buff, log_buff); ulaw_expand (smpno, log_buff, lon_buff); - smpno = fwrite (lon_buff, sizeof (short), smpno, Fo); + smpno = audio_write (Fo, lon_buff, smpno); } /* Input: LOG | Output: LINEAR */ else if (inp_type == IS_LOG) for (tot_smpno = cur_blk = 0; cur_blk < N2; cur_blk++, tot_smpno += smpno) { - smpno = fread (log_buff, sizeof (short), N, Fi); + smpno = audio_read (Fi, log_buff, N); ulaw_expand (smpno, log_buff, lon_buff); - smpno = fwrite (lon_buff, sizeof (short), smpno, Fo); + smpno = audio_write (Fo, lon_buff, smpno); } break; } @@ -437,8 +435,8 @@ int main (int argc, char *argv[]) { t2 = clock (); printf ("Speed: %f sec CPU-time for %ld processed samples\n", (t2 - t1) / (double) CLOCKS_PER_SEC, tot_smpno); - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); #ifndef VMS return (0); #endif diff --git a/src/g711iplc/CMakeLists.txt b/src/g711iplc/CMakeLists.txt index c8ed50fd..72e3506d 100644 --- a/src/g711iplc/CMakeLists.txt +++ b/src/g711iplc/CMakeLists.txt @@ -1,7 +1,7 @@ include_directories(../eid) include_directories(../utl) -add_executable(g711iplc g711iplc.c plcferio.c g711iplc.c lowcfe.c ../eid/softbit.c) +add_executable(g711iplc g711iplc.c plcferio.c g711iplc.c lowcfe.c ../eid/softbit.c ../utl/wav_io.c) target_compile_definitions(g711iplc PUBLIC USEDOUBLES=1) target_link_libraries(g711iplc ${M_LIBRARY}) diff --git a/src/g711iplc/g711iplc.c b/src/g711iplc/g711iplc.c index 30410b81..f6153f9f 100644 --- a/src/g711iplc/g711iplc.c +++ b/src/g711iplc/g711iplc.c @@ -47,6 +47,7 @@ #include #include "plcferio.h" #include "lowcfe.h" +#include "wav_io.h" char usage[] = "\ G711IPLC Version 1.0 of 24/May/2005\n\ @@ -72,8 +73,8 @@ int main (int argc, char *argv[]) { int nframes; /* processed frame count */ int nerased; /* erased frame count */ char *arg; - FILE *fi; /* input file */ - FILE *fo; /* output file */ + AUDIO_FILE *fi; /* input file */ + AUDIO_FILE *fo; /* output file */ LowcFE_c lc; /* PLC simulation data */ readplcmask mask; /* error pattern file reader */ short in[FRAMESZ]; /* i/o buffer */ @@ -98,17 +99,17 @@ int main (int argc, char *argv[]) { exit (EXIT_FAILURE); } readplcmask_open (&mask, argv[0]); /* PLC pattern file */ - if ((fi = fopen (argv[1], "rb")) == NULL) { /* input file */ + if ((fi = audio_open_read (argv[1], 0, 0, 16)) == NULL) { /* input file */ fprintf (stderr, "Can't open input file: %s", argv[1]); exit (EXIT_FAILURE); } - if ((fo = fopen (argv[2], "wb")) == NULL) { /* output file */ + if ((fo = audio_open_write (argv[2], 0, 1, 16)) == NULL) { /* output file */ fprintf (stderr, "Can't open output file: %s", argv[2]); exit (EXIT_FAILURE); } nframes = nerased = 0; g711plc_construct (&lc); - while (fread (in, sizeof (short), FRAMESZ, fi) == FRAMESZ) { + while (audio_read (fi, in, FRAMESZ) == FRAMESZ) { nframes++; if (readplcmask_erased (&mask)) { nerased++; /* frame is erased */ @@ -127,9 +128,9 @@ int main (int argc, char *argv[]) { * file is time-aligned with the input file. */ if (nframes == 1) - fwrite (&in[POVERLAPMAX], sizeof (short), FRAMESZ - POVERLAPMAX, fo); + audio_write (fo, &in[POVERLAPMAX], FRAMESZ - POVERLAPMAX); else - fwrite (in, sizeof (short), FRAMESZ, fo); + audio_write (fo, in, FRAMESZ); } /* * the following code outputs the delayed speech in the history buffer @@ -140,13 +141,13 @@ int main (int argc, char *argv[]) { for (i = 0; i < FRAMESZ; i++) in[i] = 0; g711plc_addtohistory (&lc, in); - fwrite (in, sizeof (short), POVERLAPMAX, fo); + audio_write (fo, in, POVERLAPMAX); } if (dostats && nframes) printf ("%d of %d frames concealed = %.2f%%\n", nerased, nframes, (double) nerased / nframes * 100.); /* cleanup */ - fclose (fo); - fclose (fi); + audio_close (fo); + audio_close (fi); readplcmask_close (&mask); return 0; } diff --git a/src/g722/CMakeLists.txt b/src/g722/CMakeLists.txt index 70e691ca..e89cc163 100644 --- a/src/g722/CMakeLists.txt +++ b/src/g722/CMakeLists.txt @@ -2,13 +2,13 @@ include_directories(../basop) include_directories(../eid) include_directories(../utl) -add_executable(g722demo g722demo.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c) +add_executable(g722demo g722demo.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c ../utl/wav_io.c) target_link_libraries(g722demo ${M_LIBRARY}) -add_executable(encg722 encg722.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c) +add_executable(encg722 encg722.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c ../utl/wav_io.c) target_link_libraries(encg722 ${M_LIBRARY}) -add_executable(decg722 decg722.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c) +add_executable(decg722 decg722.c funcg722.c g722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c ../utl/wav_io.c) target_link_libraries(decg722 ${M_LIBRARY}) add_executable(tstcg722 tstcg722.c funcg722.c funcg722.c ../basop/basop32.c ../basop/control.c ../basop/count.c ../basop/enh1632.c ../eid/softbit.c) diff --git a/src/g722/decg722.c b/src/g722/decg722.c index e2d10077..8803128c 100644 --- a/src/g722/decg722.c +++ b/src/g722/decg722.c @@ -85,6 +85,7 @@ FRANCE #include "g722.h" #include "ugstdemo.h" #include "g722_com.h" +#include "wav_io.h" #include "stl.h" @@ -221,7 +222,8 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STR], FileOut[MAX_STR]; - FILE *F_cod, *F_out; + FILE *F_cod; + AUDIO_FILE *F_out; long iter = 0; short N = DEF_FR_SIZE, N2 = 0, smpno = 0; long i = 0; @@ -354,7 +356,7 @@ int main (int argc, char *argv[]) { KILL (FileIn, -2); } /* Open output file */ - if ((F_out = fopen (FileOut, WB)) == NULL) { + if ((F_out = audio_open_write (FileOut, 0, 1, 16)) == NULL) { KILL (FileOut, -2); } @@ -556,7 +558,7 @@ int main (int argc, char *argv[]) { /* Update sample counter */ iter += smpno; /* Save a frame of decoded speech samples */ - if ((short) fwrite ((char *) outcode, sizeof (Word16), N, F_out) != N) { + if ((short) audio_write (F_out, outcode, N) != N) { KILL (FileOut, -4); } if (debug) { @@ -595,7 +597,7 @@ int main (int argc, char *argv[]) { iter += smpno; /* Save decoded samples */ - if ((short) fwrite ((char *) outcode, sizeof (Word16), N, F_out) != N) { + if ((short) audio_write (F_out, outcode, N) != N) { KILL (FileOut, -4); } if (debug) { @@ -609,7 +611,7 @@ int main (int argc, char *argv[]) { } /* Close input and output files */ - fclose (F_out); + audio_close (F_out); fclose (F_cod); /* Exit with success for non-vms systems */ diff --git a/src/g722/encg722.c b/src/g722/encg722.c index 44d7f2de..c8a0552c 100644 --- a/src/g722/encg722.c +++ b/src/g722/encg722.c @@ -84,6 +84,7 @@ FRANCE #include "g722.h" #include "ugstdemo.h" #include "g722_com.h" +#include "wav_io.h" #include "stl.h" @@ -131,7 +132,8 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STR], FileOut[MAX_STR]; - FILE *F_inp, *F_cod; + AUDIO_FILE *F_inp; + FILE *F_cod; long iter = 0; long frames = 1; /* number of processed frames */ @@ -240,7 +242,7 @@ int main (int argc, char *argv[]) { } /* Open input file */ - if ((F_inp = fopen (FileIn, RB)) == NULL) { + if ((F_inp = audio_open_read (FileIn, 0, 0, 16)) == NULL) { fprintf (stderr, "Could not open %s\n", FileIn); KILL (FileIn, -2); } @@ -262,7 +264,7 @@ int main (int argc, char *argv[]) { #endif /* Read one frame of samples from input file and process */ - while ((fread ((char *) incode, sizeof (short), N, F_inp)) == (size_t) N) { + while ((audio_read (F_inp, incode, N)) == (size_t) N) { #ifdef WMOPS setCounter (spe1Id); fwc (); @@ -370,7 +372,7 @@ int main (int argc, char *argv[]) { #endif /* Close input and output files */ - fclose (F_inp); + audio_close (F_inp); fclose (F_cod); /* Exit with success for non-vms systems */ diff --git a/src/g722/g722demo.c b/src/g722/g722demo.c index 678ab82a..0cc90a8c 100644 --- a/src/g722/g722demo.c +++ b/src/g722/g722demo.c @@ -81,6 +81,7 @@ /* G.722- and UGST-specific prototypes */ #include "g722.h" #include "ugstdemo.h" +#include "wav_io.h" /* Local definitions */ #define DFT_BLK 1024 @@ -161,7 +162,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[80], FileOut[80]; - FILE *inp, *out; + AUDIO_FILE *inp, *out; int read1; long iter = 0; long N = DFT_BLK, N1 = 1, N2 = 0, smpno = 0; @@ -264,11 +265,11 @@ int main (int argc, char *argv[]) { error_terminate ("Bad mode specified; aborting\n", 2); /* Open input file */ - if ((inp = fopen (FileIn, RB)) == NULL) + if ((inp = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, -2); /* Open output file */ - if ((out = fopen (FileOut, WB)) == NULL) + if ((out = audio_open_write (FileOut, 0, 1, 16)) == NULL) KILL (FileOut, -2); #ifndef STATIC_ALLOCATION @@ -327,7 +328,7 @@ int main (int argc, char *argv[]) { N /= 2; /* *** Read samples from input file and decode *** NOTE: Number of output samples: - if encoder + decoder, #inp samples = #out samples - if encoder only, #out samples = half of # of input samples - if decoder only, #out samples = double the # of input bitstream samples *** */ - while ((read1 = fread (incode, sizeof (short), N, inp)) != 0) { + while ((read1 = audio_read (inp, incode, N)) != 0) { /* print progress flag */ if (!quiet) fprintf (stderr, "%c\r", funny[(iter / read1) % 8]); @@ -360,7 +361,7 @@ int main (int argc, char *argv[]) { iter += smpno; /* Save bitstream or decoded samples */ - if (fwrite (out_buf, sizeof (Word16), read1, out) != (size_t) read1) + if (audio_write (out, out_buf, read1) != (size_t) read1) KILL (FileOut, -4); } @@ -382,8 +383,8 @@ int main (int argc, char *argv[]) { #endif /* Close input and output files */ - fclose (out); - fclose (inp); + audio_close (out); + audio_close (inp); /* Exit with success for non-vms systems */ #ifndef VMS diff --git a/src/g726/CMakeLists.txt b/src/g726/CMakeLists.txt index fe3cf65c..48da12aa 100644 --- a/src/g726/CMakeLists.txt +++ b/src/g726/CMakeLists.txt @@ -3,10 +3,10 @@ include_directories(../eid) include_directories(../g711) include_directories(../utl) -add_executable(vbr-g726 vbr-g726.c g726.c ../g711/g711.c) +add_executable(vbr-g726 vbr-g726.c g726.c ../g711/g711.c ../utl/wav_io.c) target_link_libraries(vbr-g726 ${M_LIBRARY}) -add_executable(g726demo g726demo.c g726.c) +add_executable(g726demo g726demo.c g726.c ../utl/wav_io.c) target_link_libraries(g726demo ${M_LIBRARY}) #Verification: g726demo diff --git a/src/g726/g726demo.c b/src/g726/g726demo.c index cdf1dd3f..afc14753 100644 --- a/src/g726/g726demo.c +++ b/src/g726/g726demo.c @@ -120,6 +120,7 @@ /* ..... G.726 module as include functions ..... */ #include "g726.h" +#include "wav_io.h" /* ------------------------------------------------------------------------- @@ -212,8 +213,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN], law[4], lilo[8]; - FILE *Fi, *Fo; - int inp, out; + AUDIO_FILE *Fi, *Fo; long start_byte; #ifdef VMS char mrs[15]; @@ -318,20 +318,18 @@ int main (int argc, char *argv[]) { */ /* Opening input file; abort if there's any problem */ - if ((Fi = fopen (FileIn, "rb")) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); - inp = fileno (Fi); /* Creates output file */ #ifdef VMS sprintf (mrs, "mrs=%d", 512); #endif - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) KILL (FileOut, 3); - out = fileno (Fo); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (fseek (Fi->fp, start_byte, 0) < 0l) KILL (FileIn, 4); /* @@ -344,7 +342,7 @@ int main (int argc, char *argv[]) { fprintf (stderr, "%c\r", funny[cur_blk % 8]); /* Read a block of samples */ - if ((smpno = fread (inp_buf, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, inp_buf, N)) < 0) KILL (FileIn, 5); /* Check if reset is needed */ @@ -361,7 +359,7 @@ int main (int argc, char *argv[]) { } /* Write ADPCM output word */ - if ((smpno = fwrite (out_buf, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, out_buf, smpno)) < 0) KILL (FileOut, 6); } @@ -370,8 +368,8 @@ int main (int argc, char *argv[]) { */ /* Close input and output files */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); /* Exit with success for non-vms systems */ #ifndef VMS diff --git a/src/g726/vbr-g726.c b/src/g726/vbr-g726.c index c0983029..4b19ea9c 100644 --- a/src/g726/vbr-g726.c +++ b/src/g726/vbr-g726.c @@ -139,6 +139,7 @@ /* ..... G.726 module as include functions ..... */ #include "g726.h" #include "g711.h" +#include "wav_io.h" /* ------------------------------------------------------------------------- @@ -302,8 +303,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; - int inp, out; + AUDIO_FILE *Fi, *Fo; long start_byte; #ifdef VMS char mrs[15]; @@ -451,20 +451,18 @@ int main (int argc, char *argv[]) { */ /* Opening input file; abort if there's any problem */ - if ((Fi = fopen (FileIn, "rb")) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); - inp = fileno (Fi); /* Creates output file */ #ifdef VMS sprintf (mrs, "mrs=%d", 512); #endif - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) KILL (FileOut, 3); - out = fileno (Fo); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (fseek (Fi->fp, start_byte, 0) < 0l) KILL (FileIn, 4); /* @@ -486,7 +484,7 @@ int main (int argc, char *argv[]) { #endif /* Read a block of samples */ - if ((smpno = fread (inp_buf, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, inp_buf, N)) < 0) KILL (FileIn, 5); /* Compress linear input samples */ @@ -521,7 +519,7 @@ int main (int argc, char *argv[]) { } /* Write ADPCM output word */ - if ((smpno = fwrite (out_buf, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, out_buf, smpno)) < 0) KILL (FileOut, 6); } @@ -536,8 +534,8 @@ int main (int argc, char *argv[]) { free (rate); /* Close input and output files */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); /* Exit with success for non-vms systems */ #ifndef VMS diff --git a/src/g727/CMakeLists.txt b/src/g727/CMakeLists.txt index 39e5f5a1..34198750 100644 --- a/src/g727/CMakeLists.txt +++ b/src/g727/CMakeLists.txt @@ -6,7 +6,7 @@ include_directories(../utl) add_executable(discard discard.c) target_link_libraries(discard ${M_LIBRARY}) -add_executable(g727demo g727demo.c g727.c ../g711/g711.c) +add_executable(g727demo g727demo.c g727.c ../g711/g711.c ../utl/wav_io.c) target_link_libraries(g727demo ${M_LIBRARY}) add_test(g727-1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/g727demo -q -core 4 -enh 0 -enc -law A test_data/speech.a-s test_data/speech44.iad) diff --git a/src/g727/g727demo.c b/src/g727/g727demo.c index b237bdaa..34e3fc34 100644 --- a/src/g727/g727demo.c +++ b/src/g727/g727demo.c @@ -103,6 +103,7 @@ /* ..... G.727 module as include functions ..... */ #include "g727.h" #include "../g711/g711.h" +#include "wav_io.h" /* Global variables */ @@ -200,8 +201,7 @@ int main (int argc, char **argv) { /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; - int inp, out; + AUDIO_FILE *Fi, *Fo; long start_byte; #ifdef VMS char mrs[15]; @@ -422,20 +422,18 @@ int main (int argc, char **argv) { */ /* Opening input file; abort if there's any problem */ - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); - inp = fileno (Fi); /* Creates output file */ #ifdef VMS sprintf (mrs, "mrs=%d", 512); #endif - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) KILL (FileOut, 3); - out = fileno (Fo); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (fseek (Fi->fp, start_byte, 0) < 0l) KILL (FileIn, 4); /* @@ -457,7 +455,7 @@ int main (int argc, char **argv) { #endif /* Read a block of samples */ - if ((smpno = fread (inp_buf, sizeof (short), N, Fi)) < 0) + if ((smpno = audio_read (Fi, inp_buf, N)) < 0) KILL (FileIn, 5); /* Compress linear input samples */ @@ -489,7 +487,7 @@ int main (int argc, char **argv) { } /* Write ADPCM output word */ - if ((smpno = fwrite (out_buf, sizeof (short), smpno, Fo)) < 0) + if ((smpno = audio_write (Fo, out_buf, smpno)) < 0) KILL (FileOut, 6); } @@ -499,8 +497,8 @@ int main (int argc, char **argv) { */ /* Close input and output files */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); /* Exit with success for non-vms systems */ #ifndef VMS diff --git a/src/iir/CMakeLists.txt b/src/iir/CMakeLists.txt index 3def9978..13b60508 100644 --- a/src/iir/CMakeLists.txt +++ b/src/iir/CMakeLists.txt @@ -1,12 +1,12 @@ include_directories(../utl) -add_executable(pcmdemo pcmdemo.c iir-g712.c iir-lib.c ../utl/ugst-utl.c) +add_executable(pcmdemo pcmdemo.c iir-g712.c iir-lib.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(pcmdemo ${M_LIBRARY}) -add_executable(cirsdemo cirsdemo.c iir-irs.c iir-lib.c ../utl/ugst-utl.c) +add_executable(cirsdemo cirsdemo.c iir-irs.c iir-lib.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(cirsdemo ${M_LIBRARY}) -add_executable(c712demo c712demo.c cascg712.c iir-lib.c ../utl/ugst-utl.c) +add_executable(c712demo c712demo.c cascg712.c iir-lib.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(c712demo ${M_LIBRARY}) add_test(pcmdemo1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/pcmdemo test_data/test.src test_data/testg712.100 1_1 0 0) diff --git a/src/iir/c712demo.c b/src/iir/c712demo.c index a9e57df3..184f8ef9 100644 --- a/src/iir/c712demo.c +++ b/src/iir/c712demo.c @@ -106,6 +106,7 @@ #include "ugstdemo.h" /* private defines for user interface */ #include "ugst-utl.h" /* conversion from float -> short */ #include "iirflt.h" /* G.712 IIR filtering functions */ +#include "wav_io.h" /* * ......... Definitions for this test program ......... @@ -195,7 +196,7 @@ int main (int argc, char *argv[]) { /* ......... File related variables ......... */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *inpfilptr, *outfilptr; + AUDIO_FILE *inpfilptr, *outfilptr; #if defined(VMS) static char mrs[15] = "mrs="; #endif @@ -255,11 +256,11 @@ int main (int argc, char *argv[]) { #endif GET_PAR_S (1, "_BIN-File to be processed: ............... ", inpfil); - if ((inpfilptr = fopen (inpfil, RB)) == NULL) + if ((inpfilptr = audio_open_read (inpfil, 0, 0, 16)) == NULL) error_terminate ("\n Error opening input file", 1); GET_PAR_S (2, "_BIN-Output File: ........................ ", outfil); - if ((outfilptr = fopen (outfil, WB)) == NULL) + if ((outfilptr = audio_open_write (outfil, audio_get_sample_rate (inpfilptr), 1, 16)) == NULL) error_terminate ("\n Error opening output file", 1); FIND_PAR_L (3, "_Segment Length for Filtering: ........... ", lseg, lseg); @@ -288,7 +289,7 @@ int main (int argc, char *argv[]) { lsegx = lseg; while (lsegx == lseg) { /* Read input buffer */ - lsegx = fread (sh_buff, sizeof (short), lseg, inpfilptr); + lsegx = audio_read (inpfilptr, sh_buff, lseg); /* convert short data to float in normalized range */ sh2fl_16bit (lsegx, sh_buff, fl_buff, 1); @@ -309,7 +310,7 @@ int main (int argc, char *argv[]) { /* Skip samples if requested */ if (lseg1 > skip) { /* Write samples to output file */ - nsam += fwrite (&sh_buff[skip], sizeof (short), (lseg1 - skip), outfilptr); + nsam += audio_write (outfilptr, &sh_buff[skip], (lseg1 - skip)); } else skip -= lseg1; } @@ -335,8 +336,8 @@ int main (int argc, char *argv[]) { cascade_iir_free (typ1_ptr); /* Close files */ - fclose (outfilptr); - fclose (inpfilptr); + audio_close (outfilptr); + audio_close (inpfilptr); #ifndef VMS return 0; diff --git a/src/iir/cirsdemo.c b/src/iir/cirsdemo.c index e6497411..76c0f40b 100644 --- a/src/iir/cirsdemo.c +++ b/src/iir/cirsdemo.c @@ -107,6 +107,7 @@ #include "ugstdemo.h" /* private defines for user interface */ #include "ugst-utl.h" /* conversion from float -> short */ #include "iirflt.h" /* IRS IIR filtering functions */ +#include "wav_io.h" /* * ......... Definitions for this test program ......... @@ -196,7 +197,7 @@ int main (int argc, char *argv[]) { /* ......... File related variables ......... */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *inpfilptr, *outfilptr; + AUDIO_FILE *inpfilptr, *outfilptr; #if defined(VMS) static char mrs[15] = "mrs="; #endif @@ -256,11 +257,11 @@ int main (int argc, char *argv[]) { #endif GET_PAR_S (1, "_BIN-File to be processed: ............... ", inpfil); - if ((inpfilptr = fopen (inpfil, RB)) == NULL) + if ((inpfilptr = audio_open_read (inpfil, 0, 0, 16)) == NULL) error_terminate ("\n Error opening input file", 1); GET_PAR_S (2, "_BIN-Output File: ........................ ", outfil); - if ((outfilptr = fopen (outfil, WB)) == NULL) + if ((outfilptr = audio_open_write (outfil, audio_get_sample_rate (inpfilptr), 1, 16)) == NULL) error_terminate ("\n Error opening output file", 1); FIND_PAR_L (3, "_Segment Length for Filtering: ........... ", lseg, lseg); @@ -289,7 +290,7 @@ int main (int argc, char *argv[]) { lsegx = lseg; while (lsegx == lseg) { /* Read input buffer */ - lsegx = fread (sh_buff, sizeof (short), lseg, inpfilptr); + lsegx = audio_read (inpfilptr, sh_buff, lseg); /* convert short data to float in normalized range */ sh2fl_16bit (lsegx, sh_buff, fl_buff, 1); @@ -310,7 +311,7 @@ int main (int argc, char *argv[]) { /* Skip samples if requested */ if (lseg1 > skip) { /* Write samples to output file */ - nsam += fwrite (&sh_buff[skip], sizeof (short), (lseg1 - skip), outfilptr); + nsam += audio_write (outfilptr, &sh_buff[skip], (lseg1 - skip)); skip = 0; } else skip -= lseg1; @@ -337,8 +338,8 @@ int main (int argc, char *argv[]) { cascade_iir_free (typ1_ptr); /* Close files */ - fclose (outfilptr); - fclose (inpfilptr); + audio_close (outfilptr); + audio_close (inpfilptr); #ifndef VMS return 0; diff --git a/src/iir/pcmdemo.c b/src/iir/pcmdemo.c index 1bef0696..1aa51439 100644 --- a/src/iir/pcmdemo.c +++ b/src/iir/pcmdemo.c @@ -137,6 +137,7 @@ #include "ugstdemo.h" /* private defines for user interface */ #include "ugst-utl.h" /* conversion from float -> short */ #include "iirflt.h" /* Standard PCM filtering functions */ +#include "wav_io.h" /* * ......... Definitions for this test program ......... @@ -243,7 +244,7 @@ int main (int argc, char *argv[]) { /* ......... File related variables ......... */ char inpfil[MAX_STRLEN], outfil[MAX_STRLEN]; - FILE *inpfilptr, *outfilptr; + AUDIO_FILE *inpfilptr, *outfilptr; #if defined(VMS) static char mrs[15] = "mrs=512"; #endif @@ -304,11 +305,11 @@ int main (int argc, char *argv[]) { /* ......... GETTING PARAMETERS ......... */ GET_PAR_S (1, "_BIN-File to be processed: ............... ", inpfil); - if ((inpfilptr = fopen (inpfil, RB)) == NULL) + if ((inpfilptr = audio_open_read (inpfil, 0, 0, 16)) == NULL) error_terminate ("\n Error opening input file", 1); GET_PAR_S (2, "_BIN-Output File: ........................ ", outfil); - if ((outfilptr = fopen (outfil, WB)) == NULL) + if ((outfilptr = audio_open_write (outfil, audio_get_sample_rate (inpfilptr), 1, 16)) == NULL) error_terminate ("\n Error opening output file", 1); GET_PAR_S (3, "_type of filter 1: ....................... ", typ1); @@ -402,7 +403,7 @@ int main (int argc, char *argv[]) { lsegx = lseg; while (lsegx == lseg) { /* Read input buffer */ - lsegx = fread (sh_buff, sizeof (short), lseg, inpfilptr); + lsegx = audio_read (inpfilptr, sh_buff, lseg); /* convert short data to float in normalized range */ sh2fl_16bit (lsegx, sh_buff, fl_buff, 1); @@ -487,7 +488,7 @@ int main (int argc, char *argv[]) { /* Skip samples if requested */ if (lseg1 > skip) { /* Write samples to output file */ - nsam += fwrite (&sh_buff[skip], sizeof (short), (lseg3 - skip), outfilptr); + nsam += audio_write (outfilptr, &sh_buff[skip], (lseg3 - skip)); skip = 0; } else skip -= lseg1; @@ -530,8 +531,8 @@ int main (int argc, char *argv[]) { #endif /* Close files */ - fclose (outfilptr); - fclose (inpfilptr); + audio_close (outfilptr); + audio_close (inpfilptr); #ifndef VMS return 0; diff --git a/src/mnru/CMakeLists.txt b/src/mnru/CMakeLists.txt index 51d6bf86..26dba2a7 100644 --- a/src/mnru/CMakeLists.txt +++ b/src/mnru/CMakeLists.txt @@ -1,12 +1,12 @@ include_directories(../utl) -add_executable(mnrudemo mnrudemo.c mnru.c ../utl/ugst-utl.c filtering_routines.c) +add_executable(mnrudemo mnrudemo.c mnru.c ../utl/ugst-utl.c filtering_routines.c ../utl/wav_io.c) target_link_libraries(mnrudemo ${M_LIBRARY}) add_executable(p50fbmnru p50fbmnru.c mnru.c ../utl/ugst-utl.c filtering_routines.c ) target_link_libraries(p50fbmnru ${M_LIBRARY}) -add_executable(snr calc-snr.c) +add_executable(snr calc-snr.c ../utl/wav_io.c) target_link_libraries(snr ${M_LIBRARY}) #TEST: MNRU diff --git a/src/mnru/calc-snr.c b/src/mnru/calc-snr.c index 62c37150..382ac564 100644 --- a/src/mnru/calc-snr.c +++ b/src/mnru/calc-snr.c @@ -51,6 +51,7 @@ #include #include #include +#include "wav_io.h" #if defined(VMS) #include @@ -136,7 +137,8 @@ int main (int argc, char *argv[]) { char out_is_file = NO, oper; int i, k, l, K; char File1[MAX_STRLEN], File2[MAX_STRLEN]; - FILE *F1, *F2, *Fo = stdout; + AUDIO_FILE *F1, *F2; + FILE *Fo = stdout; #ifdef VMS char mrs[15] = "mrs="; #endif @@ -232,16 +234,16 @@ int main (int argc, char *argv[]) { } /* Open input files */ - if ((F1 = fopen (File1, RB)) == NULL) + if ((F1 = audio_open_read (File1, 0, 0, 16)) == NULL) KILL (File1, 2); - if ((F2 = fopen (File2, RB)) == NULL) + if ((F2 = audio_open_read (File2, 0, 0, 16)) == NULL) KILL (File2, 3); /* Positions file to the starting of block N1 */ N1--; /* for the 1st block is not 1 but 0! */ - if (fseek (F1, N1 * N * sizeof (short), 0) != 0l) + if (fseek (F1->fp, N1 * N * sizeof (short), 0) != 0l) KILL (File1, 5); - if (fseek (F2, N1 * N * sizeof (short), 0) != 0l) + if (fseek (F2->fp, N1 * N * sizeof (short), 0) != 0l) KILL (File2, 6); /* Allocate memory for SNR vector */ @@ -266,7 +268,7 @@ int main (int argc, char *argv[]) { /* Down to work */ for (i = 0; i < N2; i++) { - if ((l = fread (a, sizeof (short), N, F1)) > 0 && (k = fread (b, sizeof (short), N, F2)) > 0) { + if ((l = audio_read (F1, a, N)) > 0 && (k = audio_read (F2, b, N)) > 0) { oper = i == 0 ? SNR_RESET : (i == N2 - 1 ? SNR_STOP : SNR_MEASURE); total_snr_dB = get_SNR (oper, a, b, N, N2, &state); } else { @@ -315,8 +317,8 @@ int main (int argc, char *argv[]) { } /* Closing... */ - fclose (F1); - fclose (F2); + audio_close (F1); + audio_close (F2); if (out_is_file) fclose (Fo); #ifndef VMS diff --git a/src/mnru/mnru.c b/src/mnru/mnru.c index bdb3c3b3..40b6580b 100644 --- a/src/mnru/mnru.c +++ b/src/mnru/mnru.c @@ -723,7 +723,7 @@ double *P50_MNRU_process(char operation, MNRU_state *s, double* input, double* o return (NULL); /* Seed for random number generation (NO LONGER USED) */ - s->seed = NULL; + s->seed = 0; /* Gain for signal path */ if (mode == MOD_NOISE) diff --git a/src/mnru/mnrudemo.c b/src/mnru/mnrudemo.c index a05f28a5..f2ca9765 100644 --- a/src/mnru/mnrudemo.c +++ b/src/mnru/mnrudemo.c @@ -75,6 +75,7 @@ /* ... Include of utilities ... */ #include "ugst-utl.h" +#include "wav_io.h" /* @@ -138,8 +139,7 @@ int main (int argc, char *argv[]) { /* File variables */ char FileIn[80], FileOut[80]; - FILE *Fi, *Fo; - int fhi, fho; + AUDIO_FILE *Fi, *Fo; #ifdef VMS char mrs[15]; #endif @@ -280,17 +280,15 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (mrs, "mrs=%d", 2 * N); #endif - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); - fhi = fileno (Fi); /* Creates output file */ - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) KILL (FileOut, 3); - fho = fileno (Fo); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (fseek (Fi->fp, start_byte, 0) < 0l) KILL (FileIn, 4); /* INSERTION OF MODULATED NOISE ACCORDING TO P.810 */ @@ -305,7 +303,7 @@ int main (int argc, char *argv[]) { /* Read samples ... */ for (cur_frame = 0; cur_frame < N2; cur_frame++) { /* Read samples ... */ - if ((l = fread (Buf, sizeof (short), N, Fi)) < 0) + if ((l = audio_read (Fi, Buf, N)) < 0) KILL (FileIn, 5); /* Information on processing phase */ @@ -330,7 +328,7 @@ int main (int argc, char *argv[]) { over += fl2sh_16bit ((long) l, out, Buf, 1); /* Save data to file */ - if ((l = fwrite (Buf, sizeof (short), l, Fo)) <= 0) + if ((l = audio_write (Fo, Buf, l)) <= 0) KILL (FileOut, 4); } @@ -341,8 +339,8 @@ int main (int argc, char *argv[]) { fprintf (stderr, "\nOverflow samples: %ld", over); fprintf (stderr, "\nClipped noise samples: %ld", state.clip); fprintf (stderr, "\n"); - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); #ifndef VMS return (0); #endif diff --git a/src/reverb/CMakeLists.txt b/src/reverb/CMakeLists.txt index 04e36d63..d6beb2d0 100644 --- a/src/reverb/CMakeLists.txt +++ b/src/reverb/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(../utl) -add_executable(reverb reverb.c reverb-lib.c) +add_executable(reverb reverb.c reverb-lib.c ../utl/wav_io.c) target_link_libraries(reverb ${M_LIBRARY}) #NOTE: Test depends on endianess! diff --git a/src/reverb/reverb.c b/src/reverb/reverb.c index 0c000ebc..0607e572 100644 --- a/src/reverb/reverb.c +++ b/src/reverb/reverb.c @@ -39,6 +39,7 @@ /* UGST modules */ #include "ugstdemo.h" +#include "wav_io.h" #include "reverb-lib.h" @@ -68,8 +69,8 @@ static void display_usage () { int main (int argc, char *argv[]) { /* File variables */ - FILE *ptr_fileIn; - FILE *ptr_fileOut; + AUDIO_FILE *ptr_fileIn; + AUDIO_FILE *ptr_fileOut; FILE *ptr_fileIR; char FileIn[MAX_STRLEN]; char FileIR[MAX_STRLEN]; @@ -149,14 +150,14 @@ int main (int argc, char *argv[]) { fclose (ptr_fileIR); /* open the input file */ - ptr_fileIn = fopen (FileIn, "rb"); + ptr_fileIn = audio_open_read (FileIn, 0, 0, 16); if (ptr_fileIn == NULL) { fprintf (stderr, "\nUnable to open Input file\n"); exit (-1); } /* open the output file */ - ptr_fileOut = fopen (FileOut, "wb"); + ptr_fileOut = audio_open_write (FileOut, 0, 1, 16); if (ptr_fileOut == NULL) { fprintf (stderr, "\nUnable to open Output file\n"); exit (-1); @@ -178,15 +179,15 @@ int main (int argc, char *argv[]) { /* .......FILTERING OPERATION ........ */ /* Filter the sound File */ - while (!feof (ptr_fileIn)) { - count = (long) fread (buffIn + N - 1, sizeof (short), N, ptr_fileIn); /* read a block of the input file */ + while (!feof (ptr_fileIn->fp)) { + count = (long) fread (buffIn + N - 1, sizeof (short), N, ptr_fileIn->fp); /* read a block of the input file */ local_sat_pos = conv (IR, buffIn, buffRvb, alignFact, N, count); /* convolves a block of the input file with the impulse response */ if (local_sat_pos >= 0) { fprintf (stderr, "\nWarning warning!! Saturation(s) in output file. In sample %ld\n", local_sat_pos + global_count); } global_count += count; - fwrite (buffRvb, sizeof (short), count, ptr_fileOut); /* output the processed block */ + fwrite (buffRvb, sizeof (short), count, ptr_fileOut->fp); /* output the processed block */ shift (buffIn, N); /* shift a part of the input buffer (to keep the N-1 last samples of the input file for the next processing) */ } @@ -201,8 +202,8 @@ int main (int argc, char *argv[]) { free (buffRvb); free (IR); /* close the opened files */ - fclose (ptr_fileIn); - fclose (ptr_fileOut); + audio_close (ptr_fileIn); + audio_close (ptr_fileOut); return (0); diff --git a/src/rpeltp/CMakeLists.txt b/src/rpeltp/CMakeLists.txt index 6ffd124b..0cd0c48e 100644 --- a/src/rpeltp/CMakeLists.txt +++ b/src/rpeltp/CMakeLists.txt @@ -1,7 +1,7 @@ include_directories(../g711) include_directories(../utl) -add_executable(rpedemo rpedemo.c add.c code.c debug.c decode.c long_ter.c lpc.c preproce.c rpe.c gsm_dest.c gsm_deco.c gsm_enco.c gsm_expl.c gsm_impl.c gsm_crea.c gsm_prin.c gsm_opti.c rpeltp.c short_te.c table.c ../g711/g711.c) +add_executable(rpedemo rpedemo.c add.c code.c debug.c decode.c long_ter.c lpc.c preproce.c rpe.c gsm_dest.c gsm_deco.c gsm_enco.c gsm_expl.c gsm_impl.c gsm_crea.c gsm_prin.c gsm_opti.c rpeltp.c short_te.c table.c ../g711/g711.c ../utl/wav_io.c) target_link_libraries(rpedemo ${M_LIBRARY}) add_executable(test-add add_test.c) diff --git a/src/rpeltp/rpedemo.c b/src/rpeltp/rpedemo.c index 562943b3..0f6a4ac3 100644 --- a/src/rpeltp/rpedemo.c +++ b/src/rpeltp/rpedemo.c @@ -120,6 +120,7 @@ #include "private.h" #include "gsm.h" #include "rpeltp.h" +#include "wav_io.h" /* ..... G.711 module definitions ..... */ #include "g711.h" @@ -205,7 +206,7 @@ int main (argc, argv) /* File variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; + AUDIO_FILE *Fi, *Fo; long start_byte; char format, run_encoder, run_decoder; #ifdef VMS @@ -325,14 +326,14 @@ int main (argc, argv) #endif /* Opening input/output files; abort if there's any problem */ - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (fseek (Fi->fp, start_byte, 0) < 0l) KILL (FileIn, 4); /* ......... CREATE AND INIT GSM OBJECT (STATE VARIABLE) ......... */ @@ -354,14 +355,14 @@ int main (argc, argv) memset (inp_buf, (int) 0, N); /* Read a block of uncoded samples */ - if ((smpno = fread (inp_buf, sizeof (short), (long) N, Fi)) <= 0) + if ((smpno = audio_read (Fi, inp_buf, (long) N)) <= 0) break; } else { /* Reset frame vector */ memset (rpe_frame, (int) 0, (long) RPE_FRAME_SIZE); /* Read a unpacked frame */ - if ((smpno = fread (rpe_frame, sizeof (short), (long) RPE_FRAME_SIZE, Fi)) <= 0) + if ((smpno = audio_read (Fi, rpe_frame, (long) RPE_FRAME_SIZE)) <= 0) break; } @@ -388,7 +389,7 @@ int main (argc, argv) } /* Save samples to file */ - if (!(smpno = fwrite (out_buf, sizeof (short), (long) smpno, Fo))) + if (!(smpno = audio_write (Fo, out_buf, (long) smpno))) break; } /* ENCODER-ONLY OPERATION */ @@ -401,7 +402,7 @@ int main (argc, argv) /* Run only the encoder, unpack frame and save rpe-ltp frame */ rpeltp_encode (rpe_enc_state, inp_buf, rpe_frame); - if (!(smpno = fwrite (rpe_frame, sizeof (short), RPE_FRAME_SIZE, Fo))) + if (!(smpno = audio_write (Fo, rpe_frame, RPE_FRAME_SIZE))) break; } /* DECODER-ONLY OPERATION */ @@ -416,23 +417,23 @@ int main (argc, argv) } /* Save the decoded samples */ - if (!(smpno = fwrite (out_buf, sizeof (short), (long) N, Fo))) + if (!(smpno = audio_write (Fo, out_buf, (long) N))) break; } count += smpno; } /* Check for errors */ - if (ferror (Fi)) + if (ferror (Fi->fp)) KILL (FileIn, 6); - else if (ferror (Fo)) + else if (ferror (Fo->fp)) KILL (FileOut, 7); /* ......... FINALIZATIONS ......... */ /* Close input and output files and state */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); rpeltp_delete (rpe_enc_state); rpeltp_delete (rpe_dec_state); diff --git a/src/stereoop/CMakeLists.txt b/src/stereoop/CMakeLists.txt index 6f2e55fa..f7f83808 100644 --- a/src/stereoop/CMakeLists.txt +++ b/src/stereoop/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(../utl) -add_executable(stereoop stereoop.c) +add_executable(stereoop stereoop.c ../utl/wav_io.c) target_link_libraries(stereoop ${M_LIBRARY}) add_test(stereoop1-interleave ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/stereoop -q -interleave test_data/sample.L.32k.1ch.smp test_data/sample.R.32k.1ch.smp test_data/sample.LR.32k.2ch.smp ) diff --git a/src/stereoop/stereoop.c b/src/stereoop/stereoop.c index 932c3e71..b04c62f6 100644 --- a/src/stereoop/stereoop.c +++ b/src/stereoop/stereoop.c @@ -25,6 +25,7 @@ v1.03 Feb 2, 2010: #include #include #include /* memset, strcmp */ +#include "wav_io.h" /* ..... Definitions used by the program ..... */ #define VERSION "stereoop.c 1.03 Feb 2, 2010" @@ -98,8 +99,8 @@ short n_infiles[N_MODES] = { 2, 1, 1, 1, 1, 1 }; short n_outfiles[N_MODES] = { 1, 2, 1, 1, 1, 1 }; int main (int argc, char *argv[]) { - FILE *Fif[MAX_IFILES]; /* Pointer to input files */ - FILE *Fof[MAX_OFILES]; /* Pointer to output files */ + AUDIO_FILE *Fif[MAX_IFILES]; /* Pointer to input files */ + AUDIO_FILE *Fof[MAX_OFILES]; /* Pointer to output files */ char ifname[MAX_IFILES][MAX_STRLEN]; /* Input file names */ char ofname[MAX_OFILES][MAX_STRLEN]; /* Output file names */ char tmp_str[MAX_STR]; @@ -180,13 +181,13 @@ int main (int argc, char *argv[]) { /* Open files */ for (i = 0; i < n_infiles[mode]; i++) { - if ((Fif[i] = fopen (ifname[i], RB)) == NULL) { + if ((Fif[i] = audio_open_read (ifname[i], 0, 0, 16)) == NULL) { sprintf (tmp_str, "Could not open input file %d,(%s)\n", i + 1, ifname[i]); error_terminate (tmp_str, 1); } } for (i = 0; i < n_outfiles[mode]; i++) { - if ((Fof[i] = fopen (ofname[i], WB)) == NULL) { + if ((Fof[i] = audio_open_write (ofname[i], 0, 1, 16)) == NULL) { sprintf (tmp_str, "Could not create output file %d,(%s)\n", i + 1, ofname[i]); error_terminate (tmp_str, 1); } @@ -195,11 +196,11 @@ int main (int argc, char *argv[]) { /* start of actual operation */ memset (tmp_short, 0, sizeof (short) * 2); if (mode == INTER) { /* read two mono file samples */ - while ((n_in = fread (tmp_short, sizeof (short), 1, Fif[0])) == 1) { - if ((n_in = fread (&tmp_short[1], sizeof (short), 1, Fif[1])) != 1) { + while ((n_in = audio_read (Fif[0], tmp_short, 1)) == 1) { + if ((n_in = audio_read (Fif[1], &tmp_short[1], 1)) != 1) { error_terminate ("Error, 1ch input file 2(right), shorter than 1ch input file 1(Left)\n", 1); } - if ((n_out = fwrite (tmp_short, sizeof (short), 2, Fof[0])) != 2) { + if ((n_out = audio_write (Fof[0], tmp_short, 2)) != 2) { error_terminate ("Error, could not write to 2ch output stereo file \n", 1); } cnt_samples++; @@ -207,18 +208,18 @@ int main (int argc, char *argv[]) { } /* while (1ch,1ch)->2ch */ /* check if samples are still available in right channel */ - if ((n_in = fread (&tmp_short[1], sizeof (short), 1, Fif[1])) != 0) { + if ((n_in = audio_read (Fif[1], &tmp_short[1], 1)) != 0) { error_terminate ("Error, 1ch input file 1(Left), shorter than 1ch input file 2(right)!\n", 1); } } else { /* reading of 2ch stereo file input samples */ - while ((n_in = fread (tmp_short, sizeof (short), 2, Fif[0])) == 2) { + while ((n_in = audio_read (Fif[0], tmp_short, 2)) == 2) { if (mode == SPLIT) { - if ((n_out = fwrite (tmp_short, sizeof (short), 1, Fof[0])) != 1) { + if ((n_out = audio_write (Fof[0], tmp_short, 1)) != 1) { error_terminate ("Error, could not write to 1ch output file 1 (Left)\n", 1); } - if ((n_out = fwrite (&tmp_short[1], sizeof (short), 1, Fof[1])) != 1) { + if ((n_out = audio_write (Fof[1], &tmp_short[1], 1)) != 1) { error_terminate ("Error, could not write to 1ch output file 2 (Right)\n", 1); } } else { /* all 2ch to 1ch options */ @@ -253,7 +254,7 @@ int main (int argc, char *argv[]) { error_terminate ("Error, illegal mode option\n", 1); break; } - if ((n_out = fwrite (tmp_short_1ch, sizeof (short), 1, Fof[0])) != 1) { + if ((n_out = audio_write (Fof[0], tmp_short_1ch, 1)) != 1) { error_terminate ("Error, could not write to 1ch output file 1\n", 1); } } @@ -273,10 +274,10 @@ int main (int argc, char *argv[]) { fprintf (stdout, "(Total %ld samples processed)\n\n", cnt_samples); } for (i = 0; i < n_infiles[mode]; i++) { - fclose (Fif[i]); + audio_close (Fif[i]); } for (i = 0; i < n_outfiles[mode]; i++) { - fclose (Fof[i]); + audio_close (Fof[i]); } return 0; } diff --git a/src/sv56/CMakeLists.txt b/src/sv56/CMakeLists.txt index 099a7861..023cf3db 100644 --- a/src/sv56/CMakeLists.txt +++ b/src/sv56/CMakeLists.txt @@ -1,10 +1,10 @@ include_directories(../g711) include_directories(../utl) -add_executable(sv56demo sv56demo.c sv-p56.c ../utl/ugst-utl.c) +add_executable(sv56demo sv56demo.c sv-p56.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(sv56demo ${M_LIBRARY}) -add_executable(actlev actlevel.c sv-p56.c ../utl/ugst-utl.c) +add_executable(actlev actlevel.c sv-p56.c ../utl/ugst-utl.c ../utl/wav_io.c) target_link_libraries(actlev ${M_LIBRARY}) add_test(sv56demo1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/sv56demo -q test_data/voice.src test_data/voice.prc 256 1 0 -30) diff --git a/src/sv56/actlevel.c b/src/sv56/actlevel.c index 0fc01e5d..2accc50d 100644 --- a/src/sv56/actlevel.c +++ b/src/sv56/actlevel.c @@ -155,6 +155,7 @@ /* ... Include of utilities ... */ #include "ugst-utl.h" +#include "wav_io.h" /* ... Local definitions ... */ #define DEF_BLK_LEN 256 /* samples per block */ @@ -423,7 +424,7 @@ int main (int argc, char *argv[]) { /* File-related variables */ char FileIn[150]; - FILE *Fi; /* input file pointer */ + AUDIO_FILE *Fi; /* input file pointer */ FILE *out = stdout; /* where to print the statistical results */ #ifdef VMS char mrs[15]; @@ -563,7 +564,7 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (mrs, "mrs=%d", 2 * N); #endif - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); /* Reinitialize number of blocks as specified initially */ @@ -577,7 +578,7 @@ int main (int argc, char *argv[]) { } /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (fseek (Fi->fp, start_byte, 0) < 0l) KILL (FileIn, 4); @@ -587,7 +588,7 @@ int main (int argc, char *argv[]) { if (!quiet) fprintf (stderr, " Processing \r"); for (i = 0; i < N2; i++) { - if ((l = fread (buffer, sizeof (short), N, Fi)) > 0) { + if ((l = audio_read (Fi, buffer, N)) > 0) { /* ... Convert samples to float */ sh2fl ((long) l, buffer, Buf, bitno, 1); @@ -681,7 +682,7 @@ int main (int argc, char *argv[]) { #endif /* LOCAL_PRINT */ /* Close current file */ - fclose (Fi); + audio_close (Fi); } /* FINALIZATIONS */ diff --git a/src/sv56/sv56demo.c b/src/sv56/sv56demo.c index 89fb4cc5..1caa436a 100644 --- a/src/sv56/sv56demo.c +++ b/src/sv56/sv56demo.c @@ -185,6 +185,7 @@ /* ... Include of utilities ... */ #include "ugst-utl.h" +#include "wav_io.h" /* Local definitions */ #define MIN_LOG_OFFSET 1.0e-20 /* To avoid sigularity with log(0.0) */ @@ -432,7 +433,7 @@ int main (int argc, char *argv[]) { /* File-related variables */ char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; - FILE *Fi, *Fo; /* input/output file pointers */ + AUDIO_FILE *Fi, *Fo; /* input/output file pointers */ FILE *out = stdout; /* where to print the statistical results */ #ifdef VMS char mrs[15]; @@ -586,15 +587,15 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (mrs, "mrs=%d", 2 * N); #endif - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); /* Creates output file */ - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi, start_byte, 0) < 0l) + if (fseek (Fi->fp, start_byte, 0) < 0l) KILL (FileIn, 4); @@ -607,7 +608,7 @@ int main (int argc, char *argv[]) { /* Process selected blocks */ for (i = 0; i < N2; i++) { /* Read samples ... */ - if ((l = fread (buffer, sizeof (short), N, Fi)) > 0) { + if ((l = audio_read (Fi, buffer, N)) > 0) { /* ... Convert samples to float */ sh2fl ((long) l, buffer, Buf, bitno, 1); @@ -645,12 +646,12 @@ int main (int argc, char *argv[]) { /* EQUALIZATION: hard clipping (with truncation) */ /* Move pointer to 1st desired block */ - if (fseek (Fi, start_byte, 0) < 0l) + if (fseek (Fi->fp, start_byte, 0) < 0l) KILL (FileIn, 4); /* Get data of interest, equalize and de-normalize */ for (i = 0; i < N2; i++) { - if ((l = fread (buffer, sizeof (short), N, Fi)) > 0) { + if ((l = audio_read (Fi, buffer, N)) > 0) { /* convert samples to float */ sh2fl ((long) l, buffer, Buf, bitno, 1); @@ -661,7 +662,7 @@ int main (int argc, char *argv[]) { NrSat += fl2sh ((long) l, Buf, buffer, (double) 0.0, mask[16 - bitno]); /* write equalized, de-normalized and hard-clipped samples to file */ - if ((l = fwrite (buffer, sizeof (short), l, Fo)) < 0) + if ((l = audio_write (Fo, buffer, l)) < 0) KILL (FileOut, 6); } else { KILL (FileIn, 5); @@ -680,8 +681,8 @@ int main (int argc, char *argv[]) { printf ("---> DONE \n"); /* Close files ... */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); if (out != stdout) fclose (out); #if !defined(VMS) diff --git a/src/unsup/CMakeLists.txt b/src/unsup/CMakeLists.txt index 03944831..9909f6f0 100644 --- a/src/unsup/CMakeLists.txt +++ b/src/unsup/CMakeLists.txt @@ -3,7 +3,7 @@ include_directories(../utl) add_executable(asc2bin asc2bin.c) target_link_libraries(asc2bin ${M_LIBRARY}) -add_executable(astrip astrip.c) +add_executable(astrip astrip.c ../utl/wav_io.c) target_link_libraries(astrip ${M_LIBRARY}) add_executable(bin2asc bin2asc.c) @@ -19,13 +19,13 @@ target_link_libraries(df ${M_LIBRARY}) add_executable(endian endian.c) -add_executable(fdelay fdelay.c) +add_executable(fdelay fdelay.c ../utl/wav_io.c) target_link_libraries(fdelay ${M_LIBRARY}) -add_executable(measure measure.c) +add_executable(measure measure.c ../utl/wav_io.c) target_link_libraries(measure ${M_LIBRARY}) -add_executable(oper oper.c) +add_executable(oper oper.c ../utl/wav_io.c) target_link_libraries(oper ${M_LIBRARY}) add_executable(sb sb.c) diff --git a/src/unsup/astrip.c b/src/unsup/astrip.c index 8e7dd52e..cdb5e7b1 100644 --- a/src/unsup/astrip.c +++ b/src/unsup/astrip.c @@ -61,6 +61,7 @@ ======================================================================== */ #include "ugstdemo.h" +#include "wav_io.h" /* OS definition */ #if defined(__MSDOS__) && !defined(MSDOS) @@ -180,7 +181,7 @@ int main (int argc, char *argv[]) { short *buf; /* file-related variables */ char File1[100], File2[100]; - FILE *fi, *fo; + AUDIO_FILE *fi, *fo; #ifdef VMS char mrs[15] = "mrs="; #endif @@ -329,13 +330,13 @@ int main (int argc, char *argv[]) { #endif /* Open input files */ - if ((fi = fopen (File1, RB)) == NULL) + if ((fi = audio_open_read (File1, 0, 0, 16)) == NULL) KILL (File1, 3); - if ((fo = fopen (File2, WB)) == NULL) + if ((fo = audio_open_write (File2, 0, 1, 16)) == NULL) KILL (File2, 4); /* Move pointer to 1st block of interest */ - if (fseek (fi, start_byte, 0l) < 0l) + if (fseek (fi->fp, start_byte, 0l) < 0l) KILL (File1, 3); /* Some preliminaries */ @@ -364,7 +365,7 @@ int main (int argc, char *argv[]) { fprintf (stderr, "%c\r", funny[count % 8]); /* Read samples from input buffer */ - if ((smpno = fread (buf, sizeof (short), N, fi)) == 0) + if ((smpno = audio_read (fi, buf, N)) == 0) break; else if (smpno < 0) KILL (File1, 2); @@ -424,13 +425,13 @@ int main (int argc, char *argv[]) { #endif } } - tot_samples += fwrite (buf, sizeof (short), smpno, fo); + tot_samples += audio_write (fo, buf, smpno); } /* ..... FINALIZATIONS ..... */ fprintf (stderr, "> Total %ld samples extracted\n", tot_samples); - fclose (fi); - fclose (fo); + audio_close (fi); + audio_close (fo); free (buf); #ifndef VMS return (0); diff --git a/src/unsup/fdelay.c b/src/unsup/fdelay.c index 57361b78..193b9363 100644 --- a/src/unsup/fdelay.c +++ b/src/unsup/fdelay.c @@ -65,6 +65,7 @@ #include /* for memset() */ #include #include "ugstdemo.h" +#include "wav_io.h" #if defined(VMS) #include @@ -93,13 +94,13 @@ ----------------------------------------------------------------------------- */ -long add_delay (short *smp_buf, short sample, short delay, FILE * Fdel, FILE * Fout, FILE * OutFile) { +long add_delay (short *smp_buf, short sample, short delay, AUDIO_FILE * Fdel, AUDIO_FILE * Fout, char * OutFile) { long saved = 0, smpno, i; if (Fdel) { /* Delay comes from a file */ - while ((smpno = fread (smp_buf, sizeof (short), delay, Fdel)) > 0) { - if ((smpno = fwrite (smp_buf, sizeof (short), smpno, Fout)) < 0) + while ((smpno = audio_read (Fdel, smp_buf, delay)) > 0) { + if ((smpno = audio_write (Fout, smp_buf, smpno)) < 0) KILL (OutFile, 7); saved += smpno; } @@ -107,7 +108,7 @@ long add_delay (short *smp_buf, short sample, short delay, FILE * Fdel, FILE * F /* Delay created here */ for (i = 0; i < delay; i++) smp_buf[i] = sample; - if ((saved = fwrite (smp_buf, sizeof (short), delay, Fout)) < delay) + if ((saved = audio_write (Fout, smp_buf, delay)) < delay) KILL (OutFile, 7); } @@ -180,7 +181,7 @@ int main (int argc, char *argv[]) { char InpFile[150], OutFile[150], *delay_file = 0; char quiet = 0, append = 0; short sample = 0; - FILE *Finp, *Fout, *Fdel = 0; + AUDIO_FILE *Finp, *Fout, *Fdel = 0; #ifdef VMS char mrs[15] = "mrs="; #endif @@ -315,13 +316,13 @@ int main (int argc, char *argv[]) { fprintf (stderr, "# %s %ld samples of value %ld (0x%04X).\n", append ? "Appending" : "Delaying", delay, sample, sample); /* Open files; abort on error */ - if ((Finp = fopen (InpFile, RB)) == NULL) + if ((Finp = audio_open_read (InpFile, 0, 0, 16)) == NULL) KILL (InpFile, 3); - if ((Fout = fopen (OutFile, WB)) == NULL) + if ((Fout = audio_open_write (OutFile, 0, 1, 16)) == NULL) KILL (OutFile, 4); if (delay_file) { /* Delay comes from a file - open delay file */ - if ((Fdel = fopen (delay_file, RB)) == NULL) + if ((Fdel = audio_open_read (delay_file, 0, 0, 16)) == NULL) KILL (delay_file, 5); } @@ -342,7 +343,7 @@ int main (int argc, char *argv[]) { } /* Move pointer to 1st block of interest */ - if (fseek (Finp, start_byte, 0) < 0l) + if (fseek (Finp->fp, start_byte, 0) < 0l) KILL (InpFile, 4); /* Put delay samples in begining of file, if *not* appending */ @@ -352,14 +353,14 @@ int main (int argc, char *argv[]) { /* Copy input file to output file */ for (i = 0; i < N2; i++) { /* Read a block of samples */ - if ((smpno = fread (smp_buf, sizeof (short), N, Finp)) < 0) + if ((smpno = audio_read (Finp, smp_buf, N)) < 0) KILL (InpFile, 6); /* Frame counter */ frame++; /* Write output words */ - if ((smpno = fwrite (smp_buf, sizeof (short), smpno, Fout)) < 0) + if ((smpno = audio_write (Fout, smp_buf, smpno)) < 0) KILL (OutFile, 7); /* Update sample counter */ @@ -375,10 +376,10 @@ int main (int argc, char *argv[]) { /* Free memory, close files */ free (smp_buf); - fclose (Finp); - fclose (Fout); + audio_close (Finp); + audio_close (Fout); if (Fdel) - fclose (Fdel); + audio_close (Fdel); return (0); } diff --git a/src/unsup/measure.c b/src/unsup/measure.c index 68cdddec..905f37ff 100644 --- a/src/unsup/measure.c +++ b/src/unsup/measure.c @@ -49,6 +49,7 @@ #include #include #include "ugstdemo.h" +#include "wav_io.h" /* Generic defines */ @@ -358,7 +359,7 @@ int main (int argc, char *argv[]) { double avg_x, rms_x, stddev_x, max_x, min_x; - FILE *Fi; + AUDIO_FILE *Fi; /* DEFAULT OPTIONS AND INITIAL VALUES */ @@ -418,13 +419,18 @@ int main (int argc, char *argv[]) { crc_x = init_crc_x; /* Open files */ - if (strcmp (inpfil, "-") == 0) - Fi = stdin; - else if ((Fi = fopen (inpfil, RB)) == NULL) + if (strcmp (inpfil, "-") == 0) { + /* stdin: wrap in a minimal AUDIO_FILE struct */ + static AUDIO_FILE stdin_af; + stdin_af.fp = stdin; + stdin_af.is_wav = 0; + stdin_af.write_mode = 0; + Fi = &stdin_af; + } else if ((Fi = audio_open_read (inpfil, 0, 0, 16)) == NULL) KILL (inpfil, 2); /* Move onto start */ - fseek (Fi, skip * blk * sizeof (short), 0); + fseek (Fi->fp, skip * blk * sizeof (short), 0); /* Allocate memory */ samples = (short *) calloc (blk, sizeof (short)); @@ -432,7 +438,7 @@ int main (int argc, char *argv[]) { error_terminate ("Cannot allocate memory - aborted\n", 1); /* Find statistics */ - while ((count = fread (samples, sizeof (short), blk, Fi)) != 0) { + while ((count = audio_read (Fi, samples, blk)) != 0) { /* Update statistics */ avg_x += get_sum (samples, count); rms_x += get_square (samples, count); @@ -478,7 +484,8 @@ int main (int argc, char *argv[]) { printf ("\t%s\n", inpfil); /* Close file */ - fclose (Fi); + if (strcmp (inpfil, "-") != 0) + audio_close (Fi); } /* EXITING */ diff --git a/src/unsup/oper.c b/src/unsup/oper.c index 92c87872..02473f85 100644 --- a/src/unsup/oper.c +++ b/src/unsup/oper.c @@ -96,6 +96,7 @@ #include /* for memset() */ #include #include "ugstdemo.h" +#include "wav_io.h" /* ... Includes for O.S. specific headers ... */ #if defined(MSDOS) @@ -224,7 +225,7 @@ double divide (double x, double y) { Operate over short int files ------------------------------------------------------------------------- */ -long operate_shorts (char *File1, char *File2, char *File3, int fh1, int fh2, int fh3, long N, long N1, long N2, double A, double B, double C, double (*oper_f) (), char trim_by, double round) { +long operate_shorts (char *File1, char *File2, char *File3, AUDIO_FILE *af1, AUDIO_FILE *af2, AUDIO_FILE *afr, long N, long N1, long N2, double A, double B, double C, double (*oper_f) (), char trim_by, double round) { long i, j, l, k, saved = 0; short *a, *b; register double tmp; @@ -243,7 +244,7 @@ long operate_shorts (char *File1, char *File2, char *File3, int fh1, int fh2, in memset (a, 0, N * sizeof (short)); memset (b, 0, N * sizeof (short)); - if ((l = read (fh1, a, sizeof (short) * N) / sizeof (short)) >= 0 && (k = read (fh2, b, sizeof (short) * N) / sizeof (short)) >= 0) + if ((l = audio_read (af1, a, N)) >= 0 && (k = audio_read (af2, b, N)) >= 0) while (j < l && j < k) { tmp = oper_f (A * (double) a[j], B * (double) b[j]) + C + round; b[j] = (short) (tmp > 32767 ? 32767 : (tmp < -32768 ? -32768 : tmp)); @@ -267,7 +268,7 @@ long operate_shorts (char *File1, char *File2, char *File3, int fh1, int fh2, in b[j] = (short) (tmp > 32767 ? 32767 : (tmp < -32768 ? -32768 : tmp)); } - saved += write (fh3, b, sizeof (short) * j) / sizeof (short); + saved += audio_write (afr, b, j); } return (saved); } @@ -278,7 +279,6 @@ long operate_shorts (char *File1, char *File2, char *File3, int fh1, int fh2, in int main (int argc, char *argv[]) { char c[1], Oper; - int fh1, fh2, fhr; long N, N1, N2, Prcd = 0; long delay = 0, start_byte1, start_byte2, samplesize; @@ -287,7 +287,7 @@ int main (int argc, char *argv[]) { char better_seed = USE_IT, trim_by = 0; static char *trim_str[4] = { "shortest", "first", "second", "longest" }; double A = 0, B = 0, C = 0, (*oper_f) (), round = 0.5; - FILE *f1, *f2, *fr; + AUDIO_FILE *f1, *f2, *fr; #ifdef VMS char mrs[15] = "mrs="; #endif @@ -516,15 +516,12 @@ int main (int argc, char *argv[]) { #endif /* Open input files */ - if ((f1 = fopen (File1, RB)) == NULL) + if ((f1 = audio_open_read (File1, 0, 0, 16)) == NULL) KILL (File1, 3); - if ((f2 = fopen (File2, RB)) == NULL) + if ((f2 = audio_open_read (File2, 0, 0, 16)) == NULL) KILL (File2, 4); - if ((fr = fopen (RFile, WB)) == NULL) + if ((fr = audio_open_write (RFile, 0, 1, 16)) == NULL) KILL (RFile, 5); - fh1 = fileno (f1); - fh2 = fileno (f2); - fhr = fileno (fr); /* If samples of the primary files are to be skipped, dump them into the output file */ if (delay > 0) { @@ -532,23 +529,23 @@ int main (int argc, char *argv[]) { short *a = (short *) calloc (sizeof (short), delay); double register tmp; - if (lseek (fh1, dump * samplesize, 0l) < 0l) + if (fseek (f1->fp, dump * samplesize, 0l) < 0l) KILL (File1, 3); - if (read (fh1, a, delay * samplesize) != samplesize * delay) + if (audio_read (f1, a, delay) != delay) KILL (File1, 6); for (i = 0; i < delay; i++) { tmp = (A * (double) a[i] + C + round); a[i] = (short) (tmp > 32767 ? 32767 : (tmp < -32768 ? -32768 : tmp)); } - write (fhr, a, delay * samplesize); + audio_write (fr, a, delay); free (a); } /* Move pointer to 1st block of interest */ - if (lseek (fh1, start_byte1, 0l) < 0l) + if (fseek (f1->fp, start_byte1, 0l) < 0l) KILL (File1, 3); - if (lseek (fh2, start_byte2, 0l) < 0l) + if (fseek (f2->fp, start_byte2, 0l) < 0l) KILL (File2, 4); /* Some preliminaries */ @@ -557,7 +554,7 @@ int main (int argc, char *argv[]) { /* Operates on the file to the screen */ switch (TypeOfData) { case 'I': /* short data */ - Prcd = operate_shorts (File1, File2, RFile, fh1, fh2, fhr, N, N1, N2, A, B, C, oper_f, trim_by, round); + Prcd = operate_shorts (File1, File2, RFile, f1, f2, fr, N, N1, N2, A, B, C, oper_f, trim_by, round); break; #ifdef DATA_TYPE_DEFINED @@ -577,8 +574,9 @@ int main (int argc, char *argv[]) { /* Finalizations */ - close (fh1); - close (fh2); + audio_close (f1); + audio_close (f2); + audio_close (fr); #ifndef VMS return (0); #endif diff --git a/src/utl/CMakeLists.txt b/src/utl/CMakeLists.txt index 98a00985..e195d661 100644 --- a/src/utl/CMakeLists.txt +++ b/src/utl/CMakeLists.txt @@ -1,10 +1,13 @@ add_executable(spdemo spdemo.c ugst-utl.c) target_link_libraries(spdemo ${M_LIBRARY}) -add_executable(scaldemo scaldemo.c ugst-utl.c) +add_executable(scaldemo scaldemo.c ugst-utl.c wav_io.c) target_link_libraries(scaldemo ${M_LIBRARY}) -add_executable(signal-diff signal-diff.c) +add_executable(signal-diff signal-diff.c wav_io.c) + +add_executable(test_wav_io test_wav_io.c wav_io.c) +add_test(wav_io ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_wav_io) #TODO Input file is not _yet_ there. add_test(scaldemo1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/scaldemo -q -trunc ../is54/test_data/voice.src test_data/voice.tru 256 1 0 0.5941352) diff --git a/src/utl/scaldemo.c b/src/utl/scaldemo.c index c4fc27e9..4eb8fb7f 100644 --- a/src/utl/scaldemo.c +++ b/src/utl/scaldemo.c @@ -86,6 +86,7 @@ #include "ugstdemo.h" #include "ugst-utl.h" +#include "wav_io.h" #ifdef VMS #include @@ -163,7 +164,7 @@ int main (int argc, char *argv[]) { char use_dB = 0, quiet = 0, pre_mask = 0; /* File variables */ - FILE *Fi, *Fo; + AUDIO_FILE *Fi, *Fo; char FileIn[MAX_STRLEN], FileOut[MAX_STRLEN]; #ifdef VMS char mrs[15]; @@ -334,15 +335,15 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (mrs, "mrs=%d", 2 * N); #endif - if ((Fi = fopen (FileIn, RB)) == NULL) + if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); /* Creates output file */ - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st desired block */ - if (fseek (Fi, start_byte, 0) < 0l) + if (fseek (Fi->fp, start_byte, 0) < 0l) KILL (FileIn, 4); /* Get data of interest, equalize and de-normalize */ @@ -352,7 +353,7 @@ int main (int argc, char *argv[]) { printf ("%c\r", funny[blk_count % 5]); /* Read block of data */ - if ((nsam = fread (s_buf, sizeof (short), N, Fi)) > 0) { + if ((nsam = audio_read (Fi, s_buf, N)) > 0) { /* convert samples to float */ sh2fl ((long) nsam, s_buf, f_buf, pre_mask ? bitno : 16, 1); @@ -363,7 +364,7 @@ int main (int argc, char *argv[]) { NrSat += fl2sh ((long) nsam, f_buf, s_buf, h, mask[16 - bitno]); /* write equalized, de-normalized and hard-clipped samples to file */ - if ((nsam = fwrite (s_buf, sizeof (short), nsam, Fo)) < 0) + if ((nsam = audio_write (Fo, s_buf, nsam)) < 0) KILL (FileOut, 6); /* Update total number of samples in file */ @@ -382,8 +383,8 @@ int main (int argc, char *argv[]) { printf ("---> DONE \n"); /* Close files, free memory */ - fclose (Fi); - fclose (Fo); + audio_close (Fi); + audio_close (Fo); free (f_buf); free (s_buf); diff --git a/src/utl/signal-diff.c b/src/utl/signal-diff.c index 2a176fb3..b9f6b3eb 100644 --- a/src/utl/signal-diff.c +++ b/src/utl/signal-diff.c @@ -55,6 +55,7 @@ #include #include #include "ugstdemo.h" +#include "wav_io.h" /* includes for DOS specific directives */ #if defined (MSDOS) @@ -106,8 +107,9 @@ int main (int argc, char *argv[]) { int i, j, k, l, K; char File1[50], File2[50]; - int fh1, fh2, fho; - FILE *F1, *F2, *Fo; + int fho; + AUDIO_FILE *F1, *F2; + FILE *Fo; long int N, N1, N2, NrDiffs = 0, NrEquivs = 0; long start_byte1, start_byte2, delay = 0; @@ -193,18 +195,16 @@ int main (int argc, char *argv[]) { } /* Open input files */ - if ((F1 = fopen (File1, RB)) == NULL) + if ((F1 = audio_open_read (File1, 0, 0, 16)) == NULL) KILL (File1, 2); - if ((F2 = fopen (File2, RB)) == NULL) + if ((F2 = audio_open_read (File2, 0, 0, 16)) == NULL) KILL (File2, 3); - fh1 = fileno (F1); - fh2 = fileno (F2); /* Positions file to the starting of block N1 */ N1--; /* for the 1st block is not 1 but 0! */ - if (lseek (fh1, start_byte1, 0) < 0l) + if (fseek (F1->fp, start_byte1, 0) < 0l) KILL (File1, 5); - if (lseek (fh2, start_byte2, 0) < 0l) + if (fseek (F2->fp, start_byte2, 0) < 0l) KILL (File2, 6); /* Print dump information */ @@ -217,7 +217,7 @@ int main (int argc, char *argv[]) { /* Dumps the file to the output (file or screen) */ for (NrDiffs = i = j = 0; i < N2; i++, j = 0) { - if ((l = read (fh1, a, 2 * N) / 2) > 0 && (k = read (fh2, b, 2 * N) / 2) > 0) { + if ((l = audio_read (F1, a, N)) > 0 && (k = audio_read (F2, b, N)) > 0) { if (out_is_file) { if (isatty (fileno (stderr)) && !quiet) fprintf (stderr, "Now processing block %d\t\t\r", i + 1); @@ -233,7 +233,7 @@ int main (int argc, char *argv[]) { if (ABS (b[j]) <= equiv && b[j] != 0) NrEquivs++; } - if ((K = write (fho, b, 2 * N)) != 2 * l) + if ((K = fwrite (b, sizeof (short), N, Fo)) != l) KILL (argv[6], 9); } else for (j = 0; j < l && j < k; j++) { @@ -280,8 +280,8 @@ int main (int argc, char *argv[]) { } /* Finalizations */ - fclose (F1); - fclose (F2); + audio_close (F1); + audio_close (F2); if (out_is_file) fclose (Fo); #ifndef VMS diff --git a/src/utl/test_wav_io.c b/src/utl/test_wav_io.c new file mode 100644 index 00000000..0e7f01bb --- /dev/null +++ b/src/utl/test_wav_io.c @@ -0,0 +1,262 @@ +/* test_wav_io.c - Test program for wav_io library + * + * Creates test WAV files, reads them back, and verifies correctness. + * Returns 0 on success, 1 on failure. + */ +#include +#include +#include +#include "wav_io.h" + +#define NSAMPLES 100 +#define TEST_RATE 8000 + +static int test_write_and_read_wav (void) { + AUDIO_FILE *af; + short buf_out[NSAMPLES], buf_in[NSAMPLES]; + long n; + int i; + + /* Generate test samples */ + for (i = 0; i < NSAMPLES; i++) + buf_out[i] = (short) (i * 100 - 5000); + + /* Write WAV */ + af = audio_open_write ("test_data/test_out.wav", TEST_RATE, 1, 16); + if (!af) { + fprintf (stderr, "FAIL: Cannot open test_out.wav for writing\n"); + return 1; + } + if (!audio_is_wav (af)) { + fprintf (stderr, "FAIL: test_out.wav not detected as WAV for writing\n"); + audio_close (af); + return 1; + } + n = audio_write (af, buf_out, NSAMPLES); + if (n != NSAMPLES) { + fprintf (stderr, "FAIL: Wrote %ld samples, expected %d\n", n, NSAMPLES); + audio_close (af); + return 1; + } + audio_close (af); + + /* Read back */ + af = audio_open_read ("test_data/test_out.wav", TEST_RATE, 1, 16); + if (!af) { + fprintf (stderr, "FAIL: Cannot open test_out.wav for reading\n"); + return 1; + } + if (!audio_is_wav (af)) { + fprintf (stderr, "FAIL: test_out.wav not detected as WAV\n"); + audio_close (af); + return 1; + } + if (audio_get_sample_rate (af) != TEST_RATE) { + fprintf (stderr, "FAIL: Sample rate %ld, expected %d\n", audio_get_sample_rate (af), TEST_RATE); + audio_close (af); + return 1; + } + if (audio_get_channels (af) != 1) { + fprintf (stderr, "FAIL: Channels %d, expected 1\n", audio_get_channels (af)); + audio_close (af); + return 1; + } + n = audio_read (af, buf_in, NSAMPLES); + if (n != NSAMPLES) { + fprintf (stderr, "FAIL: Read %ld samples, expected %d\n", n, NSAMPLES); + audio_close (af); + return 1; + } + audio_close (af); + + /* Verify samples */ + if (memcmp (buf_out, buf_in, NSAMPLES * sizeof (short)) != 0) { + fprintf (stderr, "FAIL: Sample data mismatch\n"); + return 1; + } + + printf ("PASS: write_and_read_wav\n"); + return 0; +} + +static int test_raw_file (void) { + AUDIO_FILE *af; + short buf_out[NSAMPLES], buf_in[NSAMPLES]; + long n; + int i; + + /* Write raw file directly */ + { + FILE *fp = fopen ("test_data/test_raw.pcm", "wb"); + if (!fp) { + fprintf (stderr, "FAIL: Cannot create test_raw.pcm\n"); + return 1; + } + for (i = 0; i < NSAMPLES; i++) + buf_out[i] = (short) (i * 50); + fwrite (buf_out, sizeof (short), NSAMPLES, fp); + fclose (fp); + } + + /* Read via audio_open_read */ + af = audio_open_read ("test_data/test_raw.pcm", 0, 0, 16); + if (!af) { + fprintf (stderr, "FAIL: Cannot open test_raw.pcm\n"); + return 1; + } + if (audio_is_wav (af)) { + fprintf (stderr, "FAIL: Raw file detected as WAV\n"); + audio_close (af); + return 1; + } + n = audio_read (af, buf_in, NSAMPLES); + if (n != NSAMPLES) { + fprintf (stderr, "FAIL: Read %ld samples from raw, expected %d\n", n, NSAMPLES); + audio_close (af); + return 1; + } + audio_close (af); + + if (memcmp (buf_out, buf_in, NSAMPLES * sizeof (short)) != 0) { + fprintf (stderr, "FAIL: Raw sample data mismatch\n"); + return 1; + } + + printf ("PASS: raw_file\n"); + return 0; +} + +static int test_raw_to_wav_output (void) { + AUDIO_FILE *af; + short buf[NSAMPLES]; + int i; + + for (i = 0; i < NSAMPLES; i++) + buf[i] = (short) (i * 10); + + /* Write to .wav extension — should produce WAV */ + af = audio_open_write ("test_data/test_ext.wav", 16000, 1, 16); + if (!af || !audio_is_wav (af)) { + fprintf (stderr, "FAIL: .wav extension not producing WAV output\n"); + if (af) + audio_close (af); + return 1; + } + audio_write (af, buf, NSAMPLES); + audio_close (af); + + /* Write to .pcm extension — should produce raw */ + af = audio_open_write ("test_data/test_ext.pcm", 16000, 1, 16); + if (!af || audio_is_wav (af)) { + fprintf (stderr, "FAIL: .pcm extension producing WAV output\n"); + if (af) + audio_close (af); + return 1; + } + audio_write (af, buf, NSAMPLES); + audio_close (af); + + printf ("PASS: raw_to_wav_output\n"); + return 0; +} + +static int test_rate_mismatch (void) { + AUDIO_FILE *af; + short buf[NSAMPLES]; + int i; + + /* Create a valid 8000 Hz WAV */ + for (i = 0; i < NSAMPLES; i++) + buf[i] = (short) i; + af = audio_open_write ("test_data/test_8k.wav", 8000, 1, 16); + if (!af) + return 1; + audio_write (af, buf, NSAMPLES); + audio_close (af); + + /* Try to open expecting 16000 Hz — should fail */ + af = audio_open_read ("test_data/test_8k.wav", 16000, 0, 16); + if (af != NULL) { + fprintf (stderr, "FAIL: Rate mismatch not detected\n"); + audio_close (af); + return 1; + } + + printf ("PASS: rate_mismatch\n"); + return 0; +} + +static int test_stereo_extraction (void) { + AUDIO_FILE *af; + short stereo_buf[NSAMPLES * 2], mono_buf[NSAMPLES]; + long n; + int i; + + /* Create stereo WAV: ch0 = i, ch1 = -i */ + for (i = 0; i < NSAMPLES; i++) { + stereo_buf[i * 2] = (short) i; + stereo_buf[i * 2 + 1] = (short) (-i); + } + af = audio_open_write ("test_data/test_stereo.wav", 8000, 2, 16); + if (!af) + return 1; + /* Write raw interleaved data directly for stereo */ + fwrite (stereo_buf, sizeof (short), NSAMPLES * 2, af->fp); + af->data_size += NSAMPLES * 2 * sizeof (short); + audio_close (af); + + /* Read back — should extract channel 0 */ + af = audio_open_read ("test_data/test_stereo.wav", 0, 0, 16); + if (!af) { + fprintf (stderr, "FAIL: Cannot open stereo WAV\n"); + return 1; + } + if (audio_get_channels (af) != 2) { + fprintf (stderr, "FAIL: Expected 2 channels, got %d\n", audio_get_channels (af)); + audio_close (af); + return 1; + } + n = audio_read (af, mono_buf, NSAMPLES); + if (n != NSAMPLES) { + fprintf (stderr, "FAIL: Read %ld samples, expected %d\n", n, NSAMPLES); + audio_close (af); + return 1; + } + audio_close (af); + + /* Verify channel 0 extracted */ + for (i = 0; i < NSAMPLES; i++) { + if (mono_buf[i] != (short) i) { + fprintf (stderr, "FAIL: Stereo extraction mismatch at sample %d: got %d, expected %d\n", i, mono_buf[i], i); + return 1; + } + } + + printf ("PASS: stereo_extraction\n"); + return 0; +} + +int main (void) { + int failures = 0; + + failures += test_write_and_read_wav (); + failures += test_raw_file (); + failures += test_raw_to_wav_output (); + failures += test_rate_mismatch (); + failures += test_stereo_extraction (); + + if (failures == 0) + printf ("\nAll wav_io tests PASSED\n"); + else + printf ("\n%d wav_io test(s) FAILED\n", failures); + + /* Clean up test files */ + remove ("test_data/test_out.wav"); + remove ("test_data/test_raw.pcm"); + remove ("test_data/test_ext.wav"); + remove ("test_data/test_ext.pcm"); + remove ("test_data/test_8k.wav"); + remove ("test_data/test_stereo.wav"); + + return failures ? 1 : 0; +} diff --git a/src/utl/wav_io.c b/src/utl/wav_io.c new file mode 100644 index 00000000..6e2f3899 --- /dev/null +++ b/src/utl/wav_io.c @@ -0,0 +1,396 @@ +/* wav_io.c - WAV file I/O support for STL tools + * + * Minimal canonical WAV (RIFF) reader/writer for 16-bit PCM. + * See wav_io.h for API documentation. + */ +#include "wav_io.h" +#include +#include +#include + +/* WAV format constants */ +#define WAV_RIFF_TAG 0x46464952 /* "RIFF" */ +#define WAV_WAVE_TAG 0x45564157 /* "WAVE" */ +#define WAV_FMT_TAG 0x20746D66 /* "fmt " */ +#define WAV_DATA_TAG 0x61746164 /* "data" */ +#define WAV_PCM_FORMAT 1 +#define WAV_FLOAT_FORMAT 3 +#define WAV_HEADER_SIZE 44 + +/* --- Helper: read little-endian integers from file --- */ + +static int read_u16 (FILE * fp, unsigned short *val) { + unsigned char b[2]; + if (fread (b, 1, 2, fp) != 2) + return 0; + *val = (unsigned short) (b[0] | (b[1] << 8)); + return 1; +} + +static int read_u32 (FILE * fp, unsigned long *val) { + unsigned char b[4]; + if (fread (b, 1, 4, fp) != 4) + return 0; + *val = (unsigned long) b[0] | ((unsigned long) b[1] << 8) | ((unsigned long) b[2] << 16) | ((unsigned long) b[3] << 24); + return 1; +} + +/* --- Helper: write little-endian integers to file --- */ + +static void write_u16 (FILE * fp, unsigned short val) { + unsigned char b[2]; + b[0] = (unsigned char) (val & 0xFF); + b[1] = (unsigned char) ((val >> 8) & 0xFF); + fwrite (b, 1, 2, fp); +} + +static void write_u32 (FILE * fp, unsigned long val) { + unsigned char b[4]; + b[0] = (unsigned char) (val & 0xFF); + b[1] = (unsigned char) ((val >> 8) & 0xFF); + b[2] = (unsigned char) ((val >> 16) & 0xFF); + b[3] = (unsigned char) ((val >> 24) & 0xFF); + fwrite (b, 1, 4, fp); +} + +/* --- Helper: case-insensitive extension check --- */ + +static int has_wav_extension (const char *filename) { + const char *dot; + dot = strrchr (filename, '.'); + if (!dot) + return 0; + if ((dot[1] == 'w' || dot[1] == 'W') && (dot[2] == 'a' || dot[2] == 'A') && (dot[3] == 'v' || dot[3] == 'V') && dot[4] == '\0') + return 1; + return 0; +} + +/* --- Public API --- */ + +AUDIO_FILE *audio_open_read (const char *filename, long expected_rate, int expected_channels, int expected_bits) { + AUDIO_FILE *af; + unsigned long riff_tag, file_size, wave_tag; + unsigned long chunk_id, chunk_size; + unsigned short audio_format, num_channels, bits_per_sample; + unsigned long sample_rate; + int fmt_found = 0; + + af = (AUDIO_FILE *) calloc (1, sizeof (AUDIO_FILE)); + if (!af) + return NULL; + + af->fp = fopen (filename, "rb"); + if (!af->fp) { + fprintf (stderr, "ERROR: Cannot open input file '%s'\n", filename); + free (af); + return NULL; + } + + af->write_mode = 0; + + /* Check for RIFF header */ + if (!read_u32 (af->fp, &riff_tag) || riff_tag != WAV_RIFF_TAG) { + /* Not a WAV file — treat as raw PCM */ + fseek (af->fp, 0, SEEK_SET); + af->is_wav = 0; + af->channels = 1; + af->sample_rate = 0; + af->bits_per_sample = 16; + af->data_offset = 0; + return af; + } + + /* Parse RIFF/WAVE header */ + if (!read_u32 (af->fp, &file_size) || !read_u32 (af->fp, &wave_tag) || wave_tag != WAV_WAVE_TAG) { + fprintf (stderr, "ERROR: '%s' has RIFF header but is not a WAVE file\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + + /* Find fmt and data chunks */ + while (read_u32 (af->fp, &chunk_id) && read_u32 (af->fp, &chunk_size)) { + if (chunk_id == WAV_FMT_TAG) { + if (!read_u16 (af->fp, &audio_format) || !read_u16 (af->fp, &num_channels) || !read_u32 (af->fp, &sample_rate)) { + fprintf (stderr, "ERROR: Cannot read fmt chunk in '%s'\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + /* Skip byte rate and block align */ + fseek (af->fp, 4 + 2, SEEK_CUR); + if (!read_u16 (af->fp, &bits_per_sample)) { + fprintf (stderr, "ERROR: Cannot read bits_per_sample in '%s'\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + /* Skip any extra fmt bytes */ + if (chunk_size > 16) + fseek (af->fp, chunk_size - 16, SEEK_CUR); + fmt_found = 1; + } else if (chunk_id == WAV_DATA_TAG) { + if (!fmt_found) { + fprintf (stderr, "ERROR: data chunk before fmt chunk in '%s'\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + af->data_offset = ftell (af->fp); + af->data_size = (long) chunk_size; + break; + } else { + /* Skip unknown chunk */ + fseek (af->fp, chunk_size, SEEK_CUR); + } + } + + if (!fmt_found || af->data_offset == 0) { + fprintf (stderr, "ERROR: Missing fmt or data chunk in '%s'\n", filename); + fclose (af->fp); + free (af); + return NULL; + } + + /* Validate format */ + if (audio_format != WAV_PCM_FORMAT && audio_format != WAV_FLOAT_FORMAT) { + fprintf (stderr, "ERROR: '%s' has unsupported WAV format (format tag=%d). Only PCM and IEEE float are supported.\n", filename, audio_format); + fclose (af->fp); + free (af); + return NULL; + } + + if (audio_format == WAV_FLOAT_FORMAT && bits_per_sample != 32) { + fprintf (stderr, "ERROR: '%s' is float WAV with %d bits (only 32-bit float supported).\n", filename, bits_per_sample); + fclose (af->fp); + free (af); + return NULL; + } + + if (audio_format == WAV_PCM_FORMAT && bits_per_sample != 8 && bits_per_sample != 16 && bits_per_sample != 24 && bits_per_sample != 32) { + fprintf (stderr, "ERROR: '%s' has unsupported bit depth (%d). Supported: 8, 16, 24, 32.\n", filename, bits_per_sample); + fclose (af->fp); + free (af); + return NULL; + } + + /* Check expected parameters */ + if (expected_bits > 0 && (int) bits_per_sample != expected_bits) { + fprintf (stderr, "ERROR: WAV bit depth (%d) does not match expected (%d) in '%s'\n", bits_per_sample, expected_bits, filename); + fclose (af->fp); + free (af); + return NULL; + } + + if (expected_rate > 0 && (long) sample_rate != expected_rate) { + fprintf (stderr, "ERROR: WAV sample rate (%lu Hz) does not match expected rate (%ld Hz) in '%s'\n", sample_rate, expected_rate, filename); + fclose (af->fp); + free (af); + return NULL; + } + + if (expected_channels > 0 && (int) num_channels != expected_channels) { + fprintf (stderr, "ERROR: WAV channel count (%d) does not match expected channels (%d) in '%s'\n", num_channels, expected_channels, filename); + fclose (af->fp); + free (af); + return NULL; + } + + af->is_wav = 1; + af->channels = (int) num_channels; + af->sample_rate = (long) sample_rate; + af->bits_per_sample = (int) bits_per_sample; + af->audio_format = (int) audio_format; + + return af; +} + + +AUDIO_FILE *audio_open_write (const char *filename, long sample_rate, int channels, int bits_per_sample) { + AUDIO_FILE *af; + + af = (AUDIO_FILE *) calloc (1, sizeof (AUDIO_FILE)); + if (!af) + return NULL; + + af->fp = fopen (filename, "wb"); + if (!af->fp) { + fprintf (stderr, "ERROR: Cannot open output file '%s'\n", filename); + free (af); + return NULL; + } + + af->write_mode = 1; + af->sample_rate = sample_rate; + af->channels = channels; + af->bits_per_sample = bits_per_sample > 0 ? bits_per_sample : 16; + + if (has_wav_extension (filename)) { + af->is_wav = 1; + /* Write placeholder WAV header (44 bytes) — updated on close */ + write_u32 (af->fp, WAV_RIFF_TAG); + write_u32 (af->fp, 0); /* file size - 8 (placeholder) */ + write_u32 (af->fp, WAV_WAVE_TAG); + /* fmt chunk */ + write_u32 (af->fp, WAV_FMT_TAG); + write_u32 (af->fp, 16); /* fmt chunk size */ + write_u16 (af->fp, WAV_PCM_FORMAT); + write_u16 (af->fp, (unsigned short) af->channels); + write_u32 (af->fp, (unsigned long) af->sample_rate); + write_u32 (af->fp, (unsigned long) (af->sample_rate * af->channels * af->bits_per_sample / 8)); /* byte rate */ + write_u16 (af->fp, (unsigned short) (af->channels * af->bits_per_sample / 8)); /* block align */ + write_u16 (af->fp, (unsigned short) af->bits_per_sample); + /* data chunk header */ + write_u32 (af->fp, WAV_DATA_TAG); + write_u32 (af->fp, 0); /* data size (placeholder) */ + af->data_offset = ftell (af->fp); + af->data_size = 0; + } else { + af->is_wav = 0; + af->data_size = 0; + } + + return af; +} + + +long audio_read (AUDIO_FILE * af, void *buffer, long nsamples) { + int bps, ch, sample_bytes, frame_bytes; + long frames_read, i; + + if (!af || !af->fp || !buffer || nsamples <= 0) + return 0; + + bps = af->bits_per_sample; + ch = af->is_wav ? af->channels : 1; + sample_bytes = (bps == 24) ? 3 : (bps / 8); + frame_bytes = sample_bytes * ch; + + /* Simple case: mono or raw, and not 24-bit (can fread directly) */ + if (ch <= 1 && bps != 24) { + return (long) fread (buffer, (size_t) sample_bytes, (size_t) nsamples, af->fp); + } + + /* Multi-channel extraction or 24-bit unpacking */ + { + unsigned char *raw_buf; + + if (ch > 1 && !af->warned_multichan) { + fprintf (stderr, "WARNING: Multi-channel WAV (%d channels). Extracting channel 1 only.\n", ch); + af->warned_multichan = 1; + } + + raw_buf = (unsigned char *) malloc ((size_t) (nsamples * frame_bytes)); + if (!raw_buf) + return 0; + + frames_read = (long) fread (raw_buf, (size_t) frame_bytes, (size_t) nsamples, af->fp); + + if (bps == 8) { + unsigned char *out = (unsigned char *) buffer; + for (i = 0; i < frames_read; i++) + out[i] = raw_buf[i * frame_bytes]; + } else if (bps == 16) { + short *out = (short *) buffer; + for (i = 0; i < frames_read; i++) { + unsigned char *p = raw_buf + i * frame_bytes; + out[i] = (short) (p[0] | (p[1] << 8)); + } + } else if (bps == 24) { + long *out = (long *) buffer; + for (i = 0; i < frames_read; i++) { + unsigned char *p = raw_buf + i * frame_bytes; + out[i] = (long) p[0] | ((long) p[1] << 8) | ((long) (signed char) p[2] << 16); + } + } else if (bps == 32) { + long *out = (long *) buffer; + if (af->audio_format == WAV_FLOAT_FORMAT) { + float *fout = (float *) buffer; + for (i = 0; i < frames_read; i++) { + unsigned char *p = raw_buf + i * frame_bytes; + union { unsigned char b[4]; float f; } u; + u.b[0] = p[0]; u.b[1] = p[1]; u.b[2] = p[2]; u.b[3] = p[3]; + fout[i] = u.f; + } + } else { + for (i = 0; i < frames_read; i++) { + unsigned char *p = raw_buf + i * frame_bytes; + out[i] = (long) p[0] | ((long) p[1] << 8) | ((long) p[2] << 16) | ((long) (signed char) p[3] << 24); + } + } + } + + free (raw_buf); + return frames_read; + } +} + + +long audio_write (AUDIO_FILE * af, void *buffer, long nsamples) { + int bps, sample_bytes; + long n, i; + + if (!af || !af->fp || !buffer || nsamples <= 0) + return 0; + + bps = af->bits_per_sample; + sample_bytes = (bps == 24) ? 3 : (bps / 8); + + if (bps != 24) { + /* 8, 16, 32-bit or float: direct fwrite */ + n = (long) fwrite (buffer, (size_t) sample_bytes, (size_t) nsamples, af->fp); + af->data_size += n * sample_bytes; + return n; + } + + /* 24-bit: pack from long */ + { + long *in = (long *) buffer; + for (i = 0; i < nsamples; i++) { + unsigned char b[3]; + long val = in[i]; + b[0] = (unsigned char) (val & 0xFF); + b[1] = (unsigned char) ((val >> 8) & 0xFF); + b[2] = (unsigned char) ((val >> 16) & 0xFF); + if (fwrite (b, 1, 3, af->fp) != 3) + break; + } + af->data_size += i * 3; + return i; + } +} + + +void audio_close (AUDIO_FILE * af) { + if (!af) + return; + + if (af->fp) { + if (af->write_mode && af->is_wav) { + /* Update WAV header with final sizes */ + unsigned long file_size = (unsigned long) af->data_size + WAV_HEADER_SIZE - 8; + fseek (af->fp, 4, SEEK_SET); + write_u32 (af->fp, file_size); + fseek (af->fp, WAV_HEADER_SIZE - 4, SEEK_SET); + write_u32 (af->fp, (unsigned long) af->data_size); + } + fclose (af->fp); + } + + free (af); +} + + +int audio_is_wav (AUDIO_FILE * af) { + return af ? af->is_wav : 0; +} + + +long audio_get_sample_rate (AUDIO_FILE * af) { + return af ? af->sample_rate : 0; +} + + +int audio_get_channels (AUDIO_FILE * af) { + return af ? af->channels : 0; +} diff --git a/src/utl/wav_io.h b/src/utl/wav_io.h new file mode 100644 index 00000000..cbadd2f8 --- /dev/null +++ b/src/utl/wav_io.h @@ -0,0 +1,63 @@ +/* wav_io.h - WAV file I/O support for STL tools + * + * Provides transparent reading/writing of WAV and raw PCM files. + * Input format is auto-detected (RIFF header check). + * Output format is determined by filename extension (.wav = WAV, else raw). + * Only 16-bit PCM WAV is supported. + */ +#ifndef WAV_IO_H +#define WAV_IO_H + +#include + +typedef struct { + FILE *fp; + int is_wav; /* 1 if WAV format, 0 if raw PCM */ + int channels; /* Number of channels (from WAV header, or 1 for raw) */ + long sample_rate; /* Sample rate in Hz (from WAV header, or 0 for raw) */ + int bits_per_sample; /* Bits per sample (from WAV header, or 16 for raw) */ + int audio_format; /* WAV format tag: 1=PCM, 3=IEEE float (0 for raw) */ + long data_offset; /* Byte offset to start of PCM data */ + long data_size; /* Bytes of PCM data written (for WAV write) */ + int warned_multichan; /* Flag: already warned about multi-channel extraction */ + int write_mode; /* 1 if opened for writing, 0 for reading */ +} AUDIO_FILE; + +/* Open file for reading. Auto-detects WAV vs raw PCM. + * expected_rate: if > 0, error if WAV sample rate doesn't match + * expected_channels: if > 0, error if WAV channel count doesn't match + * expected_bits: if > 0, error if WAV bits_per_sample doesn't match + * Returns NULL on error (prints message to stderr). */ +AUDIO_FILE *audio_open_read (const char *filename, long expected_rate, int expected_channels, int expected_bits); + +/* Open file for writing. Writes WAV if filename ends in .wav, raw otherwise. + * sample_rate/channels/bits_per_sample used for WAV header. + * For raw output, these are ignored. + * Returns NULL on error. */ +AUDIO_FILE *audio_open_write (const char *filename, long sample_rate, int channels, int bits_per_sample); + +/* Read up to nsamples into buffer, using the appropriate sample size + * based on the file's bits_per_sample (8/16/24/32-bit PCM or 32-bit float). + * Buffer must be large enough for the native sample size. + * For multi-channel WAV, extracts channel 0 (warns once on stderr). + * Returns number of samples actually read. */ +long audio_read (AUDIO_FILE * af, void *buffer, long nsamples); + +/* Write nsamples from buffer, using the appropriate sample size + * based on the file's bits_per_sample. + * Returns number of samples actually written. */ +long audio_write (AUDIO_FILE * af, void *buffer, long nsamples); + +/* Close file. For WAV output, updates header with final data size. */ +void audio_close (AUDIO_FILE * af); + +/* Returns 1 if file was detected/opened as WAV, 0 if raw */ +int audio_is_wav (AUDIO_FILE * af); + +/* Returns sample rate from WAV header (0 if raw) */ +long audio_get_sample_rate (AUDIO_FILE * af); + +/* Returns channel count from WAV header (0 if raw) */ +int audio_get_channels (AUDIO_FILE * af); + +#endif /* WAV_IO_H */ From 7f4946ed22691a0838b2bf5248d79818f3d53342 Mon Sep 17 00:00:00 2001 From: Ludovic Malfait Date: Sat, 30 May 2026 11:20:13 +0100 Subject: [PATCH 2/7] Fix WAV I/O: propagate sample rate, validate parameters, fix seeking - Propagate sample rate from input to output in all 18 tools that previously passed 0 to audio_open_write - Validate WAV sample rate against codec's intrinsic rate (g711=8k, g722=16k, g726/g727=8k, bs1770=48k) or user-specified -sf/-fs - Make -sf/-fs optional with WAV input: if omitted, use WAV header rate directly (sv56demo, actlevel, filter, esdru, freqresp) - Add audio_seek() to fix fseek calls that ignored WAV data_offset - Add audio_get_data_size() to fix stat()-based size calculations that included WAV header bytes - Add 108 integration tests covering WAV input (matching/mismatching parameters), WAV output header validation, and optional -sf behavior - Add mkwav and test_wav_io_validate test utilities --- src/bs1770demo/bs1770demo.c | 4 +- src/esdru/esdru.c | 8 +- src/fir/filter.c | 23 +- src/freqresp/freqresp.c | 8 +- src/g711/g711demo.c | 10 +- src/g711iplc/g711iplc.c | 4 +- src/g722/decg722.c | 2 +- src/g722/encg722.c | 2 +- src/g722/g722demo.c | 4 +- src/g726/g726demo.c | 19 +- src/g726/vbr-g726.c | 19 +- src/g727/g727demo.c | 19 +- src/mnru/mnrudemo.c | 17 +- src/reverb/reverb.c | 2 +- src/rpeltp/rpedemo.c | 28 +- src/stereoop/stereoop.c | 2 +- src/sv56/actlevel.c | 12 +- src/sv56/sv56demo.c | 25 +- src/unsup/astrip.c | 23 +- src/unsup/fdelay.c | 10 +- src/unsup/oper.c | 49 +-- src/utl/CMakeLists.txt | 5 + src/utl/mkwav.c | 48 +++ src/utl/scaldemo.c | 17 +- src/utl/test_wav_integration.cmake | 567 +++++++++++++++++++++++++++++ src/utl/test_wav_io_validate.c | 39 ++ src/utl/wav_io.c | 22 ++ src/utl/wav_io.h | 11 + 28 files changed, 835 insertions(+), 164 deletions(-) create mode 100644 src/utl/mkwav.c create mode 100644 src/utl/test_wav_integration.cmake create mode 100644 src/utl/test_wav_io_validate.c diff --git a/src/bs1770demo/bs1770demo.c b/src/bs1770demo/bs1770demo.c index d9093286..674226ad 100644 --- a/src/bs1770demo/bs1770demo.c +++ b/src/bs1770demo/bs1770demo.c @@ -478,7 +478,7 @@ int main(int argc, char **argv ) } input_filename = argv[i++]; - if( (f_input = audio_open_read (input_filename, 0, 0, 16)) == NULL ) + if( (f_input = audio_open_read (input_filename, 48000, 0, 16)) == NULL ) { fprintf( stderr, "*** Could not open input file %s, exiting..\n\n", input_filename ); usage(); @@ -490,7 +490,7 @@ int main(int argc, char **argv ) else { output_filename = argv[i]; - if( (f_output = audio_open_write( output_filename, 0, 1, 16 )) == NULL ) + if( (f_output = audio_open_write( output_filename, audio_get_sample_rate (f_input), 1, 16 )) == NULL ) { fprintf( stderr, "*** Could not open output file %s, exiting..\n\n", output_filename ); usage(); diff --git a/src/esdru/esdru.c b/src/esdru/esdru.c index d4d4c7d1..934b4b57 100644 --- a/src/esdru/esdru.c +++ b/src/esdru/esdru.c @@ -287,6 +287,7 @@ int main(int argc, char **argv ) long step; long length; long fs; + int fs_given = 0; long clip; long i; short energy_input; @@ -316,6 +317,7 @@ int main(int argc, char **argv ) fprintf(stderr, "Invalid sampling frequency %s, exiting..\n", argv[i + 1] ); usage(); } + fs_given = 1; i += 2; } else if( strcmp( argv[i], "-e_step" ) == 0 ) @@ -399,12 +401,14 @@ int main(int argc, char **argv ) } input_filename = argv[i++]; output_filename = argv[i]; - if( (f_input = audio_open_read (input_filename, 0, 0, 16)) == NULL ) + if( (f_input = audio_open_read (input_filename, fs_given ? fs : 0, 0, 16)) == NULL ) { fprintf( stderr, "Could not open input file %s, exiting..\n\n", input_filename ); usage(); } - if( (f_output = audio_open_write( output_filename, 0, 1, 16 )) == NULL ) + if (audio_get_sample_rate (f_input) > 0) + fs = audio_get_sample_rate (f_input); + if( (f_output = audio_open_write( output_filename, fs, 1, 16 )) == NULL ) { fprintf( stderr, "Could not open output file %s, exiting..\n\n", output_filename ); usage(); diff --git a/src/fir/filter.c b/src/fir/filter.c index 1208eba9..cc8b6d42 100644 --- a/src/fir/filter.c +++ b/src/fir/filter.c @@ -319,6 +319,7 @@ int main (int argc, char *argv[]) { char modified_IRS = 0, quiet = 0; long inp_size, out_size, factor, smpno; double fs = 8000; + int fs_given = 0; char kernel_type = 0; static char funny[9] = "|/-\\|/-\\"; @@ -352,6 +353,7 @@ int main (int argc, char *argv[]) { } else if (strcmp (argv[1], "-fs") == 0) { /* Change sampling frequency */ fs = atof (argv[2]); + fs_given = 1; /* Move arg{c,v} over the option to the next argument */ argc -= 2; @@ -438,14 +440,7 @@ int main (int argc, char *argv[]) { start_byte += skip * sizeof (short); #endif - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); - } + /* N2 will be computed after opening file if processing the whole file */ inp_size = N; /* samples */ @@ -760,15 +755,21 @@ int main (int argc, char *argv[]) { #endif /* Opening input file; abort if there's any problem */ - if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) + if ((Fi = audio_open_read (FileIn, fs_given ? (long) fs : 0, 0, 16)) == NULL) KILL (FileIn, 2); + if (audio_get_sample_rate (Fi) > 0) + fs = (double) audio_get_sample_rate (Fi); + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); /* Creates output file */ - if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) + if ((Fo = audio_open_write (FileOut, (long) fs, 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi->fp, start_byte, 0)) + if (audio_seek (Fi, start_byte)) KILL (FileIn, 4); diff --git a/src/freqresp/freqresp.c b/src/freqresp/freqresp.c index b9fd21d4..6b294f3b 100644 --- a/src/freqresp/freqresp.c +++ b/src/freqresp/freqresp.c @@ -125,6 +125,7 @@ int main (int argc, char *argv[]) { /* algorithm variables */ int nfft = 2048; long fs = 16000; /* sampling frequency */ + int fs_given = 0; int little_endian; /* flag =1 if little-endian, else =0 */ int i, j; int nbread; @@ -154,6 +155,7 @@ int main (int argc, char *argv[]) { if (strcmp (argv[1], "-fs") == 0) { /* Set the sampling frequency parameter */ fs = atol (argv[2]); + fs_given = 1; /* Move arg{c,v} over the option to the next argument */ argc -= 2; @@ -280,11 +282,13 @@ int main (int argc, char *argv[]) { /* ..... First File ..... */ /* open first input file */ - fp = audio_open_read (in1FileName, 0, 0, 16); + fp = audio_open_read (in1FileName, fs_given ? fs : 0, 0, 16); if (fp == NULL) { fprintf (stderr, "Error: Can't open input file %s", in1FileName); exit (-1); } + if (audio_get_sample_rate (fp) > 0) + fs = audio_get_sample_rate (fp); /* loop over first input file */ while ((nbread = audio_read (fp, frame_sh, nfft)) == nfft) { @@ -323,7 +327,7 @@ int main (int argc, char *argv[]) { /* ..... Second File ..... */ /* open second input file */ - fp = audio_open_read (in2FileName, 0, 0, 16); + fp = audio_open_read (in2FileName, fs_given ? fs : 0, 0, 16); if (fp == NULL) { fprintf (stderr, "Error: Can't open input file %s", in2FileName); exit (-1); diff --git a/src/g711/g711demo.c b/src/g711/g711demo.c index 1ce4cf69..471574ea 100644 --- a/src/g711/g711demo.c +++ b/src/g711/g711demo.c @@ -327,26 +327,24 @@ int main (int argc, char *argv[]) { #endif /* Open input file */ - if ((Fi = audio_open_read (inpfil, 0, 0, 16)) == NULL) + if ((Fi = audio_open_read (inpfil, 8000, 0, 16)) == NULL) KILL (inpfil, 2); /* Open (create) output file */ - if ((Fo = audio_open_write (outfil, 0, 1, 16)) == NULL) + if ((Fo = audio_open_write (outfil, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (outfil, 3); /* Define starting byte in file */ start_byte = (N1 * N + skip) * sizeof (short); /* ... and move file's pointer to 1st desired block */ - if (fseek (Fi->fp, (N1 * N + skip) * sizeof (short), 0) < 0l) + if (audio_seek (Fi, (N1 * N + skip) * sizeof (short)) < 0) KILL (inpfil, 4); /* Check whether is to process til end-of-file */ if (N2 == 0) { - struct stat st; /* ... hey, need to skip the delayed samples! ... */ - stat (inpfil, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); } diff --git a/src/g711iplc/g711iplc.c b/src/g711iplc/g711iplc.c index f6153f9f..ba41adcf 100644 --- a/src/g711iplc/g711iplc.c +++ b/src/g711iplc/g711iplc.c @@ -99,11 +99,11 @@ int main (int argc, char *argv[]) { exit (EXIT_FAILURE); } readplcmask_open (&mask, argv[0]); /* PLC pattern file */ - if ((fi = audio_open_read (argv[1], 0, 0, 16)) == NULL) { /* input file */ + if ((fi = audio_open_read (argv[1], 8000, 0, 16)) == NULL) { /* input file */ fprintf (stderr, "Can't open input file: %s", argv[1]); exit (EXIT_FAILURE); } - if ((fo = audio_open_write (argv[2], 0, 1, 16)) == NULL) { /* output file */ + if ((fo = audio_open_write (argv[2], audio_get_sample_rate (fi), 1, 16)) == NULL) { /* output file */ fprintf (stderr, "Can't open output file: %s", argv[2]); exit (EXIT_FAILURE); } diff --git a/src/g722/decg722.c b/src/g722/decg722.c index 8803128c..518269ec 100644 --- a/src/g722/decg722.c +++ b/src/g722/decg722.c @@ -356,7 +356,7 @@ int main (int argc, char *argv[]) { KILL (FileIn, -2); } /* Open output file */ - if ((F_out = audio_open_write (FileOut, 0, 1, 16)) == NULL) { + if ((F_out = audio_open_write (FileOut, 16000, 1, 16)) == NULL) { KILL (FileOut, -2); } diff --git a/src/g722/encg722.c b/src/g722/encg722.c index c8a0552c..9580320e 100644 --- a/src/g722/encg722.c +++ b/src/g722/encg722.c @@ -242,7 +242,7 @@ int main (int argc, char *argv[]) { } /* Open input file */ - if ((F_inp = audio_open_read (FileIn, 0, 0, 16)) == NULL) { + if ((F_inp = audio_open_read (FileIn, 16000, 0, 16)) == NULL) { fprintf (stderr, "Could not open %s\n", FileIn); KILL (FileIn, -2); } diff --git a/src/g722/g722demo.c b/src/g722/g722demo.c index 0cc90a8c..70788641 100644 --- a/src/g722/g722demo.c +++ b/src/g722/g722demo.c @@ -265,11 +265,11 @@ int main (int argc, char *argv[]) { error_terminate ("Bad mode specified; aborting\n", 2); /* Open input file */ - if ((inp = audio_open_read (FileIn, 0, 0, 16)) == NULL) + if ((inp = audio_open_read (FileIn, 16000, 0, 16)) == NULL) KILL (FileIn, -2); /* Open output file */ - if ((out = audio_open_write (FileOut, 0, 1, 16)) == NULL) + if ((out = audio_open_write (FileOut, audio_get_sample_rate (inp), 1, 16)) == NULL) KILL (FileOut, -2); #ifndef STATIC_ALLOCATION diff --git a/src/g726/g726demo.c b/src/g726/g726demo.c index afc14753..1fe7a960 100644 --- a/src/g726/g726demo.c +++ b/src/g726/g726demo.c @@ -266,14 +266,7 @@ int main (int argc, char *argv[]) { /* Find starting byte in file */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); - } + /* N2 will be computed after opening file if processing the whole file */ /* Classification of the conversion desired */ inp_type = toupper ((int) lilo[1]) == 'O' ? IS_LOG : IS_ADPCM; @@ -318,18 +311,22 @@ int main (int argc, char *argv[]) { */ /* Opening input file; abort if there's any problem */ - if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) + if ((Fi = audio_open_read (FileIn, 8000, 0, 16)) == NULL) KILL (FileIn, 2); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); + /* Creates output file */ #ifdef VMS sprintf (mrs, "mrs=%d", 512); #endif - if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi->fp, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* diff --git a/src/g726/vbr-g726.c b/src/g726/vbr-g726.c index 4b19ea9c..adcc3512 100644 --- a/src/g726/vbr-g726.c +++ b/src/g726/vbr-g726.c @@ -411,14 +411,7 @@ int main (int argc, char *argv[]) { /* Find starting byte in file */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); - } + /* N2 will be computed after opening file if processing the whole file */ /* Define correct data I/O types */ if (encode && decode) { @@ -451,18 +444,22 @@ int main (int argc, char *argv[]) { */ /* Opening input file; abort if there's any problem */ - if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) + if ((Fi = audio_open_read (FileIn, 8000, 0, 16)) == NULL) KILL (FileIn, 2); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); + /* Creates output file */ #ifdef VMS sprintf (mrs, "mrs=%d", 512); #endif - if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi->fp, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* diff --git a/src/g727/g727demo.c b/src/g727/g727demo.c index 34e3fc34..a7d1947e 100644 --- a/src/g727/g727demo.c +++ b/src/g727/g727demo.c @@ -360,14 +360,7 @@ int main (int argc, char **argv) { /* Find starting byte in file */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = (st.st_size - start_byte) / (N * sizeof (short)); - } + /* N2 will be computed after opening file if processing the whole file */ /* Convert law letter to number */ @@ -422,18 +415,22 @@ int main (int argc, char **argv) { */ /* Opening input file; abort if there's any problem */ - if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) + if ((Fi = audio_open_read (FileIn, 8000, 0, 16)) == NULL) KILL (FileIn, 2); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = audio_get_data_size (Fi) / (N * sizeof (short)); + /* Creates output file */ #ifdef VMS sprintf (mrs, "mrs=%d", 512); #endif - if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi->fp, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* diff --git a/src/mnru/mnrudemo.c b/src/mnru/mnrudemo.c index f2ca9765..9f112a14 100644 --- a/src/mnru/mnrudemo.c +++ b/src/mnru/mnrudemo.c @@ -261,14 +261,7 @@ int main (int argc, char *argv[]) { /* Find starting byte in file */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = (st.st_size - start_byte) / (N * sizeof (short)); - } + /* N2 will be computed after opening file if processing the whole file */ /* Allocate memory for data vectors */ if ((inp = (float *) calloc (N, sizeof (float))) == NULL) @@ -283,12 +276,16 @@ int main (int argc, char *argv[]) { if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = audio_get_data_size (Fi) / (N * sizeof (short)); + /* Creates output file */ - if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi->fp, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* INSERTION OF MODULATED NOISE ACCORDING TO P.810 */ diff --git a/src/reverb/reverb.c b/src/reverb/reverb.c index 0607e572..bdee0fa1 100644 --- a/src/reverb/reverb.c +++ b/src/reverb/reverb.c @@ -157,7 +157,7 @@ int main (int argc, char *argv[]) { } /* open the output file */ - ptr_fileOut = audio_open_write (FileOut, 0, 1, 16); + ptr_fileOut = audio_open_write (FileOut, audio_get_sample_rate (ptr_fileIn), 1, 16); if (ptr_fileOut == NULL) { fprintf (stderr, "\nUnable to open Output file\n"); exit (-1); diff --git a/src/rpeltp/rpedemo.c b/src/rpeltp/rpedemo.c index 0f6a4ac3..5632a00f 100644 --- a/src/rpeltp/rpedemo.c +++ b/src/rpeltp/rpedemo.c @@ -280,18 +280,7 @@ int main (argc, argv) /* Find staring byte in file; all are 16-bit word-aligned =>short data type */ start_byte = sizeof (short) * (long) (--N1) * (long) N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - /* convert to block count, depending on whether the input file is a uncoded or coded file */ - if (run_encoder) - N2 = (st.st_size - start_byte) / (N * sizeof (short)); - else - N2 = (st.st_size - start_byte) / (RPE_FRAME_SIZE * sizeof (short)); - } + /* N2 will be computed after opening file if processing the whole file */ /* Choose A/u law */ if (format == A_LAW) { @@ -326,14 +315,23 @@ int main (argc, argv) #endif /* Opening input/output files; abort if there's any problem */ - if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) + if ((Fi = audio_open_read (FileIn, 8000, 0, 16)) == NULL) KILL (FileIn, 2); - if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) { + long data_size = audio_get_data_size (Fi); + if (run_encoder) + N2 = (data_size - start_byte) / (N * sizeof (short)); + else + N2 = (data_size - start_byte) / (RPE_FRAME_SIZE * sizeof (short)); + } + + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi->fp, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* ......... CREATE AND INIT GSM OBJECT (STATE VARIABLE) ......... */ diff --git a/src/stereoop/stereoop.c b/src/stereoop/stereoop.c index b04c62f6..0a683958 100644 --- a/src/stereoop/stereoop.c +++ b/src/stereoop/stereoop.c @@ -187,7 +187,7 @@ int main (int argc, char *argv[]) { } } for (i = 0; i < n_outfiles[mode]; i++) { - if ((Fof[i] = audio_open_write (ofname[i], 0, 1, 16)) == NULL) { + if ((Fof[i] = audio_open_write (ofname[i], audio_get_sample_rate (Fif[0]), 1, 16)) == NULL) { sprintf (tmp_str, "Could not create output file %d,(%s)\n", i + 1, ofname[i]); error_terminate (tmp_str, 1); } diff --git a/src/sv56/actlevel.c b/src/sv56/actlevel.c index 2accc50d..3ff87a76 100644 --- a/src/sv56/actlevel.c +++ b/src/sv56/actlevel.c @@ -435,6 +435,7 @@ int main (int argc, char *argv[]) { float Buf[4096]; long start_byte, bitno = 16; double sf = 16000; /* Hz */ + int sf_given = 0; double ActiveLeveldB, level = 0, gain = 0; static char funny[] = "|/-\\|/-\\", funny_size = sizeof (funny), quiet = 0; #ifdef LOCAL_PRINT @@ -452,6 +453,7 @@ int main (int argc, char *argv[]) { if (strcmp (argv[1], "-sf") == 0) { /* Change default sampling frequency */ sf = atof (argv[2]); + sf_given = 1; /* Update argc/argv to next valid option/argument */ argv += 2; @@ -564,21 +566,21 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (mrs, "mrs=%d", 2 * N); #endif - if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) + if ((Fi = audio_open_read (FileIn, sf_given ? (long) sf : 0, 0, 16)) == NULL) KILL (FileIn, 2); + if (audio_get_sample_rate (Fi) > 0) + sf = (double) audio_get_sample_rate (Fi); /* Reinitialize number of blocks as specified initially */ N2 = N2_ori; /* Check if is to process the whole file */ if (N2 == 0) { - struct stat st; - stat (FileIn, &st); - N2 = ceil (st.st_size / (double) (N * sizeof (short))); + N2 = ceil (audio_get_data_size (Fi) / (double) (N * sizeof (short))); } /* Move pointer to 1st block of interest */ - if (fseek (Fi->fp, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); diff --git a/src/sv56/sv56demo.c b/src/sv56/sv56demo.c index 1caa436a..cfd4f1b5 100644 --- a/src/sv56/sv56demo.c +++ b/src/sv56/sv56demo.c @@ -445,6 +445,7 @@ int main (int argc, char *argv[]) { float Buf[4096]; long NrSat = 0, start_byte, bitno = 16; double sf = 16000, factor; + int sf_given = 0; double ActiveLeveldB, DesiredSpeechLeveldB; static char funny[5] = { '/', '-', '\\', '|', '-' }; static unsigned mask[5] = { 0xFFFF, 0xFFFE, 0xFFFB, 0xFFF8, 0xFFF0 }; @@ -467,6 +468,7 @@ int main (int argc, char *argv[]) { } else if (strcmp (argv[1], "-sf") == 0) { /* Change default sampling frequency */ sf = atof (argv[2]); + sf_given = 1; /* Update argc/argv to next valid option/argument */ argv += 2; @@ -563,14 +565,7 @@ int main (int argc, char *argv[]) { start_byte = --N1; start_byte *= N * sizeof (short); - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); - } + /* Check if is to process the whole file (computed after opening) */ /* Overflow (saturation) point */ Overflow = pow ((double) 2.0, (double) (bitno - 1)); @@ -587,15 +582,21 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (mrs, "mrs=%d", 2 * N); #endif - if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) + if ((Fi = audio_open_read (FileIn, sf_given ? (long) sf : 0, 0, 16)) == NULL) KILL (FileIn, 2); + if (audio_get_sample_rate (Fi) > 0) + sf = (double) audio_get_sample_rate (Fi); + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); /* Creates output file */ - if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) + if ((Fo = audio_open_write (FileOut, (long) sf, 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st block of interest */ - if (fseek (Fi->fp, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); @@ -646,7 +647,7 @@ int main (int argc, char *argv[]) { /* EQUALIZATION: hard clipping (with truncation) */ /* Move pointer to 1st desired block */ - if (fseek (Fi->fp, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* Get data of interest, equalize and de-normalize */ diff --git a/src/unsup/astrip.c b/src/unsup/astrip.c index cdb5e7b1..379bb8cb 100644 --- a/src/unsup/astrip.c +++ b/src/unsup/astrip.c @@ -312,16 +312,8 @@ int main (int argc, char *argv[]) { /* Define 1st sample to compare */ start_byte = samplesize * N1 * N; - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the size of the full file and discount the number */ - /* ... of samples to skip in the beginning of the file ... */ - stat (File1, &st); - to_process = (st.st_size - start_byte) / samplesize; - N2 = ceil ((st.st_size - start_byte) / (double) (N * samplesize)); - } else + /* N2 will be computed after opening file if processing the whole file */ + if (N2 != 0) to_process = N * N2; /* Opening test file; abort if there's any problem */ @@ -332,11 +324,18 @@ int main (int argc, char *argv[]) { /* Open input files */ if ((fi = audio_open_read (File1, 0, 0, 16)) == NULL) KILL (File1, 3); - if ((fo = audio_open_write (File2, 0, 1, 16)) == NULL) + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) { + to_process = (audio_get_data_size (fi) - start_byte) / samplesize; + N2 = ceil ((audio_get_data_size (fi) - start_byte) / (double) (N * samplesize)); + } + + if ((fo = audio_open_write (File2, audio_get_sample_rate (fi), 1, 16)) == NULL) KILL (File2, 4); /* Move pointer to 1st block of interest */ - if (fseek (fi->fp, start_byte, 0l) < 0l) + if (audio_seek (fi, start_byte) < 0l) KILL (File1, 3); /* Some preliminaries */ diff --git a/src/unsup/fdelay.c b/src/unsup/fdelay.c index 193b9363..6b9d6796 100644 --- a/src/unsup/fdelay.c +++ b/src/unsup/fdelay.c @@ -318,7 +318,7 @@ int main (int argc, char *argv[]) { /* Open files; abort on error */ if ((Finp = audio_open_read (InpFile, 0, 0, 16)) == NULL) KILL (InpFile, 3); - if ((Fout = audio_open_write (OutFile, 0, 1, 16)) == NULL) + if ((Fout = audio_open_write (OutFile, audio_get_sample_rate (Finp), 1, 16)) == NULL) KILL (OutFile, 4); if (delay_file) { /* Delay comes from a file - open delay file */ @@ -335,15 +335,11 @@ int main (int argc, char *argv[]) { /* Check if is to process the whole file */ if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (InpFile, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); + N2 = ceil ((audio_get_data_size (Finp) - start_byte) / (double) (N * sizeof (short))); } /* Move pointer to 1st block of interest */ - if (fseek (Finp->fp, start_byte, 0) < 0l) + if (audio_seek (Finp, start_byte) < 0l) KILL (InpFile, 4); /* Put delay samples in begining of file, if *not* appending */ diff --git a/src/unsup/oper.c b/src/unsup/oper.c index 02473f85..7416e635 100644 --- a/src/unsup/oper.c +++ b/src/unsup/oper.c @@ -479,48 +479,39 @@ int main (int argc, char *argv[]) { start_byte2 *= (N1 * N - delay); } - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - long k, l; + /* N2 will be computed after opening files if processing the whole file */ - /* ... find the size of the 2 files and the number of blks from it */ - /* ... hey, need to skip the delayed samples! ... */ - stat (File1, &st); - k = (st.st_size - start_byte1) / (N * samplesize); - stat (File2, &st); - l = (st.st_size - start_byte2) / (N * samplesize); + /* Opening test file; abort if there's any problem */ +#ifdef VMS + sprintf (mrs, "mrs=%d", sizeof (short) * N); +#endif + /* Open input files */ + if ((f1 = audio_open_read (File1, 0, 0, 16)) == NULL) + KILL (File1, 3); + if ((f2 = audio_open_read (File2, 0, 0, 16)) == NULL) + KILL (File2, 4); + + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) { + long k, l; + k = (audio_get_data_size (f1) - start_byte1) / (N * samplesize); + l = (audio_get_data_size (f2) - start_byte2) / (N * samplesize); if (trim_by == 1) N2 = k; else if (trim_by == 2) N2 = l; else if (trim_by == 3) { - /* Trim by the size of the longest file */ N2 = k > l ? k : l; - - /* Convert the trim flag to the equivalent of trimming by the size of file 1 or file 2, the longest of them; this eases implementation */ trim_by = (k > l) ? 1 : 2; } else { - /* Trim by the size of the shortest file */ N2 = k < l ? k : l; } - if (k != l) fprintf (stderr, "WARNING: Files have different sizes!\n"); } - /* Opening test file; abort if there's any problem */ -#ifdef VMS - sprintf (mrs, "mrs=%d", sizeof (short) * N); -#endif - - /* Open input files */ - if ((f1 = audio_open_read (File1, 0, 0, 16)) == NULL) - KILL (File1, 3); - if ((f2 = audio_open_read (File2, 0, 0, 16)) == NULL) - KILL (File2, 4); - if ((fr = audio_open_write (RFile, 0, 1, 16)) == NULL) + if ((fr = audio_open_write (RFile, audio_get_sample_rate (f1), 1, 16)) == NULL) KILL (RFile, 5); /* If samples of the primary files are to be skipped, dump them into the output file */ @@ -529,7 +520,7 @@ int main (int argc, char *argv[]) { short *a = (short *) calloc (sizeof (short), delay); double register tmp; - if (fseek (f1->fp, dump * samplesize, 0l) < 0l) + if (audio_seek (f1, dump * samplesize) < 0l) KILL (File1, 3); if (audio_read (f1, a, delay) != delay) @@ -543,9 +534,9 @@ int main (int argc, char *argv[]) { } /* Move pointer to 1st block of interest */ - if (fseek (f1->fp, start_byte1, 0l) < 0l) + if (audio_seek (f1, start_byte1) < 0l) KILL (File1, 3); - if (fseek (f2->fp, start_byte2, 0l) < 0l) + if (audio_seek (f2, start_byte2) < 0l) KILL (File2, 4); /* Some preliminaries */ diff --git a/src/utl/CMakeLists.txt b/src/utl/CMakeLists.txt index e195d661..700aa7ab 100644 --- a/src/utl/CMakeLists.txt +++ b/src/utl/CMakeLists.txt @@ -9,6 +9,11 @@ add_executable(signal-diff signal-diff.c wav_io.c) add_executable(test_wav_io test_wav_io.c wav_io.c) add_test(wav_io ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_wav_io) +add_executable(mkwav mkwav.c wav_io.c) +add_executable(test_wav_io_validate test_wav_io_validate.c wav_io.c) + +include(test_wav_integration.cmake) + #TODO Input file is not _yet_ there. add_test(scaldemo1 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/scaldemo -q -trunc ../is54/test_data/voice.src test_data/voice.tru 256 1 0 0.5941352) add_test(scaldemo1-verify ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cf -q ../sv56/test_data/voice.ltl test_data/voice.tru) diff --git a/src/utl/mkwav.c b/src/utl/mkwav.c new file mode 100644 index 00000000..2f91ed47 --- /dev/null +++ b/src/utl/mkwav.c @@ -0,0 +1,48 @@ +/* mkwav.c - Create a WAV file from raw PCM data or silence. + * + * Usage: mkwav [input.pcm] + * If input.pcm is omitted, generates 100 samples of silence. + */ +#include +#include +#include +#include "wav_io.h" + +int main (int argc, char *argv[]) { + AUDIO_FILE *af; + long rate; + int channels, bits; + short buf[256]; + long n; + + if (argc < 5) { + fprintf (stderr, "Usage: mkwav [input.pcm]\n"); + return 1; + } + + rate = atol (argv[2]); + channels = atoi (argv[3]); + bits = atoi (argv[4]); + + af = audio_open_write (argv[1], rate, channels, bits); + if (!af) + return 1; + + if (argc > 5) { + FILE *fp = fopen (argv[5], "rb"); + if (!fp) { + fprintf (stderr, "Cannot open input: %s\n", argv[5]); + audio_close (af); + return 1; + } + while ((n = (long) fread (buf, sizeof (short), 256, fp)) > 0) + audio_write (af, buf, n); + fclose (fp); + } else { + memset (buf, 0, sizeof (buf)); + audio_write (af, buf, 100); + } + + audio_close (af); + return 0; +} diff --git a/src/utl/scaldemo.c b/src/utl/scaldemo.c index 4eb8fb7f..ac59b432 100644 --- a/src/utl/scaldemo.c +++ b/src/utl/scaldemo.c @@ -308,14 +308,7 @@ int main (int argc, char *argv[]) { start_byte = --N1; start_byte *= N * sizeof (short); - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); - } + /* N2 will be computed after opening file if processing the whole file */ /* Allocate memory for data buffers */ if ((s_buf = (short *) calloc (sizeof (short), N)) == NULL) @@ -338,12 +331,16 @@ int main (int argc, char *argv[]) { if ((Fi = audio_open_read (FileIn, 0, 0, 16)) == NULL) KILL (FileIn, 2); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = ceil ((audio_get_data_size (Fi) - start_byte) / (double) (N * sizeof (short))); + /* Creates output file */ - if ((Fo = audio_open_write (FileOut, 0, 1, 16)) == NULL) + if ((Fo = audio_open_write (FileOut, audio_get_sample_rate (Fi), 1, 16)) == NULL) KILL (FileOut, 3); /* Move pointer to 1st desired block */ - if (fseek (Fi->fp, start_byte, 0) < 0l) + if (audio_seek (Fi, start_byte) < 0l) KILL (FileIn, 4); /* Get data of interest, equalize and de-normalize */ diff --git a/src/utl/test_wav_integration.cmake b/src/utl/test_wav_integration.cmake new file mode 100644 index 00000000..4ae4a247 --- /dev/null +++ b/src/utl/test_wav_integration.cmake @@ -0,0 +1,567 @@ +# WAV I/O integration tests +# Tests that tools correctly handle WAV input with matching/mismatching parameters +# and that raw PCM input still works (backward compatibility). + +set(BIN ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) +set(WAV_TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/wav_test_data) +file(MAKE_DIRECTORY ${WAV_TEST_DIR}) + +# --- Generate WAV test files from existing raw PCM test data --- + +# G.711 test input: 8000 Hz (narrowband codec) +add_test(NAME wav-gen-g711-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/sweep_8k.wav 8000 1 16 test_data/sweep.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g711) +add_test(NAME wav-gen-g711-wrong + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/sweep_48k.wav 48000 1 16 test_data/sweep.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g711) + +# SV56 test input: 16000 Hz (default) +add_test(NAME wav-gen-sv56-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/voice_16k.wav 16000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/sv56) +add_test(NAME wav-gen-sv56-wrong + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/voice_44k.wav 44100 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/sv56) + +# MNRU test input: no fixed rate (pass-through) +add_test(NAME wav-gen-mnru-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/sine_8k.wav 8000 1 16 test_data/sine.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/mnru) + +# G.726 test input: 8000 Hz +add_test(NAME wav-gen-g726-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g726_voice_8k.wav 8000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g726) +add_test(NAME wav-gen-g726-wrong + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g726_voice_16k.wav 16000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g726) + +# FIR filter test input +add_test(NAME wav-gen-fir-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/fir_test_8k.wav 8000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/fir) + +# Reverb test input (pass-through, any rate) +add_test(NAME wav-gen-reverb-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/reverb_input_16k.wav 16000 1 16 test_data/input.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/reverb) + +# Set fixture properties for WAV generation +set_tests_properties( + wav-gen-g711-8k wav-gen-g711-wrong + wav-gen-sv56-16k wav-gen-sv56-wrong + wav-gen-mnru-8k + wav-gen-g726-8k wav-gen-g726-wrong + wav-gen-fir-8k + wav-gen-reverb-16k + PROPERTIES FIXTURES_SETUP WAV_FILES) + +# ========================================================================== +# Case 1: WAV input with MATCHING parameters → should succeed, output matches +# ========================================================================== + +# G.711: WAV 8000 Hz input, encode A-law +add_test(NAME wav-g711-match-raw + COMMAND ${BIN}/g711demo A lilo ${CMAKE_SOURCE_DIR}/src/g711/test_data/sweep.src ${WAV_TEST_DIR}/g711_out_raw.raw 256 1 256) +set_tests_properties(wav-g711-match-raw PROPERTIES + FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-g711-match + COMMAND ${BIN}/g711demo A lilo ${WAV_TEST_DIR}/sweep_8k.wav ${WAV_TEST_DIR}/g711_out.raw 256 1 256) +set_tests_properties(wav-g711-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-g711-match-verify + COMMAND ${CMAKE_COMMAND} -E compare_files ${WAV_TEST_DIR}/g711_out.raw ${WAV_TEST_DIR}/g711_out_raw.raw) +set_tests_properties(wav-g711-match-verify PROPERTIES + DEPENDS "wav-g711-match;wav-g711-match-raw") + +# G.726: WAV 8000 Hz input +add_test(NAME wav-g726-match + COMMAND ${BIN}/g726demo -q a lilo 16 ${WAV_TEST_DIR}/g726_voice_8k.wav ${WAV_TEST_DIR}/g726_out.raw 256 1 64) +set_tests_properties(wav-g726-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# SV56: WAV 16000 Hz input (matching default -sf 16000) +add_test(NAME wav-sv56-match + COMMAND ${BIN}/sv56demo -q ${WAV_TEST_DIR}/voice_16k.wav ${WAV_TEST_DIR}/sv56_out.raw 256 1 0 -30) +set_tests_properties(wav-sv56-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# MNRU: WAV 8000 Hz input (pass-through, any rate accepted) +add_test(NAME wav-mnru-match + COMMAND ${BIN}/mnrudemo -q ${WAV_TEST_DIR}/sine_8k.wav ${WAV_TEST_DIR}/mnru_out.raw 256 1 20 00) +set_tests_properties(wav-mnru-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# FIR filter: WAV 8000 Hz input (matching default -fs 8000) +add_test(NAME wav-fir-match + COMMAND ${BIN}/firdemo -q ${WAV_TEST_DIR}/fir_test_8k.wav ${WAV_TEST_DIR}/fir_out.raw 8 0 0 0 0 0) +set_tests_properties(wav-fir-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# Reverb: WAV 16000 Hz input (pass-through) +add_test(NAME wav-reverb-match + COMMAND ${BIN}/reverb ${WAV_TEST_DIR}/reverb_input_16k.wav test_data/irtest_le.IR ${WAV_TEST_DIR}/reverb_out.raw + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/reverb) +set_tests_properties(wav-reverb-match PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# ========================================================================== +# Case 2: WAV input with WRONG sample rate → should fail (non-zero exit) +# ========================================================================== + +# G.711: WAV 48000 Hz input (expects 8000 Hz) +add_test(NAME wav-g711-mismatch + COMMAND ${BIN}/g711demo A lilo ${WAV_TEST_DIR}/sweep_48k.wav ${WAV_TEST_DIR}/g711_bad.raw 256 1 256) +set_tests_properties(wav-g711-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# G.726: WAV 16000 Hz input (expects 8000 Hz) +add_test(NAME wav-g726-mismatch + COMMAND ${BIN}/g726demo -q a lilo 16 ${WAV_TEST_DIR}/g726_voice_16k.wav ${WAV_TEST_DIR}/g726_bad.raw 256 1 64) +set_tests_properties(wav-g726-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# SV56: WAV 44100 Hz input with -sf 16000 (explicit mismatch) +add_test(NAME wav-sv56-mismatch + COMMAND ${BIN}/sv56demo -q -sf 16000 ${WAV_TEST_DIR}/voice_44k.wav ${WAV_TEST_DIR}/sv56_bad.raw 256 1 0 -30) +set_tests_properties(wav-sv56-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# SV56: WAV 16000 Hz input with -sf 8000 (explicit mismatch) +add_test(NAME wav-sv56-explicit-mismatch + COMMAND ${BIN}/sv56demo -q -sf 8000 ${WAV_TEST_DIR}/voice_16k.wav ${WAV_TEST_DIR}/sv56_bad2.raw 256 1 0 -30) +set_tests_properties(wav-sv56-explicit-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# ========================================================================== +# Case 2b: WAV input WITHOUT -sf parameter → should succeed (uses WAV rate) +# ========================================================================== + +# SV56: WAV 16000 Hz input, no -sf given (should use WAV's rate, not reject) +add_test(NAME wav-sv56-no-sf + COMMAND ${BIN}/sv56demo -q ${WAV_TEST_DIR}/voice_16k.wav ${WAV_TEST_DIR}/sv56_nosf.raw 256 1 0 -30) +set_tests_properties(wav-sv56-no-sf PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# filter: WAV 16000 Hz input, no -fs given (default is 8000, should accept WAV rate) +add_test(NAME wav-gen-filter-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/filter_test_16k.wav 16000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/fir) +set_tests_properties(wav-gen-filter-16k PROPERTIES FIXTURES_SETUP WAV_FILES_NOSF) +add_test(NAME wav-filter-no-fs + COMMAND ${BIN}/filter -q IRS16 ${WAV_TEST_DIR}/filter_test_16k.wav ${WAV_TEST_DIR}/filter_nosf.raw) +set_tests_properties(wav-filter-no-fs PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_NOSF") + +# actlevel: WAV 8000 Hz input, no -sf given (default is 16000, should accept WAV rate) +add_test(NAME wav-gen-actlev-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/actlev_8k.wav 8000 1 16 test_data/sweep.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g711) +set_tests_properties(wav-gen-actlev-8k PROPERTIES FIXTURES_SETUP WAV_FILES_NOSF) +add_test(NAME wav-actlevel-no-sf + COMMAND ${BIN}/actlev -q ${WAV_TEST_DIR}/actlev_8k.wav) +set_tests_properties(wav-actlevel-no-sf PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_NOSF") + +# esdru: WAV 16000 Hz input, no -sf given (default is 48000, should accept WAV rate) +add_test(NAME wav-gen-esdru-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/esdru_16k.wav 16000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/sv56) +set_tests_properties(wav-gen-esdru-16k PROPERTIES FIXTURES_SETUP WAV_FILES_NOSF) +add_test(NAME wav-esdru-no-sf + COMMAND ${BIN}/esdru -e_out ${WAV_TEST_DIR}/esdru_nosf_el.raw 0.2 ${WAV_TEST_DIR}/esdru_16k.wav ${WAV_TEST_DIR}/esdru_nosf.raw) +set_tests_properties(wav-esdru-no-sf PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_NOSF") + +# freqresp: WAV 8000 Hz input, no -fs given (default is 16000, should accept WAV rate) +add_test(NAME wav-freqresp-no-fs + COMMAND ${BIN}/freqresp ${WAV_TEST_DIR}/fir_test_8k.wav ${WAV_TEST_DIR}/fir_test_8k.wav ${WAV_TEST_DIR}/freqresp_nosf.txt) +set_tests_properties(wav-freqresp-no-fs PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# ========================================================================== +# Case 3: WAV output extension → produces valid WAV with correct sample rate +# ========================================================================== + +# G.711: WAV input → WAV output (check output has WAV header) +add_test(NAME wav-g711-wav-output + COMMAND ${BIN}/g711demo A lilo ${WAV_TEST_DIR}/sweep_8k.wav ${WAV_TEST_DIR}/g711_out.wav 256 1 256) +set_tests_properties(wav-g711-wav-output PROPERTIES + FIXTURES_REQUIRED WAV_FILES) + +# Verify the output WAV can be opened and has correct sample rate +add_test(NAME wav-g711-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/g711_out.wav 8000 1 16) +set_tests_properties(wav-g711-wav-output-verify PROPERTIES + DEPENDS wav-g711-wav-output) + +# SV56: WAV output +add_test(NAME wav-sv56-wav-output + COMMAND ${BIN}/sv56demo -q ${WAV_TEST_DIR}/voice_16k.wav ${WAV_TEST_DIR}/sv56_out.wav 256 1 0 -30) +set_tests_properties(wav-sv56-wav-output PROPERTIES + FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-sv56-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/sv56_out.wav 16000 1 16) +set_tests_properties(wav-sv56-wav-output-verify PROPERTIES + DEPENDS wav-sv56-wav-output) + +# MNRU: WAV output preserves input rate +add_test(NAME wav-mnru-wav-output + COMMAND ${BIN}/mnrudemo -q ${WAV_TEST_DIR}/sine_8k.wav ${WAV_TEST_DIR}/mnru_out.wav 256 1 20 00) +set_tests_properties(wav-mnru-wav-output PROPERTIES + FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-mnru-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/mnru_out.wav 8000 1 16) +set_tests_properties(wav-mnru-wav-output-verify PROPERTIES + DEPENDS wav-mnru-wav-output) + +# Reverb: WAV output preserves input rate +add_test(NAME wav-reverb-wav-output + COMMAND ${BIN}/reverb ${WAV_TEST_DIR}/reverb_input_16k.wav test_data/irtest_le.IR ${WAV_TEST_DIR}/reverb_out.wav + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/reverb) +set_tests_properties(wav-reverb-wav-output PROPERTIES + FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-reverb-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/reverb_out.wav 16000 1 16) +set_tests_properties(wav-reverb-wav-output-verify PROPERTIES + DEPENDS wav-reverb-wav-output) + +# ========================================================================== +# Additional tool coverage — matching WAV tests +# ========================================================================== + +# --- Generate additional WAV test files --- +add_test(NAME wav-gen-iir-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/iir_test_8k.wav 8000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/iir) +add_test(NAME wav-gen-scal-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/scal_voice_8k.wav 8000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/is54) +add_test(NAME wav-gen-unsup-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/unsup_bigend_8k.wav 8000 1 16 test_data/bigend.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/unsup) +add_test(NAME wav-gen-stereoop-32k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/stereo_L_32k.wav 32000 1 16 test_data/sample.L.32k.1ch.smp + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/stereoop) +add_test(NAME wav-gen-stereoop-R-32k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/stereo_R_32k.wav 32000 1 16 test_data/sample.R.32k.1ch.smp + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/stereoop) +add_test(NAME wav-gen-g711iplc-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g711iplc_8k.wav 8000 1 16 test_data/f2.le + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g711iplc) +add_test(NAME wav-gen-vbr-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/vbr_voice_8k.wav 8000 1 16 test_data/voice.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g726) +add_test(NAME wav-gen-g722-16k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g722_inp_16k.wav 16000 1 16 test_data/inpsp.bin + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g722) +add_test(NAME wav-gen-bs1770-48k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/bs1770_sine_48k.wav 48000 1 16 test_data/sine997_0dBFS.pcm + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/bs1770demo) +add_test(NAME wav-gen-esdru-48k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/esdru_stereo_48k.wav 48000 1 16 test_data/stereo_test.pcm + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/esdru) +add_test(NAME wav-gen-filter-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/filter_test_8k.wav 8000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/fir) + +set_tests_properties( + wav-gen-iir-8k wav-gen-scal-8k wav-gen-unsup-8k + wav-gen-stereoop-32k wav-gen-stereoop-R-32k wav-gen-g711iplc-8k + wav-gen-vbr-8k wav-gen-g722-16k wav-gen-bs1770-48k + wav-gen-esdru-48k wav-gen-filter-8k + PROPERTIES FIXTURES_SETUP WAV_FILES_EXT) + +# --- IIR filters --- +add_test(NAME wav-cirsdemo-match + COMMAND ${BIN}/cirsdemo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/cirsdemo_out.raw) +set_tests_properties(wav-cirsdemo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +add_test(NAME wav-c712demo-match + COMMAND ${BIN}/c712demo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/c712demo_out.raw) +set_tests_properties(wav-c712demo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +add_test(NAME wav-pcmdemo-match + COMMAND ${BIN}/pcmdemo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/pcmdemo_out.raw 1_1 0 0) +set_tests_properties(wav-pcmdemo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- filter (FIR with -fs) --- +add_test(NAME wav-filter-match + COMMAND ${BIN}/filter -q IRS8 ${WAV_TEST_DIR}/filter_test_8k.wav ${WAV_TEST_DIR}/filter_out.raw) +set_tests_properties(wav-filter-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- scaldemo --- +add_test(NAME wav-scaldemo-match + COMMAND ${BIN}/scaldemo -q -trunc ${WAV_TEST_DIR}/scal_voice_8k.wav ${WAV_TEST_DIR}/scal_out.raw 256 1 0 0.5941352) +set_tests_properties(wav-scaldemo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- stereoop --- +add_test(NAME wav-stereoop-match + COMMAND ${BIN}/stereoop -q -interleave ${WAV_TEST_DIR}/stereo_L_32k.wav ${WAV_TEST_DIR}/stereo_R_32k.wav ${WAV_TEST_DIR}/stereoop_out.raw) +set_tests_properties(wav-stereoop-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- astrip --- +add_test(NAME wav-astrip-match + COMMAND ${BIN}/astrip -q -smooth -wlen 145 -sample ${WAV_TEST_DIR}/unsup_bigend_8k.wav ${WAV_TEST_DIR}/astrip_out.raw) +set_tests_properties(wav-astrip-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- fdelay --- +add_test(NAME wav-fdelay-match + COMMAND ${BIN}/fdelay ${WAV_TEST_DIR}/unsup_bigend_8k.wav ${WAV_TEST_DIR}/fdelay_out.raw) +set_tests_properties(wav-fdelay-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- oper --- +add_test(NAME wav-oper-match + COMMAND ${BIN}/oper -q 1 ${WAV_TEST_DIR}/unsup_bigend_8k.wav + 1 ${WAV_TEST_DIR}/unsup_bigend_8k.wav 0 ${WAV_TEST_DIR}/oper_out.raw) +set_tests_properties(wav-oper-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- g711iplc --- +add_test(NAME wav-g711iplc-match + COMMAND ${BIN}/g711iplc -stats ${CMAKE_SOURCE_DIR}/src/g711iplc/test_data/fe10.g192 ${WAV_TEST_DIR}/g711iplc_8k.wav ${WAV_TEST_DIR}/g711iplc_out.raw) +set_tests_properties(wav-g711iplc-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- vbr-g726 --- +add_test(NAME wav-vbr-g726-match + COMMAND ${BIN}/vbr-g726 -q -law A -rate 16-24-32-40-32-24 ${WAV_TEST_DIR}/vbr_voice_8k.wav ${WAV_TEST_DIR}/vbr_out.raw) +set_tests_properties(wav-vbr-g726-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- g722demo --- +add_test(NAME wav-g722demo-match + COMMAND ${BIN}/g722demo -q -enc ${WAV_TEST_DIR}/g722_inp_16k.wav ${WAV_TEST_DIR}/g722_out.cod) +set_tests_properties(wav-g722demo-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- encg722 --- +add_test(NAME wav-encg722-match + COMMAND ${BIN}/encg722 ${WAV_TEST_DIR}/g722_inp_16k.wav ${WAV_TEST_DIR}/encg722_out.cod) +set_tests_properties(wav-encg722-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- bs1770demo --- +add_test(NAME wav-bs1770-match + COMMAND ${BIN}/bs1770demo ${WAV_TEST_DIR}/bs1770_sine_48k.wav ${WAV_TEST_DIR}/bs1770_out.raw) +set_tests_properties(wav-bs1770-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- esdru --- +add_test(NAME wav-esdru-match + COMMAND ${BIN}/esdru -e_out ${WAV_TEST_DIR}/esdru_el.raw 0.2 ${WAV_TEST_DIR}/esdru_stereo_48k.wav ${WAV_TEST_DIR}/esdru_out.raw) +set_tests_properties(wav-esdru-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# --- actlevel (read-only measurement) --- +add_test(NAME wav-actlevel-match + COMMAND ${BIN}/actlev -q ${WAV_TEST_DIR}/voice_16k.wav) +set_tests_properties(wav-actlevel-match PROPERTIES FIXTURES_REQUIRED WAV_FILES) + +# --- freqresp (read-only, no output file) --- +add_test(NAME wav-freqresp-match + COMMAND ${BIN}/freqresp ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/freqresp_out.txt) +set_tests_properties(wav-freqresp-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") + +# ========================================================================== +# Additional mismatch tests for tools with fixed rates +# ========================================================================== + +# vbr-g726: WAV 16000 Hz input (expects 8000 Hz) +add_test(NAME wav-vbr-g726-mismatch + COMMAND ${BIN}/vbr-g726 -q -law A -rate 16-24-32-40-32-24 ${WAV_TEST_DIR}/g726_voice_16k.wav ${WAV_TEST_DIR}/vbr_bad.raw) +set_tests_properties(wav-vbr-g726-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# g722demo: WAV 8000 Hz input (expects 16000 Hz) +add_test(NAME wav-g722-mismatch + COMMAND ${BIN}/g722demo ${WAV_TEST_DIR}/sweep_8k.wav ${WAV_TEST_DIR}/g722_bad.raw 256 1 256) +set_tests_properties(wav-g722-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# bs1770demo: WAV 8000 Hz input (expects 48000 Hz) +add_test(NAME wav-bs1770-mismatch + COMMAND ${BIN}/bs1770demo ${WAV_TEST_DIR}/sweep_8k.wav ${WAV_TEST_DIR}/bs1770_bad.raw) +set_tests_properties(wav-bs1770-mismatch PROPERTIES + FIXTURES_REQUIRED WAV_FILES + WILL_FAIL TRUE) + +# g711iplc: WAV 16000 Hz input (expects 8000 Hz) +add_test(NAME wav-g711iplc-mismatch + COMMAND ${BIN}/g711iplc ${CMAKE_SOURCE_DIR}/src/g711iplc/test_data/fe10.g192 ${WAV_TEST_DIR}/g722_inp_16k.wav ${WAV_TEST_DIR}/g711iplc_bad.raw) +set_tests_properties(wav-g711iplc-mismatch PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT" + WILL_FAIL TRUE) + +# ========================================================================== +# More tool coverage +# ========================================================================== + +# --- Generate WAV for g727 and rpedemo --- +add_test(NAME wav-gen-g727-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/g727_speech_8k.wav 8000 1 16 test_data/speech.a-s + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g727) +add_test(NAME wav-gen-sigdiff-8k + COMMAND ${BIN}/mkwav ${WAV_TEST_DIR}/sigdiff_8k.wav 8000 1 16 test_data/test.src + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/iir) +set_tests_properties(wav-gen-g727-8k wav-gen-sigdiff-8k + PROPERTIES FIXTURES_SETUP WAV_FILES_EXT2) + +# g727demo encode mode +add_test(NAME wav-g727-match + COMMAND ${BIN}/g727demo -q -core 4 -enh 0 -enc -law A ${WAV_TEST_DIR}/g727_speech_8k.wav ${WAV_TEST_DIR}/g727_out.iad) +set_tests_properties(wav-g727-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT2") + +# g727demo: WAV 16000 Hz input (expects 8000) +add_test(NAME wav-g727-mismatch + COMMAND ${BIN}/g727demo -q -core 4 -enh 0 -enc -law A ${WAV_TEST_DIR}/g722_inp_16k.wav ${WAV_TEST_DIR}/g727_bad.iad) +set_tests_properties(wav-g727-mismatch PROPERTIES + FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT" + WILL_FAIL TRUE) + +# signal-diff (read-only comparison tool) +add_test(NAME wav-sigdiff-match + COMMAND ${BIN}/signal-diff -equiv 1 -q sigdiff_8k.wav sigdiff_8k.wav + WORKING_DIRECTORY ${WAV_TEST_DIR}) +set_tests_properties(wav-sigdiff-match PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT;WAV_FILES_EXT2") + +# --- decg722 WAV output --- +add_test(NAME wav-decg722-wav-output + COMMAND ${BIN}/decg722 -q -mode 1 -byte test_data/codspw.cod ${WAV_TEST_DIR}/decg722_out.wav + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/src/g722) +set_tests_properties(wav-decg722-wav-output PROPERTIES FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-decg722-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/decg722_out.wav 16000 1 16) +set_tests_properties(wav-decg722-wav-output-verify PROPERTIES + DEPENDS wav-decg722-wav-output) + +# ========================================================================== +# WAV output verification for all remaining tools +# ========================================================================== + +# g726demo: WAV output at 8000 Hz +add_test(NAME wav-g726-wav-output + COMMAND ${BIN}/g726demo -q a lilo 16 ${WAV_TEST_DIR}/g726_voice_8k.wav ${WAV_TEST_DIR}/g726_out.wav 256 1 64) +set_tests_properties(wav-g726-wav-output PROPERTIES FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-g726-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/g726_out.wav 8000 1 16) +set_tests_properties(wav-g726-wav-output-verify PROPERTIES DEPENDS wav-g726-wav-output) + +# vbr-g726: WAV output at 8000 Hz +add_test(NAME wav-vbr-g726-wav-output + COMMAND ${BIN}/vbr-g726 -q -law A -rate 16-24-32-40-32-24 ${WAV_TEST_DIR}/vbr_voice_8k.wav ${WAV_TEST_DIR}/vbr_out.wav) +set_tests_properties(wav-vbr-g726-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-vbr-g726-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/vbr_out.wav 8000 1 16) +set_tests_properties(wav-vbr-g726-wav-output-verify PROPERTIES DEPENDS wav-vbr-g726-wav-output) + +# g727demo: WAV output at 8000 Hz +add_test(NAME wav-g727-wav-output + COMMAND ${BIN}/g727demo -q -core 4 -enh 0 -enc -law A ${WAV_TEST_DIR}/g727_speech_8k.wav ${WAV_TEST_DIR}/g727_out.wav) +set_tests_properties(wav-g727-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT2") +add_test(NAME wav-g727-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/g727_out.wav 8000 1 16) +set_tests_properties(wav-g727-wav-output-verify PROPERTIES DEPENDS wav-g727-wav-output) + +# g711iplc: WAV output at 8000 Hz +add_test(NAME wav-g711iplc-wav-output + COMMAND ${BIN}/g711iplc -stats ${CMAKE_SOURCE_DIR}/src/g711iplc/test_data/fe10.g192 ${WAV_TEST_DIR}/g711iplc_8k.wav ${WAV_TEST_DIR}/g711iplc_out.wav) +set_tests_properties(wav-g711iplc-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-g711iplc-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/g711iplc_out.wav 8000 1 16) +set_tests_properties(wav-g711iplc-wav-output-verify PROPERTIES DEPENDS wav-g711iplc-wav-output) + +# filter: WAV output at 8000 Hz +add_test(NAME wav-filter-wav-output + COMMAND ${BIN}/filter -q IRS8 ${WAV_TEST_DIR}/filter_test_8k.wav ${WAV_TEST_DIR}/filter_out.wav) +set_tests_properties(wav-filter-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-filter-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/filter_out.wav 8000 1 16) +set_tests_properties(wav-filter-wav-output-verify PROPERTIES DEPENDS wav-filter-wav-output) + +# firdemo: WAV output at 8000 Hz +add_test(NAME wav-fir-wav-output + COMMAND ${BIN}/firdemo -q ${WAV_TEST_DIR}/fir_test_8k.wav ${WAV_TEST_DIR}/fir_out.wav 8 0 0 0 0 0) +set_tests_properties(wav-fir-wav-output PROPERTIES FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-fir-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/fir_out.wav 8000 1 16) +set_tests_properties(wav-fir-wav-output-verify PROPERTIES DEPENDS wav-fir-wav-output) + +# cirsdemo: WAV output at 8000 Hz +add_test(NAME wav-cirsdemo-wav-output + COMMAND ${BIN}/cirsdemo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/cirsdemo_out.wav) +set_tests_properties(wav-cirsdemo-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-cirsdemo-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/cirsdemo_out.wav 8000 1 16) +set_tests_properties(wav-cirsdemo-wav-output-verify PROPERTIES DEPENDS wav-cirsdemo-wav-output) + +# pcmdemo: WAV output at 8000 Hz +add_test(NAME wav-pcmdemo-wav-output + COMMAND ${BIN}/pcmdemo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/pcmdemo_out.wav 1_1 0 0) +set_tests_properties(wav-pcmdemo-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-pcmdemo-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/pcmdemo_out.wav 8000 1 16) +set_tests_properties(wav-pcmdemo-wav-output-verify PROPERTIES DEPENDS wav-pcmdemo-wav-output) + +# c712demo: WAV output at 8000 Hz +add_test(NAME wav-c712demo-wav-output + COMMAND ${BIN}/c712demo ${WAV_TEST_DIR}/iir_test_8k.wav ${WAV_TEST_DIR}/c712demo_out.wav) +set_tests_properties(wav-c712demo-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-c712demo-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/c712demo_out.wav 8000 1 16) +set_tests_properties(wav-c712demo-wav-output-verify PROPERTIES DEPENDS wav-c712demo-wav-output) + +# scaldemo: WAV output at 8000 Hz +add_test(NAME wav-scaldemo-wav-output + COMMAND ${BIN}/scaldemo -q -trunc ${WAV_TEST_DIR}/scal_voice_8k.wav ${WAV_TEST_DIR}/scal_out.wav 256 1 0 0.5941352) +set_tests_properties(wav-scaldemo-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-scaldemo-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/scal_out.wav 8000 1 16) +set_tests_properties(wav-scaldemo-wav-output-verify PROPERTIES DEPENDS wav-scaldemo-wav-output) + +# stereoop: WAV output at 32000 Hz +add_test(NAME wav-stereoop-wav-output + COMMAND ${BIN}/stereoop -q -interleave ${WAV_TEST_DIR}/stereo_L_32k.wav ${WAV_TEST_DIR}/stereo_R_32k.wav ${WAV_TEST_DIR}/stereoop_out.wav) +set_tests_properties(wav-stereoop-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-stereoop-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/stereoop_out.wav 32000 1 16) +set_tests_properties(wav-stereoop-wav-output-verify PROPERTIES DEPENDS wav-stereoop-wav-output) + +# astrip: WAV output at 8000 Hz +add_test(NAME wav-astrip-wav-output + COMMAND ${BIN}/astrip -q -smooth -wlen 145 -sample ${WAV_TEST_DIR}/unsup_bigend_8k.wav ${WAV_TEST_DIR}/astrip_out.wav) +set_tests_properties(wav-astrip-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-astrip-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/astrip_out.wav 8000 1 16) +set_tests_properties(wav-astrip-wav-output-verify PROPERTIES DEPENDS wav-astrip-wav-output) + +# fdelay: WAV output at 8000 Hz +add_test(NAME wav-fdelay-wav-output + COMMAND ${BIN}/fdelay ${WAV_TEST_DIR}/unsup_bigend_8k.wav ${WAV_TEST_DIR}/fdelay_out.wav) +set_tests_properties(wav-fdelay-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-fdelay-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/fdelay_out.wav 8000 1 16) +set_tests_properties(wav-fdelay-wav-output-verify PROPERTIES DEPENDS wav-fdelay-wav-output) + +# oper: WAV output at 8000 Hz +add_test(NAME wav-oper-wav-output + COMMAND ${BIN}/oper -q 1 ${WAV_TEST_DIR}/unsup_bigend_8k.wav + 1 ${WAV_TEST_DIR}/unsup_bigend_8k.wav 0 ${WAV_TEST_DIR}/oper_out.wav) +set_tests_properties(wav-oper-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-oper-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/oper_out.wav 8000 1 16) +set_tests_properties(wav-oper-wav-output-verify PROPERTIES DEPENDS wav-oper-wav-output) + +# esdru: WAV output at 48000 Hz +add_test(NAME wav-esdru-wav-output + COMMAND ${BIN}/esdru -e_out ${WAV_TEST_DIR}/esdru_el2.raw 0.2 ${WAV_TEST_DIR}/esdru_stereo_48k.wav ${WAV_TEST_DIR}/esdru_out.wav) +set_tests_properties(wav-esdru-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-esdru-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/esdru_out.wav 48000 1 16) +set_tests_properties(wav-esdru-wav-output-verify PROPERTIES DEPENDS wav-esdru-wav-output) + +# bs1770demo: WAV output at 48000 Hz +add_test(NAME wav-bs1770-wav-output + COMMAND ${BIN}/bs1770demo ${WAV_TEST_DIR}/bs1770_sine_48k.wav ${WAV_TEST_DIR}/bs1770_out.wav) +set_tests_properties(wav-bs1770-wav-output PROPERTIES FIXTURES_REQUIRED "WAV_FILES;WAV_FILES_EXT") +add_test(NAME wav-bs1770-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/bs1770_out.wav 48000 1 16) +set_tests_properties(wav-bs1770-wav-output-verify PROPERTIES DEPENDS wav-bs1770-wav-output) diff --git a/src/utl/test_wav_io_validate.c b/src/utl/test_wav_io_validate.c new file mode 100644 index 00000000..58a4f289 --- /dev/null +++ b/src/utl/test_wav_io_validate.c @@ -0,0 +1,39 @@ +/* test_wav_io_validate.c - Validate WAV file header parameters. + * + * Usage: test_wav_io_validate + * Returns 0 if WAV file matches all expected parameters, 1 otherwise. + */ +#include +#include +#include "wav_io.h" + +int main (int argc, char *argv[]) { + AUDIO_FILE *af; + long expected_rate; + int expected_channels, expected_bits; + + if (argc != 5) { + fprintf (stderr, "Usage: test_wav_io_validate \n"); + return 1; + } + + expected_rate = atol (argv[2]); + expected_channels = atoi (argv[3]); + expected_bits = atoi (argv[4]); + + af = audio_open_read (argv[1], expected_rate, expected_channels, expected_bits); + if (!af) { + fprintf (stderr, "FAIL: Cannot open or parameters mismatch: %s\n", argv[1]); + return 1; + } + + if (!audio_is_wav (af)) { + fprintf (stderr, "FAIL: %s is not a WAV file\n", argv[1]); + audio_close (af); + return 1; + } + + printf ("PASS: %s (rate=%ld, ch=%d, bits=%d)\n", argv[1], audio_get_sample_rate (af), audio_get_channels (af), af->bits_per_sample); + audio_close (af); + return 0; +} diff --git a/src/utl/wav_io.c b/src/utl/wav_io.c index 6e2f3899..cf943126 100644 --- a/src/utl/wav_io.c +++ b/src/utl/wav_io.c @@ -394,3 +394,25 @@ long audio_get_sample_rate (AUDIO_FILE * af) { int audio_get_channels (AUDIO_FILE * af) { return af ? af->channels : 0; } + + +int audio_seek (AUDIO_FILE * af, long offset) { + if (!af || !af->fp) + return -1; + return fseek (af->fp, af->data_offset + offset, SEEK_SET) < 0 ? -1 : 0; +} + + +long audio_get_data_size (AUDIO_FILE * af) { + if (!af || !af->fp) + return 0; + if (af->is_wav) + return af->data_size; + else { + long cur = ftell (af->fp); + fseek (af->fp, 0, SEEK_END); + long size = ftell (af->fp); + fseek (af->fp, cur, SEEK_SET); + return size; + } +} diff --git a/src/utl/wav_io.h b/src/utl/wav_io.h index cbadd2f8..45752764 100644 --- a/src/utl/wav_io.h +++ b/src/utl/wav_io.h @@ -60,4 +60,15 @@ long audio_get_sample_rate (AUDIO_FILE * af); /* Returns channel count from WAV header (0 if raw) */ int audio_get_channels (AUDIO_FILE * af); +/* Seek to a byte offset relative to the start of PCM data. + * For WAV files, accounts for the header (data_offset). + * For raw files, seeks from byte 0. + * Returns 0 on success, -1 on failure. */ +int audio_seek (AUDIO_FILE * af, long offset); + +/* Returns total size of PCM data in bytes. + * For WAV, returns the data chunk size from the header. + * For raw, returns the file size. */ +long audio_get_data_size (AUDIO_FILE * af); + #endif /* WAV_IO_H */ From 00f059637da4e921222611510fb12a85c5a12abe Mon Sep 17 00:00:00 2001 From: Ludovic Malfait Date: Sat, 30 May 2026 22:25:41 +0100 Subject: [PATCH 3/7] Fix remaining fseek/stat issues in g722demo, signal-diff, calc-snr, measure, bs1770demo, esdru --- src/bs1770demo/bs1770demo.c | 9 ++++----- src/esdru/esdru.c | 5 ++--- src/g722/g722demo.c | 11 ++++++----- src/mnru/calc-snr.c | 15 +++++++-------- src/unsup/measure.c | 2 +- src/utl/signal-diff.c | 27 ++++++++++++++------------- 6 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/bs1770demo/bs1770demo.c b/src/bs1770demo/bs1770demo.c index 674226ad..4bf03cb7 100644 --- a/src/bs1770demo/bs1770demo.c +++ b/src/bs1770demo/bs1770demo.c @@ -542,9 +542,8 @@ int main(int argc, char **argv ) fprintf( stdout, "nchan: %ld\n", nchan ); /* Find length of input file */ - fseek( f_input->fp, 0L, SEEK_END ); - length_total = ftell( f_input->fp ) / (2*nchan); /* 2 bytes per sample (16 bits), nchan channels */ - if( (ftell( f_input->fp ) % (2 * nchan)) != 0 ) + length_total = audio_get_data_size( f_input ) / (2*nchan); /* 2 bytes per sample (16 bits), nchan channels */ + if( (audio_get_data_size( f_input ) % (2 * nchan)) != 0 ) { fprintf( stderr, "*** Number of samples not divisible into number of channels, exiting..\n" ); exit( -1 ); @@ -554,7 +553,7 @@ int main(int argc, char **argv ) fprintf( stderr, "*** Input file must be longer than 400 ms to use bs1770demo, exiting..\n" ); exit( -1 ); } - rewind( f_input->fp ); + audio_seek( f_input, 0L ); n_gating_blocks = 4 * (length_total - BLOCK_SIZE) / (BLOCK_SIZE); /* Allocate input buffers */ @@ -611,7 +610,7 @@ int main(int argc, char **argv ) fac = find_scaling_factor( gating_block_energy, n_gating_blocks, lev_target, rms_flag, &lev_input, &lev_obtained ); /* Apply scaling */ - rewind( f_input->fp ); + audio_seek( f_input, 0L ); length_total = 0; clip = 0; while( (length = (long)fread( input_short, sizeof( short ), STEP_SIZE * nchan, f_input->fp ) ) ) diff --git a/src/esdru/esdru.c b/src/esdru/esdru.c index 934b4b57..6faa4e2c 100644 --- a/src/esdru/esdru.c +++ b/src/esdru/esdru.c @@ -426,9 +426,8 @@ int main(int argc, char **argv ) fseed = (float) intseed; /* Load input file */ - fseek( f_input->fp, 0L, SEEK_END ); - length = ftell( f_input->fp ) / 4; /* 2 bytes per sample, 2 channels */ - rewind( f_input->fp ); + length = audio_get_data_size( f_input ) / 4; /* 2 bytes per sample, 2 channels */ + audio_seek( f_input, 0L ); input = malloc(sizeof(double) * length * 2); input_short = malloc( sizeof( short ) * length * 2 ); m = malloc( sizeof( double ) * length ); diff --git a/src/g722/g722demo.c b/src/g722/g722demo.c index 70788641..ad1f7c4a 100644 --- a/src/g722/g722demo.c +++ b/src/g722/g722demo.c @@ -253,11 +253,8 @@ int main (int argc, char *argv[]) { /* Check if is to process the whole file */ if (N2 == 0) { - struct stat st; - - /* ... find the input file size ... */ - stat (FileIn, &st); - N2 = (long) ceil ((st.st_size - start_byte) / (double) (N * sizeof (short))); + /* N2 will be computed after opening file */ + N2 = 0; } /* Protect mode, if misgiven */ @@ -268,6 +265,10 @@ int main (int argc, char *argv[]) { if ((inp = audio_open_read (FileIn, 16000, 0, 16)) == NULL) KILL (FileIn, -2); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = (long) ceil ((audio_get_data_size (inp) - start_byte) / (double) (N * sizeof (short))); + /* Open output file */ if ((out = audio_open_write (FileOut, audio_get_sample_rate (inp), 1, 16)) == NULL) KILL (FileOut, -2); diff --git a/src/mnru/calc-snr.c b/src/mnru/calc-snr.c index 382ac564..6e0944f3 100644 --- a/src/mnru/calc-snr.c +++ b/src/mnru/calc-snr.c @@ -226,12 +226,7 @@ int main (int argc, char *argv[]) { out_is_file = YES; } - /* Check if is to process the whole file */ - if (N2 == 0) { - struct stat st; - stat (File1, &st); - N2 = st.st_size / (N * sizeof (short)); - } + /* N2 will be computed after opening files */ /* Open input files */ if ((F1 = audio_open_read (File1, 0, 0, 16)) == NULL) @@ -239,11 +234,15 @@ int main (int argc, char *argv[]) { if ((F2 = audio_open_read (File2, 0, 0, 16)) == NULL) KILL (File2, 3); + /* Compute number of blocks if processing the whole file */ + if (N2 == 0) + N2 = audio_get_data_size (F1) / (N * sizeof (short)); + /* Positions file to the starting of block N1 */ N1--; /* for the 1st block is not 1 but 0! */ - if (fseek (F1->fp, N1 * N * sizeof (short), 0) != 0l) + if (audio_seek (F1, N1 * N * sizeof (short)) != 0l) KILL (File1, 5); - if (fseek (F2->fp, N1 * N * sizeof (short), 0) != 0l) + if (audio_seek (F2, N1 * N * sizeof (short)) != 0l) KILL (File2, 6); /* Allocate memory for SNR vector */ diff --git a/src/unsup/measure.c b/src/unsup/measure.c index 905f37ff..3b66eddd 100644 --- a/src/unsup/measure.c +++ b/src/unsup/measure.c @@ -430,7 +430,7 @@ int main (int argc, char *argv[]) { KILL (inpfil, 2); /* Move onto start */ - fseek (Fi->fp, skip * blk * sizeof (short), 0); + audio_seek (Fi, skip * blk * sizeof (short)); /* Allocate memory */ samples = (short *) calloc (blk, sizeof (short)); diff --git a/src/utl/signal-diff.c b/src/utl/signal-diff.c index b9f6b3eb..4c122825 100644 --- a/src/utl/signal-diff.c +++ b/src/utl/signal-diff.c @@ -181,17 +181,8 @@ int main (int argc, char *argv[]) { /* Find number of blocks */ if (N2 == 0) { struct stat st; - long k, l; - - /* ... find the shortest of the 2 files and the number of blks from it */ - /* ... hey, need to skip the delayed samples! ... */ - stat (File1, &st); - k = (st.st_size - start_byte1) / (N * sizeof (short)); - stat (File2, &st); - l = (st.st_size - start_byte2) / (N * sizeof (short)); - N2 = k < l ? k : l; - if (k != l) - fprintf (stderr, "%%SUB-W-DIFSIZ: Files have different sizes!\n"); + /* N2 will be computed after opening files */ + N2 = 0; } /* Open input files */ @@ -200,11 +191,21 @@ int main (int argc, char *argv[]) { if ((F2 = audio_open_read (File2, 0, 0, 16)) == NULL) KILL (File2, 3); + /* Compute number of blocks if processing the whole files */ + if (N2 == 0) { + long k, l; + k = (audio_get_data_size (F1) - start_byte1) / (N * sizeof (short)); + l = (audio_get_data_size (F2) - start_byte2) / (N * sizeof (short)); + N2 = k < l ? k : l; + if (k != l) + fprintf (stderr, "%%SUB-W-DIFSIZ: Files have different sizes!\n"); + } + /* Positions file to the starting of block N1 */ N1--; /* for the 1st block is not 1 but 0! */ - if (fseek (F1->fp, start_byte1, 0) < 0l) + if (audio_seek (F1, start_byte1) < 0l) KILL (File1, 5); - if (fseek (F2->fp, start_byte2, 0) < 0l) + if (audio_seek (F2, start_byte2) < 0l) KILL (File2, 6); /* Print dump information */ From 242b84172704f04f3560675b76b31f51b9865638 Mon Sep 17 00:00:00 2001 From: Ludovic Malfait Date: Sat, 30 May 2026 22:32:49 +0100 Subject: [PATCH 4/7] Add wav_io support to sine generator Allows sine to output .wav files with correct sample rate header. Includes WAV output test verifying 16000 Hz header. Note: g728, g728fp, spdemo not integrated due to complexity (endianness handling, G.192 format conversion). --- src/unsup/CMakeLists.txt | 2 +- src/unsup/sine.c | 9 +++++---- src/utl/test_wav_integration.cmake | 8 ++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/unsup/CMakeLists.txt b/src/unsup/CMakeLists.txt index 9909f6f0..e922def2 100644 --- a/src/unsup/CMakeLists.txt +++ b/src/unsup/CMakeLists.txt @@ -30,7 +30,7 @@ target_link_libraries(oper ${M_LIBRARY}) add_executable(sb sb.c) -add_executable(sine sine.c) +add_executable(sine sine.c ../utl/wav_io.c) target_link_libraries(sine ${M_LIBRARY}) add_executable(chr2sh chr2sh.c) diff --git a/src/unsup/sine.c b/src/unsup/sine.c index cf4be20e..ad1608ac 100644 --- a/src/unsup/sine.c +++ b/src/unsup/sine.c @@ -75,6 +75,7 @@ #include #include #include +#include "wav_io.h" /* includes for OS specific directives */ #if defined(MSDOS) /* ... DOS ... */ @@ -182,7 +183,7 @@ int main (int argc, char *argv[]) { double refdB = 0; #endif - FILE *Fo; + AUDIO_FILE *Fo; static char FileOut[150]; int N = 256, blk_no = 0, DClevel = 0, AD_resolution = 16; #ifdef STATIC_ALLOCATION @@ -338,7 +339,7 @@ int main (int argc, char *argv[]) { #ifdef VMS sprintf (&mrs[4], "%d", 2 * N); #endif - if ((Fo = fopen (FileOut, WB)) == NULL) + if ((Fo = audio_open_write (FileOut, (long) fs, 1, 16)) == NULL) KILL (FileOut, 1); /* Report of what is happening ... */ @@ -388,12 +389,12 @@ int main (int argc, char *argv[]) { } /* Saving the sine; aborts program on failure */ - if (fwrite (data, sizeof (short), N, Fo) != N) + if (audio_write (Fo, data, N) != N) KILL (FileOut, 2); } /* Finalizations */ - fclose (Fo); + audio_close (Fo); #ifndef VMS return (0); #endif diff --git a/src/utl/test_wav_integration.cmake b/src/utl/test_wav_integration.cmake index 4ae4a247..3545f5b5 100644 --- a/src/utl/test_wav_integration.cmake +++ b/src/utl/test_wav_integration.cmake @@ -434,6 +434,14 @@ add_test(NAME wav-decg722-wav-output-verify set_tests_properties(wav-decg722-wav-output-verify PROPERTIES DEPENDS wav-decg722-wav-output) +# --- sine WAV output --- +add_test(NAME wav-sine-wav-output + COMMAND ${BIN}/sine -q ${WAV_TEST_DIR}/sine_out.wav 20000 1000 4 16000) +set_tests_properties(wav-sine-wav-output PROPERTIES FIXTURES_REQUIRED WAV_FILES) +add_test(NAME wav-sine-wav-output-verify + COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/sine_out.wav 16000 1 16) +set_tests_properties(wav-sine-wav-output-verify PROPERTIES DEPENDS wav-sine-wav-output) + # ========================================================================== # WAV output verification for all remaining tools # ========================================================================== From 0fdbfa61be36a45c96bdea1c728e96ba15f438a3 Mon Sep 17 00:00:00 2001 From: Ludovic Malfait Date: Sun, 31 May 2026 11:51:43 +0100 Subject: [PATCH 5/7] Remove wav-g726 tests for g726demo (expects A-law input, not PCM) g726demo operates on log-domain (A-law/mu-law) samples, not linear PCM. The tests incorrectly fed linear PCM to g726demo causing segfaults. vbr-g726 WAV tests already cover G.726 WAV integration correctly. --- src/utl/test_wav_integration.cmake | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/utl/test_wav_integration.cmake b/src/utl/test_wav_integration.cmake index 3545f5b5..3ca02138 100644 --- a/src/utl/test_wav_integration.cmake +++ b/src/utl/test_wav_integration.cmake @@ -76,10 +76,7 @@ set_tests_properties(wav-g711-match-verify PROPERTIES DEPENDS "wav-g711-match;wav-g711-match-raw") # G.726: WAV 8000 Hz input -add_test(NAME wav-g726-match - COMMAND ${BIN}/g726demo -q a lilo 16 ${WAV_TEST_DIR}/g726_voice_8k.wav ${WAV_TEST_DIR}/g726_out.raw 256 1 64) -set_tests_properties(wav-g726-match PROPERTIES - FIXTURES_REQUIRED WAV_FILES) +# g726demo: removed (g726demo expects A-law/mu-law input, not linear PCM; vbr-g726 WAV tests cover G.726) # SV56: WAV 16000 Hz input (matching default -sf 16000) add_test(NAME wav-sv56-match @@ -117,13 +114,6 @@ set_tests_properties(wav-g711-mismatch PROPERTIES FIXTURES_REQUIRED WAV_FILES WILL_FAIL TRUE) -# G.726: WAV 16000 Hz input (expects 8000 Hz) -add_test(NAME wav-g726-mismatch - COMMAND ${BIN}/g726demo -q a lilo 16 ${WAV_TEST_DIR}/g726_voice_16k.wav ${WAV_TEST_DIR}/g726_bad.raw 256 1 64) -set_tests_properties(wav-g726-mismatch PROPERTIES - FIXTURES_REQUIRED WAV_FILES - WILL_FAIL TRUE) - # SV56: WAV 44100 Hz input with -sf 16000 (explicit mismatch) add_test(NAME wav-sv56-mismatch COMMAND ${BIN}/sv56demo -q -sf 16000 ${WAV_TEST_DIR}/voice_44k.wav ${WAV_TEST_DIR}/sv56_bad.raw 256 1 0 -30) @@ -446,14 +436,6 @@ set_tests_properties(wav-sine-wav-output-verify PROPERTIES DEPENDS wav-sine-wav- # WAV output verification for all remaining tools # ========================================================================== -# g726demo: WAV output at 8000 Hz -add_test(NAME wav-g726-wav-output - COMMAND ${BIN}/g726demo -q a lilo 16 ${WAV_TEST_DIR}/g726_voice_8k.wav ${WAV_TEST_DIR}/g726_out.wav 256 1 64) -set_tests_properties(wav-g726-wav-output PROPERTIES FIXTURES_REQUIRED WAV_FILES) -add_test(NAME wav-g726-wav-output-verify - COMMAND ${BIN}/test_wav_io_validate ${WAV_TEST_DIR}/g726_out.wav 8000 1 16) -set_tests_properties(wav-g726-wav-output-verify PROPERTIES DEPENDS wav-g726-wav-output) - # vbr-g726: WAV output at 8000 Hz add_test(NAME wav-vbr-g726-wav-output COMMAND ${BIN}/vbr-g726 -q -law A -rate 16-24-32-40-32-24 ${WAV_TEST_DIR}/vbr_voice_8k.wav ${WAV_TEST_DIR}/vbr_out.wav) From e95324bc0c99dbba1395408961ccb0236998c31a Mon Sep 17 00:00:00 2001 From: "Jan.Reimes" Date: Tue, 9 Jun 2026 21:56:08 +0200 Subject: [PATCH 6/7] =?UTF-8?q?=E2=9C=A8=20feat(wav=5Fio):=20add=20support?= =?UTF-8?q?=20for=208/16/24/32-bit=20PCM=20and=2032-bit=20float=20WAV?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utl/wav_io.c | 2 +- src/utl/wav_io.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utl/wav_io.c b/src/utl/wav_io.c index cf943126..1594e1fa 100644 --- a/src/utl/wav_io.c +++ b/src/utl/wav_io.c @@ -1,6 +1,6 @@ /* wav_io.c - WAV file I/O support for STL tools * - * Minimal canonical WAV (RIFF) reader/writer for 16-bit PCM. + * Canonical WAV (RIFF) reader/writer for 8/16/24/32-bit PCM and 32-bit IEEE float. * See wav_io.h for API documentation. */ #include "wav_io.h" diff --git a/src/utl/wav_io.h b/src/utl/wav_io.h index 45752764..63c2f64c 100644 --- a/src/utl/wav_io.h +++ b/src/utl/wav_io.h @@ -3,7 +3,7 @@ * Provides transparent reading/writing of WAV and raw PCM files. * Input format is auto-detected (RIFF header check). * Output format is determined by filename extension (.wav = WAV, else raw). - * Only 16-bit PCM WAV is supported. + * Supports 8/16/24/32-bit PCM and 32-bit IEEE float WAV. */ #ifndef WAV_IO_H #define WAV_IO_H From 99e3a1400afa2b0108909242400bda13bc771e18 Mon Sep 17 00:00:00 2001 From: "Jan.Reimes" Date: Tue, 9 Jun 2026 21:57:27 +0200 Subject: [PATCH 7/7] =?UTF-8?q?=F0=9F=90=9B=20fix(wav=5Fio):=20correct=20b?= =?UTF-8?q?ps=20check=20for=208-bit=20samples=20(not=201-bit!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utl/wav_io.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/src/utl/wav_io.c b/src/utl/wav_io.c index 1594e1fa..733a123a 100644 --- a/src/utl/wav_io.c +++ b/src/utl/wav_io.c @@ -266,12 +266,12 @@ long audio_read (AUDIO_FILE * af, void *buffer, long nsamples) { sample_bytes = (bps == 24) ? 3 : (bps / 8); frame_bytes = sample_bytes * ch; - /* Simple case: mono or raw, and not 24-bit (can fread directly) */ - if (ch <= 1 && bps != 24) { + /* Raw files are native-endian; direct fread is safe for 8/16-bit mono */ + if (!af->is_wav && ch <= 1 && bps <= 2) { return (long) fread (buffer, (size_t) sample_bytes, (size_t) nsamples, af->fp); } - /* Multi-channel extraction or 24-bit unpacking */ + /* WAV (little-endian) and multi-channel: extract with byte-order handling */ { unsigned char *raw_buf; @@ -337,10 +337,39 @@ long audio_write (AUDIO_FILE * af, void *buffer, long nsamples) { sample_bytes = (bps == 24) ? 3 : (bps / 8); if (bps != 24) { - /* 8, 16, 32-bit or float: direct fwrite */ - n = (long) fwrite (buffer, (size_t) sample_bytes, (size_t) nsamples, af->fp); - af->data_size += n * sample_bytes; - return n; + /* For raw or 8-bit: direct fwrite (native endian or single byte) */ + if (!af->is_wav || bps == 8) { + n = (long) fwrite (buffer, (size_t) sample_bytes, (size_t) nsamples, af->fp); + af->data_size += n * sample_bytes; + return n; + } + /* WAV 16-bit: write little-endian */ + if (bps == 16) { + short *in = (short *) buffer; + for (i = 0; i < nsamples; i++) { + unsigned char b[2]; + b[0] = (unsigned char) (in[i] & 0xFF); + b[1] = (unsigned char) ((in[i] >> 8) & 0xFF); + if (fwrite (b, 1, 2, af->fp) != 2) break; + } + af->data_size += i * 2; + return i; + } + /* WAV 32-bit: write little-endian */ + { + int *in = (int *) buffer; + for (i = 0; i < nsamples; i++) { + unsigned char b[4]; + unsigned int val = (unsigned int) in[i]; + b[0] = (unsigned char) (val & 0xFF); + b[1] = (unsigned char) ((val >> 8) & 0xFF); + b[2] = (unsigned char) ((val >> 16) & 0xFF); + b[3] = (unsigned char) ((val >> 24) & 0xFF); + if (fwrite (b, 1, 4, af->fp) != 4) break; + } + af->data_size += i * 4; + return i; + } } /* 24-bit: pack from long */