diff -ur mp4alsRM22/src/AlsImf/ImfFileStream.cpp mp4alsRM22-shntool/src/AlsImf/ImfFileStream.cpp --- mp4alsRM22/src/AlsImf/ImfFileStream.cpp 2008-10-23 21:36:32.000000000 -0400 +++ mp4alsRM22-shntool/src/AlsImf/ImfFileStream.cpp 2008-11-16 00:23:45.000000000 -0500 @@ -150,16 +150,24 @@ } try { - // Open a file. - m_fp = FOPEN64( pFilename, "rb" ); - if ( m_fp == NULL ) throw E_OPEN_STREAM; - - // Seek to Offset. - if ( Offset != 0 ) { - if ( FSEEK64( m_fp, Offset, S_BEGIN ) != 0 ) throw E_SEEK_STREAM; - if ( FTELL64( m_fp ) != Offset ) throw E_SEEK_STREAM; + if (!strcmp(pFilename," ")) { + if (Offset != 0) + throw E_SEEK_STREAM; + m_fp = stdin; + m_Offset = Offset; + } + else { + // Open a file. + m_fp = FOPEN64( pFilename, "rb" ); + if ( m_fp == NULL ) throw E_OPEN_STREAM; + + // Seek to Offset. + if ( Offset != 0 ) { + if ( FSEEK64( m_fp, Offset, S_BEGIN ) != 0 ) throw E_SEEK_STREAM; + if ( FTELL64( m_fp ) != Offset ) throw E_SEEK_STREAM; + } + m_Offset = Offset; } - m_Offset = Offset; } catch( IMF_UINT32 ErrCode ) { // Clean up. @@ -296,24 +304,33 @@ } try { - // Open a file. - if ( Mode & FW_OPEN_EXISTING ) { - // Try to open an existing file. - m_fp = FOPEN64( pFilename, "r+b" ); - } - if ( m_fp == NULL ) { - // Create a new file. - m_fp = FOPEN64( pFilename, "wb" ); - if ( m_fp == NULL ) throw E_OPEN_STREAM; - } - - // Seek to Offset. - if ( Offset != 0 ) { - if ( FSEEK64( m_fp, Offset, S_BEGIN ) != 0 ) throw E_SEEK_STREAM; - if ( FTELL64( m_fp ) != Offset ) throw E_SEEK_STREAM; - } - m_Offset = Offset; - m_Mode = Mode; + if (!strcmp(pFilename," ")) { + if (Offset != 0) + throw E_SEEK_STREAM; + m_fp = stdout; + m_Offset = Offset; + m_Mode = Mode; + } + else { + // Open a file. + if ( Mode & FW_OPEN_EXISTING ) { + // Try to open an existing file. + m_fp = FOPEN64( pFilename, "r+b" ); + } + if ( m_fp == NULL ) { + // Create a new file. + m_fp = FOPEN64( pFilename, "wb" ); + if ( m_fp == NULL ) throw E_OPEN_STREAM; + } + + // Seek to Offset. + if ( Offset != 0 ) { + if ( FSEEK64( m_fp, Offset, S_BEGIN ) != 0 ) throw E_SEEK_STREAM; + if ( FTELL64( m_fp ) != Offset ) throw E_SEEK_STREAM; + } + m_Offset = Offset; + m_Mode = Mode; + } } catch( IMF_UINT32 ErrCode ) { // Clean up. diff -ur mp4alsRM22/src/encoder.cpp mp4alsRM22-shntool/src/encoder.cpp --- mp4alsRM22/src/encoder.cpp 2008-10-30 00:18:22.000000000 -0400 +++ mp4alsRM22-shntool/src/encoder.cpp 2008-11-16 00:23:45.000000000 -0500 @@ -394,7 +394,7 @@ if ( RawAudio ) throw 0; // RAW // Try wave format - HeaderSize = GetWaveFormatPCM( fpInput, &wf, &Samples ); + HeaderSize = GetWaveFormatPCM( fpInput, &wf, &Samples, ainfo ); if ( HeaderSize >= 0 ) throw 1; // WAVE // Try aiff format @@ -418,9 +418,11 @@ FileType = static_cast( ft ); } - fseek(fpInput, 0L, SEEK_END); - FileLen = ftell(fpInput); - rewind(fpInput); + if (strcmp(ainfo->FileName," ")) { + fseek(fpInput, 0L, SEEK_END); + FileLen = ftell(fpInput); + rewind(fpInput); + } if ( ( FileType == 1 ) || ( FileType == 3 ) || ( FileType == 4 ) || ( FileType == 5 ) ) { @@ -443,6 +445,10 @@ // Invalid FormatTag return -1; } + + if (!strcmp(ainfo->FileName," ")) { + FileLen = HeaderSize + DataLen; + } } else if (FileType == 2) { @@ -536,7 +542,7 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// // Generate and write header -ALS_INT64 CLpacEncoder::WriteHeader(ENCINFO *encinfo) +ALS_INT64 CLpacEncoder::WriteHeader(ENCINFO *encinfo, AUDIOINFO *ainfo) { BYTE audiotyp, tmp = 0; long i, j, rest; @@ -828,8 +834,13 @@ fseek( fpInput, HeaderSize, SEEK_CUR ); } else { // copy audio file header (if present) - fread( buff, 1, static_cast( HeaderSize ), fpInput ); - if ( fwrite( buff, 1, static_cast( HeaderSize ), fpOutput ) != static_cast( HeaderSize ) ) return ( frames = -2 ); + if (ainfo && !strcmp(ainfo->FileName," ")) { + if ( fwrite( ainfo->Header, 1, static_cast( HeaderSize ), fpOutput ) != static_cast( HeaderSize ) ) return ( frames = -2 ); + } + else { + fread( buff, 1, static_cast( HeaderSize ), fpInput ); + if ( fwrite( buff, 1, static_cast( HeaderSize ), fpOutput ) != static_cast( HeaderSize ) ) return ( frames = -2 ); + } } // get current position and write dummy bytes for trailer (if present) @@ -904,12 +915,12 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// // Generate and write header, encoded audio, and trailing non-audio data -short CLpacEncoder::EncodeAll() +short CLpacEncoder::EncodeAll(AUDIOINFO *ainfo) { long f; ENCINFO encinfo; - if ((frames = WriteHeader(&encinfo)) < 0) + if ((frames = WriteHeader(&encinfo,ainfo)) < 0) return static_cast( frames ); for (f = 0; f < frames; f++) diff -ur mp4alsRM22/src/encoder.h mp4alsRM22-shntool/src/encoder.h --- mp4alsRM22/src/encoder.h 2008-10-23 21:36:34.000000000 -0400 +++ mp4alsRM22-shntool/src/encoder.h 2008-11-16 00:23:45.000000000 -0500 @@ -206,9 +206,9 @@ short SpecifyAudioInfo(AUDIOINFO *ainfo); short OpenOutputFile( const char *name, bool mp4, bool oafi ) { mp4file = mp4; oafi_flag = oafi; CloseOutput = ( OpenFileWriter( name, &fpOutput ) == 0 ); return CloseOutput ? 0 : 1; } short SetOutputFile( HALSSTREAM hStream, bool mp4, bool oafi ) { mp4file = mp4; oafi_flag = oafi; fpOutput = hStream; CloseOutput = false; return 0; } - ALS_INT64 WriteHeader(ENCINFO *encinfo); + ALS_INT64 WriteHeader(ENCINFO *encinfo, AUDIOINFO *ainfo = NULL); ALS_INT64 WriteTrailer(); - short EncodeAll(); + short EncodeAll(AUDIOINFO *ainfo = NULL); long SetFrameLength(long N); short SetOrder(short P); diff -ur mp4alsRM22/src/mp4als.cpp mp4alsRM22-shntool/src/mp4als.cpp --- mp4alsRM22/src/mp4als.cpp 2008-10-23 21:36:34.000000000 -0400 +++ mp4alsRM22-shntool/src/mp4als.cpp 2008-11-16 00:23:45.000000000 -0500 @@ -205,7 +205,7 @@ void ShowUsage(void); void ShowHelp(void); -int main(short argc, char **argv) +int main(int argc, char **argv) { clock_t start, finish; short verbose, decode, info, autoname = 0, output, len, crc = 0, result = 0, input, wrongext; @@ -363,6 +363,7 @@ fprintf(stderr, "\nUnable to open file %s for reading!\n", infile); exit(3); } + ainfo.FileName = infile; // Raw input file if (encoder.SetRawAudio(CheckOption(argc, argv, "-R"))) @@ -563,7 +564,7 @@ // Encoding /////////////////////////////////////////////////////////////////////////////// if (!verbose) { - result = encoder.EncodeAll(); + result = encoder.EncodeAll(&ainfo); } else { @@ -571,7 +572,7 @@ ALS_INT64 frames, f; // Generate and write header - if ((frames = encoder.WriteHeader(&encinfo)) < 0) + if ((frames = encoder.WriteHeader(&encinfo, &ainfo)) < 0) result = (short)frames; if (frames < 1000) diff -ur mp4alsRM22/src/wave.cpp mp4alsRM22-shntool/src/wave.cpp --- mp4alsRM22/src/wave.cpp 2008-10-23 21:36:32.000000000 -0400 +++ mp4alsRM22-shntool/src/wave.cpp 2008-11-16 00:23:45.000000000 -0500 @@ -63,58 +63,71 @@ #include "wave.h" #include "stream.h" -ALS_INT64 GetWaveFormatPCM(HALSSTREAM wav, WAVEFORMATPCM *wf, ALS_INT64 *samples) +ALS_INT64 GetWaveFormatPCM(HALSSTREAM wav, WAVEFORMATPCM *wf, ALS_INT64 *samples, AUDIOINFO *ainfo) { char RiffChunkRef[4] = {'R', 'I', 'F', 'F'}; char WaveChunkRef[4] = {'W', 'A', 'V', 'E'}; char FormChunkRef[4] = {'f', 'm', 't', ' '}; char DataChunkRef[4] = {'d', 'a', 't', 'a'}; - char RiffChunk[4], WaveChunk[4]; - char ChunkBuf[4]; + unsigned char *RiffChunk, *WaveChunk; + unsigned char *ChunkBuf; ALS_INT64 RiffLen, FormLen, DataLen, ChunkLen, ChunkLenSum, i; + int pos = 0; // Read file header // 'RIFF' + RiffChunk = ainfo->Header + pos; fread(RiffChunk, 1, 4, wav); + pos += 4; if (memcmp(RiffChunk, RiffChunkRef, 4) != 0) return(-1); - RiffLen = ReadULongLSBfirst(wav); + RiffLen = ReadULongLSBfirstBuf(wav, ainfo->Header, &pos); // 'WAVE' + WaveChunk = ainfo->Header + pos; fread(WaveChunk, 1, 4, wav); + pos += 4; if (memcmp(WaveChunk, WaveChunkRef, 4) != 0) return(-2); // 'fmt ' - //fread(FormChunk, 1, 4, wav); ChunkLenSum = FormLen = 0; + ChunkBuf = ainfo->Header + pos; fread(ChunkBuf, 1, 4, wav); + pos += 4; while(memcmp(ChunkBuf, DataChunkRef, 4) != 0) { if (memcmp(ChunkBuf, FormChunkRef, 4) != 0) { //unknown chank befor fmt - ChunkLen = ReadULongLSBfirst(wav); - for(i=0;iHeader, &pos); + for(i=0;iHeader + pos; fread(ChunkBuf, 1, 1, wav); + pos += 1; + } ChunkLenSum += (ChunkLen + 8); + ChunkBuf = ainfo->Header + pos; fread(ChunkBuf, 1, 4, wav); + pos += 4; } else { - FormLen = ReadULongLSBfirst(wav); - if ( !ReadWaveFormat( wav, wf, FormLen ) ) return (-3); + FormLen = ReadULongLSBfirstBuf(wav, ainfo->Header, &pos); + if ( !ReadWaveFormat( wav, wf, FormLen, ainfo->Header, &pos ) ) return (-3); + ChunkBuf = ainfo->Header + pos; fread(ChunkBuf, 1, 4, wav); + pos += 4; } } // 'data' - //fread(DataChunk, 1, 4, wav); - DataLen = ReadULongLSBfirst(wav); + DataLen = ReadULongLSBfirstBuf(wav, ainfo->Header, &pos); if (memcmp(ChunkBuf, DataChunkRef, 4) != 0) // Additional unknown chunk { fseek(wav, DataLen, SEEK_CUR); FormLen += DataLen + 8; // Add size of unknown chunk fread(ChunkBuf, 1, 4, wav); - DataLen = ReadULongLSBfirst(wav); + pos += 4; + DataLen = ReadULongLSBfirstBuf(wav, ainfo->Header, &pos); if (memcmp(ChunkBuf, DataChunkRef, 4) != 0) return(-5); } @@ -181,6 +194,20 @@ return(((unsigned short)tmp[1] << 8) + (unsigned short)tmp[0]); } +unsigned short ReadUShortLSBfirstBuf(HALSSTREAM fp, unsigned char *buf, int *n) +{ + unsigned char *tmp; + + if (NULL == buf || NULL == n) + return ReadUShortLSBfirst(fp); + + tmp = buf + *n; + + *n += fread(tmp, 1, 2, fp); + + return(((unsigned short)tmp[1] << 8) + (unsigned short)tmp[0]); +} + unsigned short ReadUShortMSBfirst(HALSSTREAM fp) { unsigned char tmp[2]; @@ -224,6 +251,21 @@ + ((unsigned long)tmp[1] << 8) + (unsigned long)tmp[0]); } +unsigned long ReadULongLSBfirstBuf(HALSSTREAM fp, unsigned char *buf, int *n) +{ + unsigned char *tmp; + + if (NULL == buf || NULL == n) + return ReadULongLSBfirst(fp); + + tmp = buf + *n; + + *n += fread(tmp, 1, 4, fp); + + return(((unsigned long)tmp[3] << 24) + ((unsigned long)tmp[2] << 16) + + ((unsigned long)tmp[1] << 8) + (unsigned long)tmp[0]); +} + unsigned long ReadULongMSBfirst(HALSSTREAM fp) { unsigned char tmp[4]; @@ -462,7 +504,7 @@ if ( ChunkLen < ( sizeof(ChunkBuf) + sizeof(ALS_INT64) + 16 ) ) throw false; ChunkLen -= sizeof(ChunkBuf) + sizeof(ALS_INT64); - if ( !ReadWaveFormat( wav, wf, ChunkLen ) ) throw false; + if ( !ReadWaveFormat( wav, wf, ChunkLen, NULL, NULL ) ) throw false; // byte-aligned on 8-byte boundaries. Pos = ftell( wav ); @@ -543,7 +585,7 @@ ChunkLen = ReadULongLSBfirst( wav ); if ( ChunkLen < 16 ) throw false; - if ( !ReadWaveFormat( wav, wf, ChunkLen ) ) throw false; + if ( !ReadWaveFormat( wav, wf, ChunkLen, NULL, NULL ) ) throw false; bReadFormChunk = true; } // Read the next Chunk @@ -562,7 +604,7 @@ } } -bool ReadWaveFormat( HALSSTREAM wav, WAVEFORMATPCM* pFmt, ALS_INT64 FmtLen ) +bool ReadWaveFormat( HALSSTREAM wav, WAVEFORMATPCM* pFmt, ALS_INT64 FmtLen, unsigned char *buf, int *bufpos) { USHORT cbSize; BYTE SubFormat[16]; @@ -573,24 +615,24 @@ if ( FmtLen < 16 ) return false; // Read common fields for PCMWAVEFORMAT, WAVEFORMATEX and WAVEFORMATEXTENSIBLE. - pFmt->FormatTag = ReadUShortLSBfirst( wav ); - pFmt->Channels = ReadUShortLSBfirst( wav ); - pFmt->SamplesPerSec = ReadULongLSBfirst( wav ); - pFmt->AvgBytesPerSec = ReadULongLSBfirst( wav ); - pFmt->BlockAlign = ReadUShortLSBfirst( wav ); - pFmt->BitsPerSample = ReadUShortLSBfirst( wav ); + pFmt->FormatTag = ReadUShortLSBfirstBuf( wav, buf, bufpos ); + pFmt->Channels = ReadUShortLSBfirstBuf( wav, buf, bufpos ); + pFmt->SamplesPerSec = ReadULongLSBfirstBuf( wav, buf, bufpos ); + pFmt->AvgBytesPerSec = ReadULongLSBfirstBuf( wav, buf, bufpos ); + pFmt->BlockAlign = ReadUShortLSBfirstBuf( wav, buf, bufpos ); + pFmt->BitsPerSample = ReadUShortLSBfirstBuf( wav, buf, bufpos ); pFmt->ValidBitsPerSample = pFmt->BitsPerSample; // Check the fmt length. if ( FmtLen >= 16 + 2 ) { // Read cbSize. - cbSize = ReadUShortLSBfirst( wav ); + cbSize = ReadUShortLSBfirstBuf( wav, buf, bufpos ); if ( FmtLen != 16 + 2 + cbSize ) return false; if ( pFmt->FormatTag == 0xfffe ) { // WAVEFORMATEXTENSIBLE // Read wValidBitsPerSample. - pFmt->ValidBitsPerSample = ReadUShortLSBfirst( wav ); + pFmt->ValidBitsPerSample = ReadUShortLSBfirstBuf( wav, buf, bufpos ); // Skip dwChannelMask. - ReadULongLSBfirst( wav ); + ReadULongLSBfirstBuf( wav, buf, bufpos ); // Read SubFormat. if ( fread( SubFormat, 1, 16, wav ) != 16 ) return false; if ( memcmp( SubFormat, SubFormatPCM, 16 ) == 0 ) pFmt->FormatTag = 1; diff -ur mp4alsRM22/src/wave.h mp4alsRM22-shntool/src/wave.h --- mp4alsRM22/src/wave.h 2008-10-23 21:36:34.000000000 -0400 +++ mp4alsRM22-shntool/src/wave.h 2008-11-16 00:23:45.000000000 -0500 @@ -88,13 +88,13 @@ typedef struct { - USHORT FormatTag PACKED; // WAVE_FORMAT_PCM = 1, WAVE_FORMAT_IEEE_FLOAT = 3 - USHORT Channels PACKED; // Mono = 1, Stereo = 2, Multichannel > 2 (undefined channel mapping) - ULONG SamplesPerSec PACKED; // Sampling frequency (in Hz) - ULONG AvgBytesPerSec PACKED; // Bytes per second (SampPerSec * BlockAlign) - USHORT BlockAlign PACKED; // Bytes per sample step (1...4 * Channels) - USHORT BitsPerSample PACKED; // Bits per sample (typically 8, 16, 24 or 32) - USHORT ValidBitsPerSample PACKED; // Valid bits per sample + USHORT FormatTag PACKED; // WAVE_FORMAT_PCM = 1, WAVE_FORMAT_IEEE_FLOAT = 3 + USHORT Channels PACKED; // Mono = 1, Stereo = 2, Multichannel > 2 (undefined channel mapping) + ULONG SamplesPerSec PACKED; // Sampling frequency (in Hz) + ULONG AvgBytesPerSec PACKED; // Bytes per second (SampPerSec * BlockAlign) + USHORT BlockAlign PACKED; // Bytes per sample step (1...4 * Channels) + USHORT BitsPerSample PACKED; // Bits per sample (typically 8, 16, 24 or 32) + USHORT ValidBitsPerSample PACKED; // Valid bits per sample } WAVEFORMATPCM; typedef struct @@ -153,6 +153,8 @@ unsigned long Freq; // Sample Rate in Hz ALS_INT64 HeaderSize; // Header Size in Bytes ALS_INT64 TrailerSize; // Trailer Size in Bytes + unsigned char Header[4096]; // Header contents + char* FileName; // File name } AUDIOINFO; typedef struct @@ -171,20 +173,22 @@ } ENCINFO; // Functions -ALS_INT64 GetWaveFormatPCM(HALSSTREAM wav,WAVEFORMATPCM *wf, ALS_INT64 *samples); +ALS_INT64 GetWaveFormatPCM(HALSSTREAM wav,WAVEFORMATPCM *wf, ALS_INT64 *samples, AUDIOINFO *ainfo); short WriteWaveHeaderPCM(HALSSTREAM wav, WAVEFORMATPCM *wf, ULONG *samples); ALS_INT64 GetAiffFormat(HALSSTREAM aif, AIFFCOMMON *ac, ALS_INT64 *Offset, ALS_INT64 *BlockSize, ULONG *samplerate); ALS_INT64 GetWave64FormatPCM(HALSSTREAM wav, WAVEFORMATPCM* wf, ALS_INT64* samples); ALS_INT64 GetRF64FormatPCM(HALSSTREAM wav, WAVEFORMATPCM* wf, ALS_INT64* samples); -bool ReadWaveFormat( HALSSTREAM wav, WAVEFORMATPCM* pFmt, ALS_INT64 FmtLen ); +bool ReadWaveFormat( HALSSTREAM wav, WAVEFORMATPCM* pFmt, ALS_INT64 FmtLen, unsigned char *buf, int *bufpos); void WriteUShortLSBfirst(unsigned short x, HALSSTREAM fp); void WriteUShortMSBfirst(unsigned short x, HALSSTREAM fp); unsigned short ReadUShortLSBfirst(HALSSTREAM fp); +unsigned short ReadUShortLSBfirstBuf(HALSSTREAM fp, unsigned char *tmp, int *n); unsigned short ReadUShortMSBfirst(HALSSTREAM fp); void WriteULongLSBfirst(unsigned long x, HALSSTREAM fp); void WriteULongMSBfirst(unsigned long x, HALSSTREAM fp); unsigned long ReadULongLSBfirst(HALSSTREAM fp); +unsigned long ReadULongLSBfirstBuf(HALSSTREAM fp, unsigned char *tmp, int *n); unsigned long ReadULongMSBfirst(HALSSTREAM fp); void WriteUINT64LSBfirst(ALS_UINT64 x, HALSSTREAM fp); void WriteUINT64MSBfirst(ALS_UINT64 x, HALSSTREAM fp);