FS-4657 --resolve update libsndfile to its latest master

This commit is contained in:
Jeff Lenk committed 2014-02-21 16:10:32 -06:00
1 parent 0c1f6ef2ed
commit 199a64bf6a
291 files changed
+25965 -5744

No files matched your search

+200
View File
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: ALACAudioTypes.h
*/
#ifndef ALACAUDIOTYPES_H
#define ALACAUDIOTYPES_H
/* Force these Mac OS specific things to zero. */
#define PRAGMA_STRUCT_ALIGN 0
#define PRAGMA_STRUCT_PACKPUSH 0
#define PRAGMA_STRUCT_PACK 0
#define PRAGMA_ONCE 0
#define PRAGMA_MARK 0
#if PRAGMA_ONCE
#pragma once
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "sfendian.h"
#if CPU_IS_BIG_ENDIAN == 1
#define TARGET_RT_BIG_ENDIAN 1
#else
#define TARGET_RT_BIG_ENDIAN 0
#endif
#define kChannelAtomSize 12
enum
{
kALAC_UnimplementedError = -4,
kALAC_FileNotFoundError = -43,
kALAC_ParamError = -50,
kALAC_MemFullError = -108,
fALAC_FrameLengthError = -666,
};
enum
{
kALACFormatAppleLossless = MAKE_MARKER ('a', 'l', 'a', 'c'),
kALACFormatLinearPCM = MAKE_MARKER ('l', 'p', 'c', 'm')
};
enum
{
kALACMaxChannels = 8,
kALACMaxEscapeHeaderBytes = 8,
kALACMaxSearches = 16,
kALACMaxCoefs = 16,
kALACDefaultFramesPerPacket = 4096
};
typedef uint32_t ALACChannelLayoutTag;
enum
{
kALACFormatFlagIsFloat = (1 << 0), // 0x1
kALACFormatFlagIsBigEndian = (1 << 1), // 0x2
kALACFormatFlagIsSignedInteger = (1 << 2), // 0x4
kALACFormatFlagIsPacked = (1 << 3), // 0x8
kALACFormatFlagIsAlignedHigh = (1 << 4), // 0x10
};
enum
{
#if TARGET_RT_BIG_ENDIAN
kALACFormatFlagsNativeEndian = kALACFormatFlagIsBigEndian
#else
kALACFormatFlagsNativeEndian = 0
#endif
};
// this is required to be an IEEE 64bit float
typedef double alac_float64_t;
// These are the Channel Layout Tags used in the Channel Layout Info portion of the ALAC magic cookie
enum
{
kALACChannelLayoutTag_Mono = (100<<16) | 1, // C
kALACChannelLayoutTag_Stereo = (101<<16) | 2, // L R
kALACChannelLayoutTag_MPEG_3_0_B = (113<<16) | 3, // C L R
kALACChannelLayoutTag_MPEG_4_0_B = (116<<16) | 4, // C L R Cs
kALACChannelLayoutTag_MPEG_5_0_D = (120<<16) | 5, // C L R Ls Rs
kALACChannelLayoutTag_MPEG_5_1_D = (124<<16) | 6, // C L R Ls Rs LFE
kALACChannelLayoutTag_AAC_6_1 = (142<<16) | 7, // C L R Ls Rs Cs LFE
kALACChannelLayoutTag_MPEG_7_1_B = (127<<16) | 8 // C Lc Rc L R Ls Rs LFE (doc: IS-13818-7 MPEG2-AAC)
};
// ALAC currently only utilizes these channels layouts. There is a one for one correspondance between a
// given number of channels and one of these layout tags
static const ALACChannelLayoutTag ALACChannelLayoutTags[kALACMaxChannels] =
{
kALACChannelLayoutTag_Mono, // C
kALACChannelLayoutTag_Stereo, // L R
kALACChannelLayoutTag_MPEG_3_0_B, // C L R
kALACChannelLayoutTag_MPEG_4_0_B, // C L R Cs
kALACChannelLayoutTag_MPEG_5_0_D, // C L R Ls Rs
kALACChannelLayoutTag_MPEG_5_1_D, // C L R Ls Rs LFE
kALACChannelLayoutTag_AAC_6_1, // C L R Ls Rs Cs LFE
kALACChannelLayoutTag_MPEG_7_1_B // C Lc Rc L R Ls Rs LFE (doc: IS-13818-7 MPEG2-AAC)
};
// AudioChannelLayout from CoreAudioTypes.h. We never need the AudioChannelDescription so we remove it
struct ALACAudioChannelLayout
{
ALACChannelLayoutTag mChannelLayoutTag;
uint32_t mChannelBitmap;
uint32_t mNumberChannelDescriptions;
};
typedef struct ALACAudioChannelLayout ALACAudioChannelLayout;
struct AudioFormatDescription
{
alac_float64_t mSampleRate;
uint32_t mFormatID;
uint32_t mFormatFlags;
uint32_t mBytesPerPacket;
uint32_t mFramesPerPacket;
uint32_t mBytesPerFrame;
uint32_t mChannelsPerFrame;
uint32_t mBitsPerChannel;
uint32_t mReserved;
};
typedef struct AudioFormatDescription AudioFormatDescription;
/* Lossless Definitions */
enum
{
kALACCodecFormat = MAKE_MARKER ('a', 'l', 'a', 'c'),
kALACVersion = 0,
kALACCompatibleVersion = kALACVersion,
kALACDefaultFrameSize = 4096
};
// note: this struct is wrapped in an 'alac' atom in the sample description extension area
// note: in QT movies, it will be further wrapped in a 'wave' atom surrounded by 'frma' and 'term' atoms
typedef struct ALACSpecificConfig
{
uint32_t frameLength;
uint8_t compatibleVersion;
uint8_t bitDepth; // max 32
uint8_t pb; // 0 <= pb <= 255
uint8_t mb;
uint8_t kb;
uint8_t numChannels;
uint16_t maxRun;
uint32_t maxFrameBytes;
uint32_t avgBitRate;
uint32_t sampleRate;
} ALACSpecificConfig;
// The AudioChannelLayout atom type is not exposed yet so define it here
enum
{
AudioChannelLayoutAID = MAKE_MARKER ('c', 'h', 'a', 'n')
};
#if PRAGMA_STRUCT_ALIGN
#pragma options align=reset
#elif PRAGMA_STRUCT_PACKPUSH
#pragma pack(pop)
#elif PRAGMA_STRUCT_PACK
#pragma pack()
#endif
#ifdef __cplusplus
}
#endif
#endif /* ALACAUDIOTYPES_H */
+262
View File
@@ -0,0 +1,262 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*=============================================================================
File: ALACBitUtilities.c
$NoKeywords: $
=============================================================================*/
#include <stdio.h>
#include "ALACBitUtilities.h"
#define PRAGMA_MARK 0
// BitBufferInit
//
void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize )
{
bits->cur = buffer;
bits->end = bits->cur + byteSize;
bits->bitIndex = 0;
bits->byteSize = byteSize;
}
// BitBufferRead
//
uint32_t BitBufferRead( BitBuffer * bits, uint8_t numBits )
{
uint32_t returnBits;
//Assert( numBits <= 16 );
returnBits = ((uint32_t)bits->cur[0] << 16) | ((uint32_t)bits->cur[1] << 8) | ((uint32_t)bits->cur[2]);
returnBits = returnBits << bits->bitIndex;
returnBits &= 0x00FFFFFF;
bits->bitIndex += numBits;
returnBits = returnBits >> (24 - numBits);
bits->cur += (bits->bitIndex >> 3);
bits->bitIndex &= 7;
//Assert( bits->cur <= bits->end );
return returnBits;
}
// BitBufferReadSmall
//
// Reads up to 8 bits
uint8_t BitBufferReadSmall( BitBuffer * bits, uint8_t numBits )
{
uint16_t returnBits;
//Assert( numBits <= 8 );
returnBits = (bits->cur[0] << 8) | bits->cur[1];
returnBits = returnBits << bits->bitIndex;
bits->bitIndex += numBits;
returnBits = returnBits >> (16 - numBits);
bits->cur += (bits->bitIndex >> 3);
bits->bitIndex &= 7;
//Assert( bits->cur <= bits->end );
return (uint8_t)returnBits;
}
// BitBufferReadOne
//
// Reads one byte
uint8_t BitBufferReadOne( BitBuffer * bits )
{
uint8_t returnBits;
returnBits = (bits->cur[0] >> (7 - bits->bitIndex)) & 1;
bits->bitIndex++;
bits->cur += (bits->bitIndex >> 3);
bits->bitIndex &= 7;
//Assert( bits->cur <= bits->end );
return returnBits;
}
// BitBufferPeek
//
uint32_t BitBufferPeek( BitBuffer * bits, uint8_t numBits )
{
return ((((((uint32_t) bits->cur[0] << 16) | ((uint32_t) bits->cur[1] << 8) |
((uint32_t) bits->cur[2])) << bits->bitIndex) & 0x00FFFFFF) >> (24 - numBits));
}
// BitBufferPeekOne
//
uint32_t BitBufferPeekOne( BitBuffer * bits )
{
return ((bits->cur[0] >> (7 - bits->bitIndex)) & 1);
}
// BitBufferUnpackBERSize
//
uint32_t BitBufferUnpackBERSize( BitBuffer * bits )
{
uint32_t size;
uint8_t tmp;
for ( size = 0, tmp = 0x80u; tmp &= 0x80u; size = (size << 7u) | (tmp & 0x7fu) )
tmp = (uint8_t) BitBufferReadSmall( bits, 8 );
return size;
}
// BitBufferGetPosition
//
uint32_t BitBufferGetPosition( BitBuffer * bits )
{
uint8_t * begin;
begin = bits->end - bits->byteSize;
return ((uint32_t)(bits->cur - begin) * 8) + bits->bitIndex;
}
// BitBufferByteAlign
//
void BitBufferByteAlign( BitBuffer * bits, int32_t addZeros )
{
// align bit buffer to next byte boundary, writing zeros if requested
if ( bits->bitIndex == 0 )
return;
if ( addZeros )
BitBufferWrite( bits, 0, 8 - bits->bitIndex );
else
BitBufferAdvance( bits, 8 - bits->bitIndex );
}
// BitBufferAdvance
//
void BitBufferAdvance( BitBuffer * bits, uint32_t numBits )
{
if ( numBits )
{
bits->bitIndex += numBits;
bits->cur += (bits->bitIndex >> 3);
bits->bitIndex &= 7;
}
}
// BitBufferRewind
//
void BitBufferRewind( BitBuffer * bits, uint32_t numBits )
{
uint32_t numBytes;
if ( numBits == 0 )
return;
if ( bits->bitIndex >= numBits )
{
bits->bitIndex -= numBits;
return;
}
numBits -= bits->bitIndex;
bits->bitIndex = 0;
numBytes = numBits / 8;
numBits = numBits % 8;
bits->cur -= numBytes;
if ( numBits > 0 )
{
bits->bitIndex = 8 - numBits;
bits->cur--;
}
if ( bits->cur < (bits->end - bits->byteSize) )
{
//DebugCMsg("BitBufferRewind: Rewound too far.");
bits->cur = (bits->end - bits->byteSize);
bits->bitIndex = 0;
}
}
// BitBufferWrite
//
void BitBufferWrite( BitBuffer * bits, uint32_t bitValues, uint32_t numBits )
{
uint32_t invBitIndex;
RequireAction( bits != NULL, return; );
RequireActionSilent( numBits > 0, return; );
invBitIndex = 8 - bits->bitIndex;
while ( numBits > 0 )
{
uint32_t tmp;
uint8_t shift;
uint8_t mask;
uint32_t curNum;
curNum = MIN( invBitIndex, numBits );
tmp = bitValues >> (numBits - curNum);
shift = (uint8_t)(invBitIndex - curNum);
mask = 0xffu >> (8 - curNum); // must be done in two steps to avoid compiler sequencing ambiguity
mask <<= shift;
bits->cur[0] = (bits->cur[0] & ~mask) | (((uint8_t) tmp << shift) & mask);
numBits -= curNum;
// increment to next byte if need be
invBitIndex -= curNum;
if ( invBitIndex == 0 )
{
invBitIndex = 8;
bits->cur++;
}
}
bits->bitIndex = 8 - invBitIndex;
}
void BitBufferReset( BitBuffer * bits )
//void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize )
{
bits->cur = bits->end - bits->byteSize;
bits->bitIndex = 0;
}
#if PRAGMA_MARK
#pragma mark -
#endif
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*=============================================================================
File: ALACBitUtilities.h
$NoKeywords: $
=============================================================================*/
#ifndef __ALACBITUTILITIES_H
#define __ALACBITUTILITIES_H
#include <stdint.h>
#ifndef MIN
#define MIN(x, y) ( (x)<(y) ?(x) :(y) )
#endif //MIN
#ifndef MAX
#define MAX(x, y) ( (x)>(y) ?(x): (y) )
#endif //MAX
#define RequireAction(condition, action) if (!(condition)) { action }
#define RequireActionSilent(condition, action) if (!(condition)) { action }
#define RequireNoErr(condition, action) if ((condition)) { action }
enum
{
ALAC_noErr = 0
};
typedef enum
{
ID_SCE = 0, /* Single Channel Element */
ID_CPE = 1, /* Channel Pair Element */
ID_CCE = 2, /* Coupling Channel Element */
ID_LFE = 3, /* LFE Channel Element */
ID_DSE = 4, /* not yet supported */
ID_PCE = 5,
ID_FIL = 6,
ID_END = 7
} ELEMENT_TYPE;
// types
typedef struct BitBuffer
{
uint8_t * cur;
uint8_t * end;
uint32_t bitIndex;
uint32_t byteSize;
} BitBuffer;
/*
BitBuffer routines
- these routines take a fixed size buffer and read/write to it
- bounds checking must be done by the client
*/
void BitBufferInit( BitBuffer * bits, uint8_t * buffer, uint32_t byteSize );
uint32_t BitBufferRead( BitBuffer * bits, uint8_t numBits ); // note: cannot read more than 16 bits at a time
uint8_t BitBufferReadSmall( BitBuffer * bits, uint8_t numBits );
uint8_t BitBufferReadOne( BitBuffer * bits );
uint32_t BitBufferPeek( BitBuffer * bits, uint8_t numBits ); // note: cannot read more than 16 bits at a time
uint32_t BitBufferPeekOne( BitBuffer * bits );
uint32_t BitBufferUnpackBERSize( BitBuffer * bits );
uint32_t BitBufferGetPosition( BitBuffer * bits );
void BitBufferByteAlign( BitBuffer * bits, int32_t addZeros );
void BitBufferAdvance( BitBuffer * bits, uint32_t numBits );
void BitBufferRewind( BitBuffer * bits, uint32_t numBits );
void BitBufferWrite( BitBuffer * bits, uint32_t value, uint32_t numBits );
void BitBufferReset( BitBuffer * bits);
#endif /* __BITUTILITIES_H */
+61
View File
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: ALACDecoder.h
*/
#ifndef _ALACDECODER_H
#define _ALACDECODER_H
#include <stdint.h>
#include "ALACAudioTypes.h"
struct BitBuffer;
class ALACDecoder
{
public:
ALACDecoder();
~ALACDecoder();
int32_t Init( void * inMagicCookie, uint32_t inMagicCookieSize );
int32_t Decode( struct BitBuffer * bits, uint8_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples );
public:
// decoding parameters (public for use in the analyzer)
ALACSpecificConfig mConfig;
protected:
int32_t FillElement( struct BitBuffer * bits );
int32_t DataStreamElement( struct BitBuffer * bits );
uint16_t mActiveElements;
// decoding buffers
int32_t * mMixBufferU;
int32_t * mMixBufferV;
int32_t * mPredictor;
uint16_t * mShiftBuffer; // note: this points to mPredictor's memory but different
// variable for clarity and type difference
};
#endif /* _ALACDECODER_H */
+92
View File
@@ -0,0 +1,92 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: ALACEncoder.h
*/
#pragma once
#include <stdint.h>
#include "ALACAudioTypes.h"
struct BitBuffer;
class ALACEncoder
{
public:
ALACEncoder();
virtual ~ALACEncoder();
virtual int32_t Encode(AudioFormatDescription theInputFormat, AudioFormatDescription theOutputFormat,
unsigned char * theReadBuffer, unsigned char * theWriteBuffer, int32_t * ioNumBytes);
virtual int32_t Finish( );
void SetFastMode( bool fast ) { mFastMode = fast; };
// this must be called *before* InitializeEncoder()
void SetFrameSize( uint32_t frameSize ) { mFrameSize = frameSize; };
void GetConfig( ALACSpecificConfig & config );
uint32_t GetMagicCookieSize(uint32_t inNumChannels);
void GetMagicCookie( void * config, uint32_t * ioSize );
virtual int32_t InitializeEncoder(AudioFormatDescription theOutputFormat);
protected:
virtual void GetSourceFormat( const AudioFormatDescription * source, AudioFormatDescription * output );
int32_t EncodeStereo( struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
int32_t EncodeStereoFast( struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
int32_t EncodeStereoEscape( struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t numSamples );
int32_t EncodeMono( struct BitBuffer * bitstream, void * input, uint32_t stride, uint32_t channelIndex, uint32_t numSamples );
// ALAC encoder parameters
int16_t mBitDepth;
bool mFastMode;
// encoding state
int16_t mLastMixRes[kALACMaxChannels];
// encoding buffers
int32_t * mMixBufferU;
int32_t * mMixBufferV;
int32_t * mPredictorU;
int32_t * mPredictorV;
uint16_t * mShiftBufferUV;
uint8_t * mWorkBuffer;
// per-channel coefficients buffers
int16_t mCoefsU[kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
int16_t mCoefsV[kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
// encoding statistics
uint32_t mTotalBytesGenerated;
uint32_t mAvgBitRate;
uint32_t mMaxFrameBytes;
uint32_t mFrameSize;
uint32_t mMaxOutputBytes;
uint32_t mNumChannels;
uint32_t mOutputSampleRate;
};
+39
View File
@@ -0,0 +1,39 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
** Copyright (C) 2013 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
//
// EndianPortable.h
//
// Copyright 2011 Apple Inc. All rights reserved.
//
#ifndef _EndianPortable_h
#define _EndianPortable_h
#include <sfendian.h>
#define Swap16NtoB(x) H2BE_16(x)
#define Swap16BtoN(x) BE2H_16(x)
#define Swap32NtoB(x) H2BE_32(x)
#define Swap32BtoN(x) BE2H_32(x)
#endif
+170
View File
@@ -0,0 +1,170 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the
copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other
entities that control, are controlled by, or are under common control
with that entity. For the purposes of this definition, "control" means
(i) the power, direct or indirect, to cause the direction or management
of such entity, whether by contract or otherwise, or (ii) ownership
of fifty percent (50%) or more of the outstanding shares, or (iii)
beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation source,
and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but not
limited to compiled object code, generated documentation, and
conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object
form, made available under the License, as indicated by a copyright
notice that is included in or attached to the work (an example is
provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original
version of the Work and any modifications or additions to that Work or
Derivative Works thereof, that is intentionally submitted to Licensor
for inclusion in the Work by the copyright owner or by an individual
or Legal Entity authorized to submit on behalf of the copyright owner.
For the purposes of this definition, "submitted" means any form of
electronic, verbal, or written communication sent to the Licensor
or its representatives, including but not limited to communication
on electronic mailing lists, source code control systems, and issue
tracking systems that are managed by, or on behalf of, the Licensor
for the purpose of discussing and improving the Work, but excluding
communication that is conspicuously marked or otherwise designated in
writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions
of this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of, publicly
display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except
as stated in this section) patent license to make, have made, use,
offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such
Contributor that are necessarily infringed by their Contribution(s)
alone or by combination of their Contribution(s) with the Work to which
such Contribution(s) was submitted. If You institute patent litigation
against any entity (including a cross-claim or counterclaim in a
lawsuit) alleging that the Work or a Contribution incorporated within
the Work constitutes direct or contributory patent infringement, then
any patent licenses granted to You under this License for that Work
shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You meet the
following conditions:
You must give any other recipients of the Work or Derivative Works a
copy of this License; and
You must cause any modified files to carry prominent notices stating
that You changed the files; and
You must retain, in the Source form of any Derivative Works that You
distribute, all copyright, patent, trademark, and attribution notices
from the Source form of the Work, excluding those notices that do not
pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution,
then any Derivative Works that You distribute must include a readable
copy of the attribution notices contained within such NOTICE file,
excluding those notices that do not pertain to any part of the
Derivative Works, in at least one of the following places: within a
NOTICE text file distributed as part of the Derivative Works; within
the Source form or documentation, if provided along with the Derivative
Works; or, within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents of the
NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative
Works that You distribute, alongside or as an addendum to the NOTICE
text from the Work, provided that such additional attribution notices
cannot be construed as modifying the License. You may add Your own
copyright statement to Your modifications and may provide additional
or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as
a whole, provided Your use, reproduction, and distribution of the Work
otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work by
You to the Licensor shall be under the terms and conditions of this
License, without any additional terms or conditions. Notwithstanding
the above, nothing herein shall supersede or modify the terms of any
separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed
to in writing, Licensor provides the Work (and each Contributor
provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied, including, without
limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your
exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise, unless
required by applicable law (such as deliberate and grossly negligent
acts) or agreed to in writing, shall any Contributor be liable to You
for damages, including any direct, indirect, special, incidental, or
consequential damages of any character arising as a result of this
License or out of the use or inability to use the Work (including but
not limited to damages for loss of goodwill, work stoppage, computer
failure or malfunction, or any and all other commercial damages or
losses), even if such Contributor has been advised of the possibility of
such damages.
9. Accepting Warranty or Additional Liability. While redistributing the
Work or Derivative Works thereof, You may choose to offer, and charge a
fee for, acceptance of support, warranty, indemnity, or other liability
obligations and/or rights consistent with this License. However, in
accepting such obligations, You may act only on Your own behalf and
on Your sole responsibility, not on behalf of any other Contributor,
and only if You agree to indemnify, defend, and hold each Contributor
harmless for any liability incurred by, or claims asserted against, such
Contributor by reason of your accepting any such warranty or additional
liability.
+355
View File
@@ -0,0 +1,355 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: ag_dec.c
Contains: Adaptive Golomb decode routines.
Copyright: (c) 2001-2011 Apple, Inc.
*/
#include "aglib.h"
#include "ALACBitUtilities.h"
#include "ALACAudioTypes.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CODE_TO_LONG_MAXBITS 32
#define N_MAX_MEAN_CLAMP 0xffff
#define N_MEAN_CLAMP_VAL 0xffff
#define REPORT_VAL 40
#if __GNUC__
#define ALWAYS_INLINE __attribute__((always_inline))
#else
#define ALWAYS_INLINE
#endif
/* And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this
to help the compiler out. In many cases this required manual inlining or a macro. Sorry
if it is ugly but the performance gains are well worth it.
- WSK 5/19/04
*/
void set_standard_ag_params(AGParamRecPtr params, uint32_t fullwidth, uint32_t sectorwidth)
{
/* Use
fullwidth = sectorwidth = numOfSamples, for analog 1-dimensional type-short data,
but use
fullwidth = full image width, sectorwidth = sector (patch) width
for such as image (2-dim.) data.
*/
set_ag_params( params, MB0, PB0, KB0, fullwidth, sectorwidth, MAX_RUN_DEFAULT );
}
void set_ag_params(AGParamRecPtr params, uint32_t m, uint32_t p, uint32_t k, uint32_t f, uint32_t s, uint32_t maxrun)
{
params->mb = params->mb0 = m;
params->pb = p;
params->kb = k;
params->wb = (1u<<params->kb)-1;
params->qb = QB-params->pb;
params->fw = f;
params->sw = s;
params->maxrun = maxrun;
}
#if PRAGMA_MARK
#pragma mark -
#endif
// note: implementing this with some kind of "count leading zeros" assembly is a big performance win
static inline int32_t lead( int32_t m )
{
long j;
unsigned long c = (1ul << 31);
for(j=0; j < 32; j++)
{
if((c & m) != 0)
break;
c >>= 1;
}
return (j);
}
#define arithmin(a, b) ((a) < (b) ? (a) : (b))
static inline int32_t ALWAYS_INLINE lg3a( int32_t x)
{
int32_t result;
x += 3;
result = lead(x);
return 31 - result;
}
static inline uint32_t ALWAYS_INLINE read32bit( uint8_t * buffer )
{
// embedded CPUs typically can't read unaligned 32-bit words so just read the bytes
uint32_t value;
value = ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) |
((uint32_t)buffer[2] << 8) | (uint32_t)buffer[3];
return value;
}
#if PRAGMA_MARK
#pragma mark -
#endif
#define get_next_fromlong(inlong, suff) ((inlong) >> (32 - (suff)))
static inline uint32_t ALWAYS_INLINE
getstreambits( uint8_t *in, int32_t bitoffset, int32_t numbits )
{
uint32_t load1, load2;
uint32_t byteoffset = bitoffset / 8;
uint32_t result;
//Assert( numbits <= 32 );
load1 = read32bit( in + byteoffset );
if ( (numbits + (bitoffset & 0x7)) > 32)
{
int32_t load2shift;
result = load1 << (bitoffset & 0x7);
load2 = (uint32_t) in[byteoffset+4];
load2shift = (8-(numbits + (bitoffset & 0x7)-32));
load2 >>= load2shift;
result >>= (32-numbits);
result |= load2;
}
else
{
result = load1 >> (32-numbits-(bitoffset & 7));
}
// a shift of >= "the number of bits in the type of the value being shifted" results in undefined
// behavior so don't try to shift by 32
if ( numbits != (sizeof(result) * 8) )
result &= ~(0xfffffffful << numbits);
return result;
}
static inline int32_t dyn_get(unsigned char *in, uint32_t *bitPos, uint32_t m, uint32_t k)
{
uint32_t tempbits = *bitPos;
uint32_t result;
uint32_t pre = 0, v;
uint32_t streamlong;
streamlong = read32bit( in + (tempbits >> 3) );
streamlong <<= (tempbits & 7);
/* find the number of bits in the prefix */
{
uint32_t notI = ~streamlong;
pre = lead( notI);
}
if(pre >= MAX_PREFIX_16)
{
pre = MAX_PREFIX_16;
tempbits += pre;
streamlong <<= pre;
result = get_next_fromlong(streamlong,MAX_DATATYPE_BITS_16);
tempbits += MAX_DATATYPE_BITS_16;
}
else
{
// all of the bits must fit within the long we have loaded
//Assert(pre+1+k <= 32);
tempbits += pre;
tempbits += 1;
streamlong <<= pre+1;
v = get_next_fromlong(streamlong, k);
tempbits += k;
result = pre*m + v-1;
if(v<2) {
result -= (v-1);
tempbits -= 1;
}
}
*bitPos = tempbits;
return result;
}
static inline int32_t dyn_get_32bit( uint8_t * in, uint32_t * bitPos, int32_t m, int32_t k, int32_t maxbits )
{
uint32_t tempbits = *bitPos;
uint32_t v;
uint32_t streamlong;
uint32_t result;
streamlong = read32bit( in + (tempbits >> 3) );
streamlong <<= (tempbits & 7);
/* find the number of bits in the prefix */
{
uint32_t notI = ~streamlong;
result = lead( notI);
}
if(result >= MAX_PREFIX_32)
{
result = getstreambits(in, tempbits+MAX_PREFIX_32, maxbits);
tempbits += MAX_PREFIX_32 + maxbits;
}
else
{
/* all of the bits must fit within the long we have loaded*/
//Assert(k<=14);
//Assert(result<MAX_PREFIX_32);
//Assert(result+1+k <= 32);
tempbits += result;
tempbits += 1;
if (k != 1)
{
streamlong <<= result+1;
v = get_next_fromlong(streamlong, k);
tempbits += k;
tempbits -= 1;
result = result*m;
if(v>=2)
{
result += (v-1);
tempbits += 1;
}
}
}
*bitPos = tempbits;
return result;
}
int32_t dyn_decomp( AGParamRecPtr params, BitBuffer * bitstream, int32_t * pc, int32_t numSamples, int32_t maxSize, uint32_t * outNumBits )
{
uint8_t *in;
int32_t *outPtr = pc;
uint32_t bitPos, startPos, maxPos;
uint32_t j, m, k, n, c, mz;
int32_t del, zmode;
uint32_t mb;
uint32_t pb_local = params->pb;
uint32_t kb_local = params->kb;
uint32_t wb_local = params->wb;
int32_t status;
RequireAction( (bitstream != NULL) && (pc != NULL) && (outNumBits != NULL), return kALAC_ParamError; );
*outNumBits = 0;
in = bitstream->cur;
startPos = bitstream->bitIndex;
maxPos = bitstream->byteSize * 8;
bitPos = startPos;
mb = params->mb0;
zmode = 0;
c = 0;
status = ALAC_noErr;
while (c < (uint32_t) numSamples)
{
// bail if we've run off the end of the buffer
RequireAction( bitPos < maxPos, status = kALAC_ParamError; goto Exit; );
m = (mb)>>QBSHIFT;
k = lg3a(m);
k = arithmin(k, kb_local);
m = (1<<k)-1;
n = dyn_get_32bit( in, &bitPos, m, k, maxSize );
// least significant bit is sign bit
{
uint32_t ndecode = n + zmode;
int32_t multiplier = (- (ndecode&1));
multiplier |= 1;
del = ((ndecode+1) >> 1) * (multiplier);
}
*outPtr++ = del;
c++;
mb = pb_local*(n+zmode) + mb - ((pb_local*mb)>>QBSHIFT);
// update mean tracking
if (n > N_MAX_MEAN_CLAMP)
mb = N_MEAN_CLAMP_VAL;
zmode = 0;
if (((mb << MMULSHIFT) < QB) && (c < (uint32_t) numSamples))
{
zmode = 1;
k = lead(mb) - BITOFF+((mb+MOFF)>>MDENSHIFT);
mz = ((1<<k)-1) & wb_local;
n = dyn_get(in, &bitPos, mz, k);
RequireAction(c+n <= (uint32_t) numSamples, status = kALAC_ParamError; goto Exit; );
for(j=0; j < n; j++)
{
*outPtr++ = 0;
++c;
}
if(n >= 65535)
zmode = 0;
mb = 0;
}
}
Exit:
*outNumBits = (bitPos - startPos);
BitBufferAdvance( bitstream, *outNumBits );
RequireAction( bitstream->cur <= bitstream->end, status = kALAC_ParamError; );
return status;
}
+360
View File
@@ -0,0 +1,360 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2013 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: ag_enc.c
Contains: Adaptive Golomb encode routines.
Copyright: (c) 2001-2011 Apple, Inc.
*/
#include "aglib.h"
#include "ALACBitUtilities.h"
#include "EndianPortable.h"
#include "ALACAudioTypes.h"
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CODE_TO_LONG_MAXBITS 32
#define N_MAX_MEAN_CLAMP 0xffff
#define N_MEAN_CLAMP_VAL 0xffff
#define REPORT_VAL 40
#if __GNUC__
#define ALWAYS_INLINE __attribute__((always_inline))
#else
#define ALWAYS_INLINE
#endif
/* And on the subject of the CodeWarrior x86 compiler and inlining, I reworked a lot of this
to help the compiler out. In many cases this required manual inlining or a macro. Sorry
if it is ugly but the performance gains are well worth it.
- WSK 5/19/04
*/
// note: implementing this with some kind of "count leading zeros" assembly is a big performance win
static inline int32_t lead( int32_t m )
{
long j;
unsigned long c = (1ul << 31);
for(j=0; j < 32; j++)
{
if((c & m) != 0)
break;
c >>= 1;
}
return (j);
}
#define arithmin(a, b) ((a) < (b) ? (a) : (b))
static inline int32_t ALWAYS_INLINE lg3a( int32_t x)
{
int32_t result;
x += 3;
result = lead(x);
return 31 - result;
}
static inline int32_t ALWAYS_INLINE abs_func( int32_t a )
{
// note: the CW PPC intrinsic __abs() turns into these instructions so no need to try and use it
int32_t isneg = a >> 31;
int32_t xorval = a ^ isneg;
int32_t result = xorval-isneg;
return result;
}
static inline uint32_t ALWAYS_INLINE read32bit( uint8_t * buffer )
{
// embedded CPUs typically can't read unaligned 32-bit words so just read the bytes
uint32_t value;
value = ((uint32_t)buffer[0] << 24) | ((uint32_t)buffer[1] << 16) |
((uint32_t)buffer[2] << 8) | (uint32_t)buffer[3];
return value;
}
#if PRAGMA_MARK
#pragma mark -
#endif
static inline int32_t dyn_code(int32_t m, int32_t k, int32_t n, uint32_t *outNumBits)
{
uint32_t divx, mod, de;
uint32_t numBits;
uint32_t value;
//Assert( n >= 0 );
divx = n/m;
if(divx >= MAX_PREFIX_16)
{
numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16;
value = (((1<<MAX_PREFIX_16)-1)<<MAX_DATATYPE_BITS_16) + n;
}
else
{
mod = n%m;
de = (mod == 0);
numBits = divx + k + 1 - de;
value = (((1<<divx)-1)<<(numBits-divx)) + mod + 1 - de;
// if coding this way is bigger than doing escape, then do escape
if (numBits > MAX_PREFIX_16 + MAX_DATATYPE_BITS_16)
{
numBits = MAX_PREFIX_16 + MAX_DATATYPE_BITS_16;
value = (((1<<MAX_PREFIX_16)-1)<<MAX_DATATYPE_BITS_16) + n;
}
}
*outNumBits = numBits;
return (int32_t) value;
}
static inline int32_t dyn_code_32bit(int32_t maxbits, uint32_t m, uint32_t k, uint32_t n, uint32_t *outNumBits, uint32_t *outValue, uint32_t *overflow, uint32_t *overflowbits)
{
uint32_t divx, mod, de;
uint32_t numBits;
uint32_t value;
int32_t didOverflow = 0;
divx = n/m;
if (divx < MAX_PREFIX_32)
{
mod = n - (m * divx);
de = (mod == 0);
numBits = divx + k + 1 - de;
value = (((1<<divx)-1)<<(numBits-divx)) + mod + 1 - de;
if (numBits > 25)
goto codeasescape;
}
else
{
codeasescape:
numBits = MAX_PREFIX_32;
value = (((1<<MAX_PREFIX_32)-1));
*overflow = n;
*overflowbits = maxbits;
didOverflow = 1;
}
*outNumBits = numBits;
*outValue = value;
return didOverflow;
}
static inline void ALWAYS_INLINE dyn_jam_noDeref(unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value)
{
uint32_t mask;
uint32_t curr;
uint32_t shift;
//Assert( numBits <= 32 );
curr = psf_get_be32 (out, bitPos >> 3);
shift = 32 - (bitPos & 7) - numBits;
mask = ~0u >> (32 - numBits); // mask must be created in two steps to avoid compiler sequencing ambiguity
mask <<= shift;
value = (value << shift) & mask;
value |= curr & ~mask;
psf_put_be32 (out, bitPos >> 3, value) ;
}
static inline void ALWAYS_INLINE dyn_jam_noDeref_large(unsigned char *out, uint32_t bitPos, uint32_t numBits, uint32_t value)
{
uint32_t w;
uint32_t curr;
uint32_t mask;
int32_t shiftvalue = (32 - (bitPos&7) - numBits);
//Assert(numBits <= 32);
curr = psf_get_be32 (out, bitPos >> 3);
if (shiftvalue < 0)
{
uint8_t tailbyte;
uint8_t *tailptr;
w = value >> -shiftvalue;
mask = ~0u >> -shiftvalue;
w |= (curr & ~mask);
tailptr = out + (bitPos>>3) + 4;
tailbyte = (value << ((8+shiftvalue))) & 0xff;
*tailptr = (uint8_t)tailbyte;
}
else
{
mask = ~0u >> (32 - numBits);
mask <<= shiftvalue; // mask must be created in two steps to avoid compiler sequencing ambiguity
w = (value << shiftvalue) & mask;
w |= curr & ~mask;
}
psf_put_be32 (out, bitPos >> 3, w) ;
}
int32_t dyn_comp( AGParamRecPtr params, int32_t * pc, BitBuffer * bitstream, int32_t numSamples, int32_t bitSize, uint32_t * outNumBits )
{
unsigned char * out;
uint32_t bitPos, startPos;
uint32_t m, k, n, c, mz, nz;
uint32_t numBits;
uint32_t value;
int32_t del, zmode;
uint32_t overflow, overflowbits;
int32_t status;
// shadow the variables in params so there's not the dereferencing overhead
uint32_t mb, pb, kb, wb;
int32_t rowPos = 0;
int32_t rowSize = params->sw;
int32_t rowJump = (params->fw) - rowSize;
int32_t * inPtr = pc;
*outNumBits = 0;
RequireAction( (bitSize >= 1) && (bitSize <= 32), return kALAC_ParamError; );
out = bitstream->cur;
startPos = bitstream->bitIndex;
bitPos = startPos;
mb = params->mb = params->mb0;
pb = params->pb;
kb = params->kb;
wb = params->wb;
zmode = 0;
c=0;
status = ALAC_noErr;
while (c < (uint32_t) numSamples)
{
m = mb >> QBSHIFT;
k = lg3a(m);
if ( k > kb)
{
k = kb;
}
m = (1<<k)-1;
del = *inPtr++;
rowPos++;
n = (abs_func(del) << 1) - ((del >> 31) & 1) - zmode;
//Assert( 32-lead(n) <= bitSize );
if ( dyn_code_32bit(bitSize, m, k, n, &numBits, &value, &overflow, &overflowbits) )
{
dyn_jam_noDeref(out, bitPos, numBits, value);
bitPos += numBits;
dyn_jam_noDeref_large(out, bitPos, overflowbits, overflow);
bitPos += overflowbits;
}
else
{
dyn_jam_noDeref(out, bitPos, numBits, value);
bitPos += numBits;
}
c++;
if ( rowPos >= rowSize)
{
rowPos = 0;
inPtr += rowJump;
}
mb = pb * (n + zmode) + mb - ((pb *mb)>>QBSHIFT);
// update mean tracking if it's overflowed
if (n > N_MAX_MEAN_CLAMP)
mb = N_MEAN_CLAMP_VAL;
zmode = 0;
RequireAction(c <= (uint32_t) numSamples, status = kALAC_ParamError; goto Exit; );
if (((mb << MMULSHIFT) < QB) && (c < (uint32_t) numSamples))
{
zmode = 1;
nz = 0;
while(c<(uint32_t) numSamples && *inPtr == 0)
{
/* Take care of wrap-around globals. */
++inPtr;
++nz;
++c;
if ( ++rowPos >= rowSize)
{
rowPos = 0;
inPtr += rowJump;
}
if(nz >= 65535)
{
zmode = 0;
break;
}
}
k = lead(mb) - BITOFF+((mb+MOFF)>>MDENSHIFT);
mz = ((1<<k)-1) & wb;
value = dyn_code(mz, k, nz, &numBits);
dyn_jam_noDeref(out, bitPos, numBits, value);
bitPos += numBits;
mb = 0;
}
}
*outNumBits = (bitPos - startPos);
BitBufferAdvance( bitstream, *outNumBits );
Exit:
return status;
}
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: aglib.h
Copyright: (C) 2001-2011 Apple, Inc.
*/
#ifndef AGLIB_H
#define AGLIB_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#define QBSHIFT 9
#define QB (1<<QBSHIFT)
#define PB0 40
#define MB0 10
#define KB0 14
#define MAX_RUN_DEFAULT 255
#define MMULSHIFT 2
#define MDENSHIFT (QBSHIFT - MMULSHIFT - 1)
#define MOFF ((1<<(MDENSHIFT-2)))
#define BITOFF 24
/* Max. prefix of 1's. */
#define MAX_PREFIX_16 9
#define MAX_PREFIX_TOLONG_16 15
#define MAX_PREFIX_32 9
/* Max. bits in 16-bit data type */
#define MAX_DATATYPE_BITS_16 16
typedef struct AGParamRec
{
uint32_t mb, mb0, pb, kb, wb, qb;
uint32_t fw, sw;
uint32_t maxrun;
// fw = 1, sw = 1;
} AGParamRec, *AGParamRecPtr;
struct BitBuffer;
void set_standard_ag_params(AGParamRecPtr params, uint32_t fullwidth, uint32_t sectorwidth);
void set_ag_params(AGParamRecPtr params, uint32_t m, uint32_t p, uint32_t k, uint32_t f, uint32_t s, uint32_t maxrun);
int32_t dyn_comp(AGParamRecPtr params, int32_t * pc, struct BitBuffer * bitstream, int32_t numSamples, int32_t bitSize, uint32_t * outNumBits);
int32_t dyn_decomp(AGParamRecPtr params, struct BitBuffer * bitstream, int32_t * pc, int32_t numSamples, int32_t maxSize, uint32_t * outNumBits);
#ifdef __cplusplus
}
#endif
#endif //#ifndef AGLIB_H
+103
View File
@@ -0,0 +1,103 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: alac_codec.h
*/
#ifndef ALAC_CODEC_H
#define ALAC_CODEC_H
#include <stdint.h>
#include "ALACAudioTypes.h"
#define ALAC_FRAME_LENGTH 4096
struct BitBuffer;
typedef struct alac_decoder_s
{
// decoding parameters (public for use in the analyzer)
ALACSpecificConfig mConfig;
uint16_t mActiveElements;
// decoding buffers
int32_t mMixBufferU [ALAC_FRAME_LENGTH];
int32_t mMixBufferV [ALAC_FRAME_LENGTH];
union
{
int32_t mPredictor [ALAC_FRAME_LENGTH];
uint16_t mShiftBuffer [ALAC_FRAME_LENGTH];
} ;
} ALAC_DECODER ;
typedef struct alac_encoder_s
{
// ALAC encoder parameters
int16_t mBitDepth;
// encoding state
int16_t mLastMixRes [kALACMaxChannels];
int32_t mFastMode;
// encoding buffers
int32_t mMixBufferU [ALAC_FRAME_LENGTH] ;
int32_t mMixBufferV [ALAC_FRAME_LENGTH] ;
int32_t mPredictorU [ALAC_FRAME_LENGTH] ;
int32_t mPredictorV [ALAC_FRAME_LENGTH] ;
uint16_t mShiftBufferUV [2 * ALAC_FRAME_LENGTH] ;
uint8_t mWorkBuffer [4 * ALAC_FRAME_LENGTH];
// per-channel coefficients buffers
int16_t mCoefsU [kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
int16_t mCoefsV [kALACMaxChannels][kALACMaxSearches][kALACMaxCoefs];
// encoding statistics
uint32_t mTotalBytesGenerated;
uint32_t mAvgBitRate;
uint32_t mMaxFrameBytes;
uint32_t mFrameSize;
uint32_t mMaxOutputBytes;
uint32_t mNumChannels;
uint32_t mOutputSampleRate;
} ALAC_ENCODER ;
int32_t alac_decoder_init (ALAC_DECODER *p, void * inMagicCookie, uint32_t inMagicCookieSize) ;
int32_t alac_encoder_init (ALAC_ENCODER *p, uint32_t samplerate, uint32_t channels, uint32_t format_flags, uint32_t frameSize) ;
int32_t alac_decode (ALAC_DECODER *, struct BitBuffer * bits, int32_t * sampleBuffer,
uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples) ;
int32_t alac_encode (ALAC_ENCODER *p, uint32_t numChannels, uint32_t numSamples,
int32_t * theReadBuffer, unsigned char * theWriteBuffer,
uint32_t * ioNumBytes) ;
void alac_set_fastmode(ALAC_ENCODER * p, int32_t fast) ;
uint32_t alac_get_magic_cookie_size(uint32_t inNumChannels) ;
void alac_get_magic_cookie(ALAC_ENCODER *p, void * config, uint32_t * ioSize) ;
void alac_get_source_format(ALAC_ENCODER *p, const AudioFormatDescription * source, AudioFormatDescription * output) ;
#endif
+646
View File
@@ -0,0 +1,646 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: ALACDecoder.cpp
*/
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include "alac_codec.h"
#include "dplib.h"
#include "aglib.h"
#include "matrixlib.h"
#include "ALACBitUtilities.h"
#include "EndianPortable.h"
typedef enum
{ false = 0,
true = 1
} bool ;
// constants/data
const uint32_t kMaxBitDepth = 32; // max allowed bit depth is 32
// prototypes
static int32_t alac_fill_element (struct BitBuffer * bits) ;
static int32_t alac_data_stream_element (struct BitBuffer * bits) ;
static void Zero32( int32_t * buffer, uint32_t numItems, uint32_t stride );
/*
Init()
- initialize the decoder with the given configuration
*/
int32_t
alac_decoder_init (ALAC_DECODER *p, void * inMagicCookie, uint32_t inMagicCookieSize)
{
int32_t status = ALAC_noErr;
ALACSpecificConfig theConfig;
uint8_t * theActualCookie = (uint8_t *)inMagicCookie;
uint32_t theCookieBytesRemaining = inMagicCookieSize;
// For historical reasons the decoder needs to be resilient to magic cookies vended by older encoders.
// As specified in the ALACMagicCookieDescription.txt document, there may be additional data encapsulating
// the ALACSpecificConfig. This would consist of format ('frma') and 'alac' atoms which precede the
// ALACSpecificConfig.
// See ALACMagicCookieDescription.txt for additional documentation concerning the 'magic cookie'
// skip format ('frma') atom if present
if (theActualCookie[4] == 'f' && theActualCookie[5] == 'r' && theActualCookie[6] == 'm' && theActualCookie[7] == 'a')
{
theActualCookie += 12;
theCookieBytesRemaining -= 12;
}
// skip 'alac' atom header if present
if (theActualCookie[4] == 'a' && theActualCookie[5] == 'l' && theActualCookie[6] == 'a' && theActualCookie[7] == 'c')
{
theActualCookie += 12;
theCookieBytesRemaining -= 12;
}
// read the ALACSpecificConfig
if (theCookieBytesRemaining >= sizeof(ALACSpecificConfig))
{
theConfig.frameLength = psf_get_be32 (theActualCookie, offsetof (ALACSpecificConfig, frameLength)) ;
if (theConfig.frameLength > ALAC_FRAME_LENGTH)
return fALAC_FrameLengthError ;
theConfig.compatibleVersion = theActualCookie [offsetof (ALACSpecificConfig, compatibleVersion)] ;
theConfig.bitDepth = theActualCookie [offsetof (ALACSpecificConfig, bitDepth)] ;
theConfig.pb = theActualCookie [offsetof (ALACSpecificConfig, pb)] ;
theConfig.mb = theActualCookie [offsetof (ALACSpecificConfig, mb)] ;
theConfig.kb = theActualCookie [offsetof (ALACSpecificConfig, kb)] ;
theConfig.numChannels = theActualCookie [offsetof (ALACSpecificConfig, numChannels)] ;
theConfig.maxRun = psf_get_be16 (theActualCookie, offsetof (ALACSpecificConfig, maxRun)) ;
theConfig.maxFrameBytes = psf_get_be32 (theActualCookie, offsetof (ALACSpecificConfig, maxFrameBytes)) ;
theConfig.avgBitRate = psf_get_be32 (theActualCookie, offsetof (ALACSpecificConfig, avgBitRate)) ;
theConfig.sampleRate = psf_get_be32 (theActualCookie, offsetof (ALACSpecificConfig, sampleRate)) ;
p->mConfig = theConfig;
RequireAction( p->mConfig.compatibleVersion <= kALACVersion, return kALAC_ParamError; );
RequireAction( (p->mMixBufferU != NULL) && (p->mMixBufferV != NULL) && (p->mPredictor != NULL),
status = kALAC_MemFullError; goto Exit; );
}
else
{
status = kALAC_ParamError;
}
// skip to Channel Layout Info
// theActualCookie += sizeof(ALACSpecificConfig);
// Currently, the Channel Layout Info portion of the magic cookie (as defined in the
// ALACMagicCookieDescription.txt document) is unused by the decoder.
Exit:
return status;
}
/*
Decode()
- the decoded samples are interleaved into the output buffer in the order they arrive in
the bitstream
*/
int32_t
alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples)
{
BitBuffer shiftBits;
uint32_t bits1, bits2;
uint8_t tag;
uint8_t elementInstanceTag;
AGParamRec agParams;
uint32_t channelIndex;
int16_t coefsU[32]; // max possible size is 32 although NUMCOEPAIRS is the current limit
int16_t coefsV[32];
uint8_t numU, numV;
uint8_t mixBits;
int8_t mixRes;
uint16_t unusedHeader;
uint8_t escapeFlag;
uint32_t chanBits;
uint8_t bytesShifted;
uint32_t shift;
uint8_t modeU, modeV;
uint32_t denShiftU, denShiftV;
uint16_t pbFactorU, pbFactorV;
uint16_t pb;
int32_t * out32;
uint8_t headerByte;
uint8_t partialFrame;
uint32_t extraBits;
int32_t val;
uint32_t i, j;
int32_t status;
RequireAction( (bits != NULL) && (sampleBuffer != NULL) && (outNumSamples != NULL), return kALAC_ParamError; );
RequireAction( numChannels > 0, return kALAC_ParamError; );
p->mActiveElements = 0;
channelIndex = 0;
status = ALAC_noErr;
*outNumSamples = numSamples;
while ( status == ALAC_noErr )
{
// bail if we ran off the end of the buffer
RequireAction( bits->cur < bits->end, status = kALAC_ParamError; goto Exit; );
// copy global decode params for this element
pb = p->mConfig.pb;
// read element tag
tag = BitBufferReadSmall( bits, 3 );
switch ( tag )
{
case ID_SCE:
case ID_LFE:
{
// mono/LFE channel
elementInstanceTag = BitBufferReadSmall( bits, 4 );
p->mActiveElements |= (1u << elementInstanceTag);
// read the 12 unused header bits
unusedHeader = (uint16_t) BitBufferRead( bits, 12 );
RequireAction( unusedHeader == 0, status = kALAC_ParamError; goto Exit; );
// read the 1-bit "partial frame" flag, 2-bit "shift-off" flag & 1-bit "escape" flag
headerByte = (uint8_t) BitBufferRead( bits, 4 );
partialFrame = headerByte >> 3;
bytesShifted = (headerByte >> 1) & 0x3u;
RequireAction( bytesShifted != 3, status = kALAC_ParamError; goto Exit; );
shift = bytesShifted * 8;
escapeFlag = headerByte & 0x1;
chanBits = p->mConfig.bitDepth - (bytesShifted * 8);
// check for partial frame to override requested numSamples
if ( partialFrame != 0 )
{
numSamples = BitBufferRead( bits, 16 ) << 16;
numSamples |= BitBufferRead( bits, 16 );
}
if ( escapeFlag == 0 )
{
// compressed frame, read rest of parameters
mixBits = (uint8_t) BitBufferRead( bits, 8 );
mixRes = (int8_t) BitBufferRead( bits, 8 );
//Assert( (mixBits == 0) && (mixRes == 0) ); // no mixing for mono
headerByte = (uint8_t) BitBufferRead( bits, 8 );
modeU = headerByte >> 4;
denShiftU = headerByte & 0xfu;
headerByte = (uint8_t) BitBufferRead( bits, 8 );
pbFactorU = headerByte >> 5;
numU = headerByte & 0x1fu;
for ( i = 0; i < numU; i++ )
coefsU[i] = (int16_t) BitBufferRead( bits, 16 );
// if shift active, skip the the shift buffer but remember where it starts
if ( bytesShifted != 0 )
{
shiftBits = *bits;
BitBufferAdvance( bits, (bytesShifted * 8) * numSamples );
}
// decompress
set_ag_params( &agParams, p->mConfig.mb, (pb * pbFactorU) / 4, p->mConfig.kb, numSamples, numSamples, p->mConfig.maxRun );
status = dyn_decomp( &agParams, bits, p->mPredictor, numSamples, chanBits, &bits1 );
RequireNoErr( status, goto Exit; );
if ( modeU == 0 )
{
unpc_block( p->mPredictor, p->mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU );
}
else
{
// the special "numActive == 31" mode can be done in-place
unpc_block( p->mPredictor, p->mPredictor, numSamples, NULL, 31, chanBits, 0 );
unpc_block( p->mPredictor, p->mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU );
}
}
else
{
//Assert( bytesShifted == 0 );
// uncompressed frame, copy data into the mix buffer to use common output code
shift = 32 - chanBits;
if ( chanBits <= 16 )
{
for ( i = 0; i < numSamples; i++ )
{
val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits );
val = (val << shift) >> shift;
p->mMixBufferU[i] = val;
}
}
else
{
// BitBufferRead() can't read more than 16 bits at a time so break up the reads
extraBits = chanBits - 16;
for ( i = 0; i < numSamples; i++ )
{
val = (int32_t) BitBufferRead( bits, 16 );
val = (val << 16) >> shift;
p->mMixBufferU[i] = val | BitBufferRead( bits, (uint8_t) extraBits );
}
}
mixBits = mixRes = 0;
bits1 = chanBits * numSamples;
bytesShifted = 0;
}
// now read the shifted values into the shift buffer
if ( bytesShifted != 0 )
{
shift = bytesShifted * 8;
//Assert( shift <= 16 );
for ( i = 0; i < numSamples; i++ )
p->mShiftBuffer[i] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift );
}
// convert 32-bit integers into output buffer
switch ( p->mConfig.bitDepth )
{
case 16:
out32 = sampleBuffer + channelIndex;
for ( i = 0, j = 0; i < numSamples; i++, j += numChannels )
out32[j] = p->mMixBufferU[i] << 16;
break;
case 20:
out32 = sampleBuffer + channelIndex;
copyPredictorTo20( p->mMixBufferU, out32, numChannels, numSamples );
break;
case 24:
out32 = sampleBuffer + channelIndex;
if ( bytesShifted != 0 )
copyPredictorTo24Shift( p->mMixBufferU, p->mShiftBuffer, out32, numChannels, numSamples, bytesShifted );
else
copyPredictorTo24( p->mMixBufferU, out32, numChannels, numSamples );
break;
case 32:
out32 = sampleBuffer + channelIndex;
if ( bytesShifted != 0 )
copyPredictorTo32Shift( p->mMixBufferU, p->mShiftBuffer, out32, numChannels, numSamples, bytesShifted );
else
copyPredictorTo32( p->mMixBufferU, out32, numChannels, numSamples);
break;
}
channelIndex += 1;
*outNumSamples = numSamples;
break;
}
case ID_CPE:
{
// if decoding this pair would take us over the max channels limit, bail
if ( (channelIndex + 2) > numChannels )
goto NoMoreChannels;
// stereo channel pair
elementInstanceTag = BitBufferReadSmall( bits, 4 );
p->mActiveElements |= (1u << elementInstanceTag);
// read the 12 unused header bits
unusedHeader = (uint16_t) BitBufferRead( bits, 12 );
RequireAction( unusedHeader == 0, status = kALAC_ParamError; goto Exit; );
// read the 1-bit "partial frame" flag, 2-bit "shift-off" flag & 1-bit "escape" flag
headerByte = (uint8_t) BitBufferRead( bits, 4 );
partialFrame = headerByte >> 3;
bytesShifted = (headerByte >> 1) & 0x3u;
RequireAction( bytesShifted != 3, status = kALAC_ParamError; goto Exit; );
shift = bytesShifted * 8;
escapeFlag = headerByte & 0x1;
chanBits = p->mConfig.bitDepth - (bytesShifted * 8) + 1;
// check for partial frame length to override requested numSamples
if ( partialFrame != 0 )
{
numSamples = BitBufferRead( bits, 16 ) << 16;
numSamples |= BitBufferRead( bits, 16 );
}
if ( escapeFlag == 0 )
{
// compressed frame, read rest of parameters
mixBits = (uint8_t) BitBufferRead( bits, 8 );
mixRes = (int8_t) BitBufferRead( bits, 8 );
headerByte = (uint8_t) BitBufferRead( bits, 8 );
modeU = headerByte >> 4;
denShiftU = headerByte & 0xfu;
headerByte = (uint8_t) BitBufferRead( bits, 8 );
pbFactorU = headerByte >> 5;
numU = headerByte & 0x1fu;
for ( i = 0; i < numU; i++ )
coefsU[i] = (int16_t) BitBufferRead( bits, 16 );
headerByte = (uint8_t) BitBufferRead( bits, 8 );
modeV = headerByte >> 4;
denShiftV = headerByte & 0xfu;
headerByte = (uint8_t) BitBufferRead( bits, 8 );
pbFactorV = headerByte >> 5;
numV = headerByte & 0x1fu;
for ( i = 0; i < numV; i++ )
coefsV[i] = (int16_t) BitBufferRead( bits, 16 );
// if shift active, skip the interleaved shifted values but remember where they start
if ( bytesShifted != 0 )
{
shiftBits = *bits;
BitBufferAdvance( bits, (bytesShifted * 8) * 2 * numSamples );
}
// decompress and run predictor for "left" channel
set_ag_params( &agParams, p->mConfig.mb, (pb * pbFactorU) / 4, p->mConfig.kb, numSamples, numSamples, p->mConfig.maxRun );
status = dyn_decomp( &agParams, bits, p->mPredictor, numSamples, chanBits, &bits1 );
RequireNoErr( status, goto Exit; );
if ( modeU == 0 )
{
unpc_block( p->mPredictor, p->mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU );
}
else
{
// the special "numActive == 31" mode can be done in-place
unpc_block( p->mPredictor, p->mPredictor, numSamples, NULL, 31, chanBits, 0 );
unpc_block( p->mPredictor, p->mMixBufferU, numSamples, &coefsU[0], numU, chanBits, denShiftU );
}
// decompress and run predictor for "right" channel
set_ag_params( &agParams, p->mConfig.mb, (pb * pbFactorV) / 4, p->mConfig.kb, numSamples, numSamples, p->mConfig.maxRun );
status = dyn_decomp( &agParams, bits, p->mPredictor, numSamples, chanBits, &bits2 );
RequireNoErr( status, goto Exit; );
if ( modeV == 0 )
{
unpc_block( p->mPredictor, p->mMixBufferV, numSamples, &coefsV[0], numV, chanBits, denShiftV );
}
else
{
// the special "numActive == 31" mode can be done in-place
unpc_block( p->mPredictor, p->mPredictor, numSamples, NULL, 31, chanBits, 0 );
unpc_block( p->mPredictor, p->mMixBufferV, numSamples, &coefsV[0], numV, chanBits, denShiftV );
}
}
else
{
//Assert( bytesShifted == 0 );
// uncompressed frame, copy data into the mix buffers to use common output code
chanBits = p->mConfig.bitDepth;
shift = 32 - chanBits;
if ( chanBits <= 16 )
{
for ( i = 0; i < numSamples; i++ )
{
val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits );
val = (val << shift) >> shift;
p->mMixBufferU[i] = val;
val = (int32_t) BitBufferRead( bits, (uint8_t) chanBits );
val = (val << shift) >> shift;
p->mMixBufferV[i] = val;
}
}
else
{
// BitBufferRead() can't read more than 16 bits at a time so break up the reads
extraBits = chanBits - 16;
for ( i = 0; i < numSamples; i++ )
{
val = (int32_t) BitBufferRead( bits, 16 );
val = (val << 16) >> shift;
p->mMixBufferU[i] = val | BitBufferRead( bits, (uint8_t)extraBits );
val = (int32_t) BitBufferRead( bits, 16 );
val = (val << 16) >> shift;
p->mMixBufferV[i] = val | BitBufferRead( bits, (uint8_t)extraBits );
}
}
bits1 = chanBits * numSamples;
bits2 = chanBits * numSamples;
mixBits = mixRes = 0;
bytesShifted = 0;
}
// now read the shifted values into the shift buffer
if ( bytesShifted != 0 )
{
shift = bytesShifted * 8;
//Assert( shift <= 16 );
for ( i = 0; i < (numSamples * 2); i += 2 )
{
p->mShiftBuffer[i + 0] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift );
p->mShiftBuffer[i + 1] = (uint16_t) BitBufferRead( &shiftBits, (uint8_t) shift );
}
}
// un-mix the data and convert to output format
// - note that mixRes = 0 means just interleave so we use that path for uncompressed frames
switch ( p->mConfig.bitDepth )
{
case 16:
out32 = sampleBuffer + channelIndex;
unmix16( p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples, mixBits, mixRes );
break;
case 20:
out32 = sampleBuffer + channelIndex;
unmix20( p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples, mixBits, mixRes );
break;
case 24:
out32 = sampleBuffer + channelIndex;
unmix24( p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples,
mixBits, mixRes, p->mShiftBuffer, bytesShifted );
break;
case 32:
out32 = sampleBuffer + channelIndex;
unmix32( p->mMixBufferU, p->mMixBufferV, out32, numChannels, numSamples,
mixBits, mixRes, p->mShiftBuffer, bytesShifted );
break;
}
channelIndex += 2;
*outNumSamples = numSamples;
break;
}
case ID_CCE:
case ID_PCE:
{
// unsupported element, bail
//AssertNoErr( tag );
status = kALAC_ParamError;
break;
}
case ID_DSE:
{
// data stream element -- parse but ignore
status = alac_data_stream_element (bits) ;
break;
}
case ID_FIL:
{
// fill element -- parse but ignore
status = alac_fill_element (bits) ;
break;
}
case ID_END:
{
// frame end, all done so byte align the frame and check for overruns
BitBufferByteAlign( bits, false );
//Assert( bits->cur == bits->end );
goto Exit;
}
}
#if 0 // ! DEBUG
// if we've decoded all of our channels, bail (but not in debug b/c we want to know if we're seeing bad bits)
// - this also protects us if the config does not match the bitstream or crap data bits follow the audio bits
if ( channelIndex >= numChannels )
break;
#endif
}
NoMoreChannels:
// if we get here and haven't decoded all of the requested channels, fill the remaining channels with zeros
for ( ; channelIndex < numChannels; channelIndex++ )
{
int32_t * fill32 = sampleBuffer + channelIndex;
Zero32( fill32, numSamples, numChannels );
}
Exit:
return status;
}
#if PRAGMA_MARK
#pragma mark -
#endif
/*
FillElement()
- they're just filler so we don't need 'em
*/
static int32_t
alac_fill_element (struct BitBuffer * bits)
{
int16_t count;
// 4-bit count or (4-bit + 8-bit count) if 4-bit count == 15
// - plus this weird -1 thing I still don't fully understand
count = BitBufferReadSmall( bits, 4 );
if ( count == 15 )
count += (int16_t) BitBufferReadSmall( bits, 8 ) - 1;
BitBufferAdvance( bits, count * 8 );
RequireAction( bits->cur <= bits->end, return kALAC_ParamError; );
return ALAC_noErr;
}
/*
DataStreamElement()
- we don't care about data stream elements so just skip them
*/
static int32_t
alac_data_stream_element (struct BitBuffer * bits)
{
int32_t data_byte_align_flag;
uint16_t count;
// the tag associates this data stream element with a given audio element
/* element_instance_tag = */ BitBufferReadSmall( bits, 4 );
data_byte_align_flag = BitBufferReadOne( bits );
// 8-bit count or (8-bit + 8-bit count) if 8-bit count == 255
count = BitBufferReadSmall( bits, 8 );
if ( count == 255 )
count += BitBufferReadSmall( bits, 8 );
// the align flag means the bitstream should be byte-aligned before reading the following data bytes
if ( data_byte_align_flag )
BitBufferByteAlign( bits, false );
// skip the data bytes
BitBufferAdvance( bits, count * 8 );
RequireAction( bits->cur <= bits->end, return kALAC_ParamError; );
return ALAC_noErr;
}
/*
ZeroN()
- helper routines to clear out output channel buffers when decoding fewer channels than requested
*/
static void Zero32( int32_t * buffer, uint32_t numItems, uint32_t stride )
{
uint32_t indx;
if ( stride == 1 )
{
memset( buffer, 0, numItems * sizeof(int32_t) );
}
else
{
for ( indx = 0; indx < (numItems * stride); indx += stride )
buffer[indx] = 0;
}
}
+61
View File
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: alac_decoder.h
*/
#ifndef ALAC_DECODER_H
#define ALAC_DECODER_H
#include <stdint.h>
#include "ALACAudioTypes.h"
typedef enum
{
false = 0,
ALAC_TRUE = 1
} bool ;
struct BitBuffer;
typedef struct alac_decoder
{
// decoding parameters (public for use in the analyzer)
ALACSpecificConfig mConfig;
uint16_t mActiveElements;
// decoding buffers
int32_t * mMixBufferU;
int32_t * mMixBufferV;
int32_t * mPredictor;
uint16_t * mShiftBuffer; // note: this points to mPredictor's memory but different
// variable for clarity and type difference
} alac_decoder ;
alac_decoder * alac_decoder_new (void) ;
void alac_decoder_delete (alac_decoder *) ;
int32_t alac_init (alac_decoder *p, void * inMagicCookie, uint32_t inMagicCookieSize) ;
int32_t alac_decode (alac_decoder *, struct BitBuffer * bits, uint8_t * sampleBuffer, uint32_t numSamples, uint32_t numChannels, uint32_t * outNumSamples) ;
#endif /* ALAC_DECODER_H */
File diff suppressed because it is too large. Load diff
+375
View File
@@ -0,0 +1,375 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: dp_dec.c
Contains: Dynamic Predictor decode routines
Copyright: (c) 2001-2011 Apple, Inc.
*/
#include "dplib.h"
#include <string.h>
#if __GNUC__
#define ALWAYS_INLINE __attribute__((always_inline))
#else
#define ALWAYS_INLINE
#endif
#define LOOP_ALIGN
static inline int32_t ALWAYS_INLINE sign_of_int( int32_t i )
{
int32_t negishift;
negishift = ((uint32_t)-i) >> 31;
return negishift | (i >> 31);
}
void unpc_block( int32_t * pc1, int32_t * out, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift )
{
register int16_t a0, a1, a2, a3;
register int32_t b0, b1, b2, b3;
int32_t j, k, lim;
int32_t sum1, sg, sgn, top, dd;
int32_t * pout;
int32_t del, del0;
uint32_t chanshift = 32 - chanbits;
int32_t denhalf = 1<<(denshift-1);
out[0] = pc1[0];
if ( numactive == 0 )
{
// just copy if numactive == 0 (but don't bother if in/out pointers the same)
if ( (num > 1) && (pc1 != out) )
memcpy( &out[1], &pc1[1], (num - 1) * sizeof(int32_t) );
return;
}
if ( numactive == 31 )
{
// short-circuit if numactive == 31
int32_t prev;
/* this code is written such that the in/out buffers can be the same
to conserve buffer space on embedded devices like the iPod
(original code)
for ( j = 1; j < num; j++ )
del = pc1[j] + out[j-1];
out[j] = (del << chanshift) >> chanshift;
*/
prev = out[0];
for ( j = 1; j < num; j++ )
{
del = pc1[j] + prev;
prev = (del << chanshift) >> chanshift;
out[j] = prev;
}
return;
}
for ( j = 1; j <= numactive; j++ )
{
del = pc1[j] + out[j-1];
out[j] = (del << chanshift) >> chanshift;
}
lim = numactive + 1;
if ( numactive == 4 )
{
// optimization for numactive == 4
register int16_t ia0, ia1, ia2, ia3;
register int32_t ib0, ib1, ib2, ib3;
ia0 = coefs[0];
ia1 = coefs[1];
ia2 = coefs[2];
ia3 = coefs[3];
for ( j = lim; j < num; j++ )
{
LOOP_ALIGN
top = out[j - lim];
pout = out + j - 1;
ib0 = top - pout[0];
ib1 = top - pout[-1];
ib2 = top - pout[-2];
ib3 = top - pout[-3];
sum1 = (denhalf - ia0 * ib0 - ia1 * ib1 - ia2 * ib2 - ia3 * ib3) >> denshift;
del = pc1[j];
del0 = del;
sg = sign_of_int(del);
del += top + sum1;
out[j] = (del << chanshift) >> chanshift;
if ( sg > 0 )
{
sgn = sign_of_int( ib3 );
ia3 -= sgn;
del0 -= (4 - 3) * ((sgn * ib3) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( ib2 );
ia2 -= sgn;
del0 -= (4 - 2) * ((sgn * ib2) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( ib1 );
ia1 -= sgn;
del0 -= (4 - 1) * ((sgn * ib1) >> denshift);
if ( del0 <= 0 )
continue;
ia0 -= sign_of_int( ib0 );
}
else if ( sg < 0 )
{
// note: to avoid unnecessary negations, we flip the value of "sgn"
sgn = -sign_of_int( ib3 );
ia3 -= sgn;
del0 -= (4 - 3) * ((sgn * ib3) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( ib2 );
ia2 -= sgn;
del0 -= (4 - 2) * ((sgn * ib2) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( ib1 );
ia1 -= sgn;
del0 -= (4 - 1) * ((sgn * ib1) >> denshift);
if ( del0 >= 0 )
continue;
ia0 += sign_of_int( ib0 );
}
}
coefs[0] = ia0;
coefs[1] = ia1;
coefs[2] = ia2;
coefs[3] = ia3;
}
else if ( numactive == 8 )
{
register int16_t a4, a5, a6, a7;
register int32_t b4, b5, b6, b7;
// optimization for numactive == 8
a0 = coefs[0];
a1 = coefs[1];
a2 = coefs[2];
a3 = coefs[3];
a4 = coefs[4];
a5 = coefs[5];
a6 = coefs[6];
a7 = coefs[7];
for ( j = lim; j < num; j++ )
{
LOOP_ALIGN
top = out[j - lim];
pout = out + j - 1;
b0 = top - (*pout--);
b1 = top - (*pout--);
b2 = top - (*pout--);
b3 = top - (*pout--);
b4 = top - (*pout--);
b5 = top - (*pout--);
b6 = top - (*pout--);
b7 = top - (*pout);
pout += 8;
sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3
- a4 * b4 - a5 * b5 - a6 * b6 - a7 * b7) >> denshift;
del = pc1[j];
del0 = del;
sg = sign_of_int(del);
del += top + sum1;
out[j] = (del << chanshift) >> chanshift;
if ( sg > 0 )
{
sgn = sign_of_int( b7 );
a7 -= sgn;
del0 -= 1 * ((sgn * b7) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b6 );
a6 -= sgn;
del0 -= 2 * ((sgn * b6) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b5 );
a5 -= sgn;
del0 -= 3 * ((sgn * b5) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b4 );
a4 -= sgn;
del0 -= 4 * ((sgn * b4) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b3 );
a3 -= sgn;
del0 -= 5 * ((sgn * b3) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b2 );
a2 -= sgn;
del0 -= 6 * ((sgn * b2) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b1 );
a1 -= sgn;
del0 -= 7 * ((sgn * b1) >> denshift);
if ( del0 <= 0 )
continue;
a0 -= sign_of_int( b0 );
}
else if ( sg < 0 )
{
// note: to avoid unnecessary negations, we flip the value of "sgn"
sgn = -sign_of_int( b7 );
a7 -= sgn;
del0 -= 1 * ((sgn * b7) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b6 );
a6 -= sgn;
del0 -= 2 * ((sgn * b6) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b5 );
a5 -= sgn;
del0 -= 3 * ((sgn * b5) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b4 );
a4 -= sgn;
del0 -= 4 * ((sgn * b4) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b3 );
a3 -= sgn;
del0 -= 5 * ((sgn * b3) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b2 );
a2 -= sgn;
del0 -= 6 * ((sgn * b2) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b1 );
a1 -= sgn;
del0 -= 7 * ((sgn * b1) >> denshift);
if ( del0 >= 0 )
continue;
a0 += sign_of_int( b0 );
}
}
coefs[0] = a0;
coefs[1] = a1;
coefs[2] = a2;
coefs[3] = a3;
coefs[4] = a4;
coefs[5] = a5;
coefs[6] = a6;
coefs[7] = a7;
}
else
{
// general case
for ( j = lim; j < num; j++ )
{
LOOP_ALIGN
sum1 = 0;
pout = out + j - 1;
top = out[j-lim];
for ( k = 0; k < numactive; k++ )
sum1 += coefs[k] * (pout[-k] - top);
del = pc1[j];
del0 = del;
sg = sign_of_int( del );
del += top + ((sum1 + denhalf) >> denshift);
out[j] = (del << chanshift) >> chanshift;
if ( sg > 0 )
{
for ( k = (numactive - 1); k >= 0; k-- )
{
dd = top - pout[-k];
sgn = sign_of_int( dd );
coefs[k] -= sgn;
del0 -= (numactive - k) * ((sgn * dd) >> denshift);
if ( del0 <= 0 )
break;
}
}
else if ( sg < 0 )
{
for ( k = (numactive - 1); k >= 0; k-- )
{
dd = top - pout[-k];
sgn = sign_of_int( dd );
coefs[k] += sgn;
del0 -= (numactive - k) * ((-sgn * dd) >> denshift);
if ( del0 >= 0 )
break;
}
}
}
}
}
+380
View File
@@ -0,0 +1,380 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: dp_enc.c
Contains: Dynamic Predictor encode routines
Copyright: (c) 2001-2011 Apple, Inc.
*/
#include "dplib.h"
#include <string.h>
#if __GNUC__
#define ALWAYS_INLINE __attribute__((always_inline))
#else
#define ALWAYS_INLINE
#endif
#define LOOP_ALIGN
void init_coefs( int16_t * coefs, uint32_t denshift, int32_t numPairs )
{
int32_t k;
int32_t den = 1 << denshift;
coefs[0] = (AINIT * den) >> 4;
coefs[1] = (BINIT * den) >> 4;
coefs[2] = (CINIT * den) >> 4;
for ( k = 3; k < numPairs; k++ )
coefs[k] = 0;
}
void copy_coefs( int16_t * srcCoefs, int16_t * dstCoefs, int32_t numPairs )
{
int32_t k;
for ( k = 0; k < numPairs; k++ )
dstCoefs[k] = srcCoefs[k];
}
static inline int32_t ALWAYS_INLINE sign_of_int( int32_t i )
{
int32_t negishift;
negishift = ((uint32_t)-i) >> 31;
return negishift | (i >> 31);
}
void pc_block( int32_t * in, int32_t * pc1, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift )
{
register int16_t a0, a1, a2, a3;
register int32_t b0, b1, b2, b3;
int32_t j, k, lim;
int32_t * pin;
int32_t sum1, dd;
int32_t sg, sgn;
int32_t top;
int32_t del, del0;
uint32_t chanshift = 32 - chanbits;
int32_t denhalf = 1 << (denshift - 1);
pc1[0] = in[0];
if ( numactive == 0 )
{
// just copy if numactive == 0 (but don't bother if in/out pointers the same)
if ( (num > 1) && (in != pc1) )
memcpy( &pc1[1], &in[1], (num - 1) * sizeof(int32_t) );
return;
}
if ( numactive == 31 )
{
// short-circuit if numactive == 31
for( j = 1; j < num; j++ )
{
del = in[j] - in[j-1];
pc1[j] = (del << chanshift) >> chanshift;
}
return;
}
for ( j = 1; j <= numactive; j++ )
{
del = in[j] - in[j-1];
pc1[j] = (del << chanshift) >> chanshift;
}
lim = numactive + 1;
if ( numactive == 4 )
{
// optimization for numactive == 4
a0 = coefs[0];
a1 = coefs[1];
a2 = coefs[2];
a3 = coefs[3];
for ( j = lim; j < num; j++ )
{
LOOP_ALIGN
top = in[j - lim];
pin = in + j - 1;
b0 = top - pin[0];
b1 = top - pin[-1];
b2 = top - pin[-2];
b3 = top - pin[-3];
sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3) >> denshift;
del = in[j] - top - sum1;
del = (del << chanshift) >> chanshift;
pc1[j] = del;
del0 = del;
sg = sign_of_int(del);
if ( sg > 0 )
{
sgn = sign_of_int( b3 );
a3 -= sgn;
del0 -= (4 - 3) * ((sgn * b3) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b2 );
a2 -= sgn;
del0 -= (4 - 2) * ((sgn * b2) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b1 );
a1 -= sgn;
del0 -= (4 - 1) * ((sgn * b1) >> denshift);
if ( del0 <= 0 )
continue;
a0 -= sign_of_int( b0 );
}
else if ( sg < 0 )
{
// note: to avoid unnecessary negations, we flip the value of "sgn"
sgn = -sign_of_int( b3 );
a3 -= sgn;
del0 -= (4 - 3) * ((sgn * b3) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b2 );
a2 -= sgn;
del0 -= (4 - 2) * ((sgn * b2) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b1 );
a1 -= sgn;
del0 -= (4 - 1) * ((sgn * b1) >> denshift);
if ( del0 >= 0 )
continue;
a0 += sign_of_int( b0 );
}
}
coefs[0] = a0;
coefs[1] = a1;
coefs[2] = a2;
coefs[3] = a3;
}
else if ( numactive == 8 )
{
// optimization for numactive == 8
register int16_t a4, a5, a6, a7;
register int32_t b4, b5, b6, b7;
a0 = coefs[0];
a1 = coefs[1];
a2 = coefs[2];
a3 = coefs[3];
a4 = coefs[4];
a5 = coefs[5];
a6 = coefs[6];
a7 = coefs[7];
for ( j = lim; j < num; j++ )
{
LOOP_ALIGN
top = in[j - lim];
pin = in + j - 1;
b0 = top - (*pin--);
b1 = top - (*pin--);
b2 = top - (*pin--);
b3 = top - (*pin--);
b4 = top - (*pin--);
b5 = top - (*pin--);
b6 = top - (*pin--);
b7 = top - (*pin);
pin += 8;
sum1 = (denhalf - a0 * b0 - a1 * b1 - a2 * b2 - a3 * b3
- a4 * b4 - a5 * b5 - a6 * b6 - a7 * b7) >> denshift;
del = in[j] - top - sum1;
del = (del << chanshift) >> chanshift;
pc1[j] = del;
del0 = del;
sg = sign_of_int(del);
if ( sg > 0 )
{
sgn = sign_of_int( b7 );
a7 -= sgn;
del0 -= 1 * ((sgn * b7) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b6 );
a6 -= sgn;
del0 -= 2 * ((sgn * b6) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b5 );
a5 -= sgn;
del0 -= 3 * ((sgn * b5) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b4 );
a4 -= sgn;
del0 -= 4 * ((sgn * b4) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b3 );
a3 -= sgn;
del0 -= 5 * ((sgn * b3) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b2 );
a2 -= sgn;
del0 -= 6 * ((sgn * b2) >> denshift);
if ( del0 <= 0 )
continue;
sgn = sign_of_int( b1 );
a1 -= sgn;
del0 -= 7 * ((sgn * b1) >> denshift);
if ( del0 <= 0 )
continue;
a0 -= sign_of_int( b0 );
}
else if ( sg < 0 )
{
// note: to avoid unnecessary negations, we flip the value of "sgn"
sgn = -sign_of_int( b7 );
a7 -= sgn;
del0 -= 1 * ((sgn * b7) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b6 );
a6 -= sgn;
del0 -= 2 * ((sgn * b6) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b5 );
a5 -= sgn;
del0 -= 3 * ((sgn * b5) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b4 );
a4 -= sgn;
del0 -= 4 * ((sgn * b4) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b3 );
a3 -= sgn;
del0 -= 5 * ((sgn * b3) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b2 );
a2 -= sgn;
del0 -= 6 * ((sgn * b2) >> denshift);
if ( del0 >= 0 )
continue;
sgn = -sign_of_int( b1 );
a1 -= sgn;
del0 -= 7 * ((sgn * b1) >> denshift);
if ( del0 >= 0 )
continue;
a0 += sign_of_int( b0 );
}
}
coefs[0] = a0;
coefs[1] = a1;
coefs[2] = a2;
coefs[3] = a3;
coefs[4] = a4;
coefs[5] = a5;
coefs[6] = a6;
coefs[7] = a7;
}
else
{
//pc_block_general:
// general case
for ( j = lim; j < num; j++ )
{
LOOP_ALIGN
top = in[j - lim];
pin = in + j - 1;
sum1 = 0;
for ( k = 0; k < numactive; k++ )
sum1 -= coefs[k] * (top - pin[-k]);
del = in[j] - top - ((sum1 + denhalf) >> denshift);
del = (del << chanshift) >> chanshift;
pc1[j] = del;
del0 = del;
sg = sign_of_int( del );
if ( sg > 0 )
{
for ( k = (numactive - 1); k >= 0; k-- )
{
dd = top - pin[-k];
sgn = sign_of_int( dd );
coefs[k] -= sgn;
del0 -= (numactive - k) * ((sgn * dd) >> denshift);
if ( del0 <= 0 )
break;
}
}
else if ( sg < 0 )
{
for ( k = (numactive - 1); k >= 0; k-- )
{
dd = top - pin[-k];
sgn = sign_of_int( dd );
coefs[k] += sgn;
del0 -= (numactive - k) * ((-sgn * dd) >> denshift);
if ( del0 >= 0 )
break;
}
}
}
}
}
+61
View File
@@ -0,0 +1,61 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: dplib.h
Contains: Dynamic Predictor routines
Copyright: Copyright (C) 2001-2011 Apple, Inc.
*/
#ifndef __DPLIB_H__
#define __DPLIB_H__
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// defines
#define DENSHIFT_MAX 15
#define DENSHIFT_DEFAULT 9
#define AINIT 38
#define BINIT (-29)
#define CINIT (-2)
#define NUMCOEPAIRS 16
// prototypes
void init_coefs( int16_t * coefs, uint32_t denshift, int32_t numPairs );
void copy_coefs( int16_t * srcCoefs, int16_t * dstCoefs, int32_t numPairs );
// NOTE: these routines read at least "numactive" samples so the i/o buffers must be at least that big
void pc_block( int32_t * in, int32_t * pc, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift );
void unpc_block( int32_t * pc, int32_t * out, int32_t num, int16_t * coefs, int32_t numactive, uint32_t chanbits, uint32_t denshift );
#ifdef __cplusplus
}
#endif
#endif /* __DPLIB_H__ */
+320
View File
@@ -0,0 +1,320 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: matrix_dec.c
Contains: ALAC mixing/matrixing decode routines.
Copyright: (c) 2004-2011 Apple, Inc.
*/
#include "matrixlib.h"
#include "ALACAudioTypes.h"
// up to 24-bit "offset" macros for the individual bytes of a 20/24-bit word
#if TARGET_RT_BIG_ENDIAN
#define LBYTE 2
#define MBYTE 1
#define HBYTE 0
#else
#define LBYTE 0
#define MBYTE 1
#define HBYTE 2
#endif
/*
There is no plain middle-side option; instead there are various mixing
modes including middle-side, each lossless, as embodied in the mix()
and unmix() functions. These functions exploit a generalized middle-side
transformation:
u := [(rL + (m-r)R)/m];
v := L - R;
where [ ] denotes integer floor. The (lossless) inverse is
L = u + v - [rV/m];
R = L - v;
*/
// 16-bit routines
void unmix16( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres )
{
int32_t j;
if ( mixres != 0 )
{
/* matrixed stereo */
for ( j = 0; j < numSamples; j++ )
{
int32_t l, r;
l = u[j] + v[j] - ((mixres * v[j]) >> mixbits);
r = l - v[j];
out[0] = l << 16;
out[1] = r << 16;
out += stride;
}
}
else
{
/* Conventional separated stereo. */
for ( j = 0; j < numSamples; j++ )
{
out[0] = u[j] << 16;
out[1] = v[j] << 16;
out += stride;
}
}
}
// 20-bit routines
// - the 20 bits of data are left-justified in 3 bytes of storage but right-aligned for input/output predictor buffers
void unmix20( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres )
{
int32_t j;
if ( mixres != 0 )
{
/* matrixed stereo */
for ( j = 0; j < numSamples; j++ )
{
int32_t l, r;
l = u[j] + v[j] - ((mixres * v[j]) >> mixbits);
r = l - v[j];
out[0] = l << 12;
out[1] = r << 12;
out += stride;
}
}
else
{
/* Conventional separated stereo. */
for ( j = 0; j < numSamples; j++ )
{
out[0] = u[j] << 12;
out[1] = v[j] << 12;
out += stride;
}
}
}
// 24-bit routines
// - the 24 bits of data are right-justified in the input/output predictor buffers
void unmix24( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted )
{
int32_t shift = bytesShifted * 8;
int32_t l, r;
int32_t j, k;
if ( mixres != 0 )
{
/* matrixed stereo */
if ( bytesShifted != 0 )
{
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = u[j] + v[j] - ((mixres * v[j]) >> mixbits);
r = l - v[j];
l = (l << shift) | (uint32_t) shiftUV[k + 0];
r = (r << shift) | (uint32_t) shiftUV[k + 1];
out[0] = l << 8;
out[1] = r << 8;
out += stride;
}
}
else
{
for ( j = 0; j < numSamples; j++ )
{
l = u[j] + v[j] - ((mixres * v[j]) >> mixbits);
r = l - v[j];
out[0] = l << 8;
out[1] = r << 8;
out += stride;
}
}
}
else
{
/* Conventional separated stereo. */
if ( bytesShifted != 0 )
{
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = u[j];
r = v[j];
l = (l << shift) | (uint32_t) shiftUV[k + 0];
r = (r << shift) | (uint32_t) shiftUV[k + 1];
out[0] = l << 8;
out[1] = r << 8;
out += stride;
}
}
else
{
for ( j = 0; j < numSamples; j++ )
{
out[0] = u[j] << 8;
out[1] = v[j] << 8;
out += stride;
}
}
}
}
// 32-bit routines
// - note that these really expect the internal data width to be < 32 but the arrays are 32-bit
// - otherwise, the calculations might overflow into the 33rd bit and be lost
// - therefore, these routines deal with the specified "unused lower" bytes in the "shift" buffers
void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted )
{
int32_t shift = bytesShifted * 8;
int32_t l, r;
int32_t j, k;
if ( mixres != 0 )
{
//Assert( bytesShifted != 0 );
/* matrixed stereo with shift */
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
int32_t lt, rt;
lt = u[j];
rt = v[j];
l = lt + rt - ((mixres * rt) >> mixbits);
r = l - rt;
out[0] = (l << shift) | (uint32_t) shiftUV[k + 0];
out[1] = (r << shift) | (uint32_t) shiftUV[k + 1];
out += stride;
}
}
else
{
if ( bytesShifted == 0 )
{
/* interleaving w/o shift */
for ( j = 0; j < numSamples; j++ )
{
out[0] = u[j];
out[1] = v[j];
out += stride;
}
}
else
{
/* interleaving with shift */
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
out[0] = (u[j] << shift) | (uint32_t) shiftUV[k + 0];
out[1] = (v[j] << shift) | (uint32_t) shiftUV[k + 1];
out += stride;
}
}
}
}
// 20/24-bit <-> 32-bit helper routines (not really matrixing but convenient to put here)
void copyPredictorTo24( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples )
{
int32_t j;
for ( j = 0; j < numSamples; j++ )
{
out[0] = in[j] << 8;
out += stride;
}
}
void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted )
{
int32_t shiftVal = bytesShifted * 8;
int32_t j;
//Assert( bytesShifted != 0 );
for ( j = 0; j < numSamples; j++ )
{
int32_t val = in[j];
val = (val << shiftVal) | (uint32_t) shift[j];
out[0] = val << 8;
out += stride;
}
}
void copyPredictorTo20( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples )
{
int32_t j;
// 32-bit predictor values are right-aligned but 20-bit output values should be left-aligned
// in the 24-bit output buffer
for ( j = 0; j < numSamples; j++ )
{
out[0] = in[j] << 12;
out += stride;
}
}
void copyPredictorTo32( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples )
{
int32_t i, j;
// this is only a subroutine to abstract the "iPod can only output 16-bit data" problem
for ( i = 0, j = 0; i < numSamples; i++, j += stride )
out[j] = in[i] << 8;
}
void copyPredictorTo32Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted )
{
int32_t * op = out;
uint32_t shiftVal = bytesShifted * 8;
int32_t j;
//Assert( bytesShifted != 0 );
// this is only a subroutine to abstract the "iPod can only output 16-bit data" problem
for ( j = 0; j < numSamples; j++ )
{
op[0] = (in[j] << shiftVal) | (uint32_t) shift[j];
op += stride;
}
}
+272
View File
@@ -0,0 +1,272 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: matrix_enc.c
Contains: ALAC mixing/matrixing encode routines.
Copyright: (c) 2004-2011 Apple, Inc.
*/
#include "matrixlib.h"
#include "ALACAudioTypes.h"
/*
There is no plain middle-side option; instead there are various mixing
modes including middle-side, each lossless, as embodied in the mix()
and unmix() functions. These functions exploit a generalized middle-side
transformation:
u := [(rL + (m-r)R)/m];
v := L - R;
where [ ] denotes integer floor. The (lossless) inverse is
L = u + v - [rV/m];
R = L - v;
*/
// 16-bit routines
void mix16( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres )
{
int32_t j;
if ( mixres != 0 )
{
int32_t mod = 1 << mixbits;
int32_t m2;
/* matrixed stereo */
m2 = mod - mixres;
for ( j = 0; j < numSamples; j++ )
{
int32_t l, r;
l = in[0] >> 16;
r = in[1] >> 16;
in += stride;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
}
else
{
/* Conventional separated stereo. */
for ( j = 0; j < numSamples; j++ )
{
u[j] = in[0] >> 16;
v[j] = in[1] >> 16;
in += stride;
}
}
}
// 20-bit routines
// - the 20 bits of data are left-justified in 3 bytes of storage but right-aligned for input/output predictor buffers
void mix20( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres )
{
int32_t l, r;
int32_t j;
if ( mixres != 0 )
{
/* matrixed stereo */
int32_t mod = 1 << mixbits;
int32_t m2 = mod - mixres;
for ( j = 0; j < numSamples; j++ )
{
l = in[0] >> 12;
r = in[1] >> 12;
in += stride;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
}
else
{
/* Conventional separated stereo. */
for ( j = 0; j < numSamples; j++ )
{
u[j] = in[0] >> 12;
v[j] = in[1] >> 12;
in += stride;
}
}
}
// 24-bit routines
// - the 24 bits of data are right-justified in the input/output predictor buffers
void mix24( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted )
{
int32_t l, r;
int32_t shift = bytesShifted * 8;
uint32_t mask = (1ul << shift) - 1;
int32_t j, k;
if ( mixres != 0 )
{
/* matrixed stereo */
int32_t mod = 1 << mixbits;
int32_t m2 = mod - mixres;
if ( bytesShifted != 0 )
{
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = in[0] >> 8;
r = in[1] >> 8;
in += stride;
shiftUV[k + 0] = (uint16_t)(l & mask);
shiftUV[k + 1] = (uint16_t)(r & mask);
l >>= shift;
r >>= shift;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
}
else
{
for ( j = 0; j < numSamples; j++ )
{
l = in[0] >> 8;
r = in[1] >> 8;
in += stride;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
}
}
else
{
/* Conventional separated stereo. */
if ( bytesShifted != 0 )
{
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = in[0] >> 8;
r = in[1] >> 8;
in += stride;
shiftUV[k + 0] = (uint16_t)(l & mask);
shiftUV[k + 1] = (uint16_t)(r & mask);
l >>= shift;
r >>= shift;
u[j] = l;
v[j] = r;
}
}
else
{
for ( j = 0; j < numSamples; j++ )
{
l = in[0] >> 8;
r = in[1] >> 8;
in += stride;
}
}
}
}
// 32-bit routines
// - note that these really expect the internal data width to be < 32 but the arrays are 32-bit
// - otherwise, the calculations might overflow into the 33rd bit and be lost
// - therefore, these routines deal with the specified "unused lower" bytes in the "shift" buffers
void mix32( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted )
{
int32_t shift = bytesShifted * 8;
uint32_t mask = (1ul << shift) - 1;
int32_t l, r;
int32_t j, k;
if ( mixres != 0 )
{
int32_t mod = 1 << mixbits;
int32_t m2;
//Assert( bytesShifted != 0 );
/* matrixed stereo with shift */
m2 = mod - mixres;
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = in[0];
r = in[1];
in += stride;
shiftUV[k + 0] = (uint16_t)(l & mask);
shiftUV[k + 1] = (uint16_t)(r & mask);
l >>= shift;
r >>= shift;
u[j] = (mixres * l + m2 * r) >> mixbits;
v[j] = l - r;
}
}
else
{
if ( bytesShifted == 0 )
{
/* de-interleaving w/o shift */
for ( j = 0; j < numSamples; j++ )
{
u[j] = in[0];
v[j] = in[1];
in += stride;
}
}
else
{
/* de-interleaving with shift */
for ( j = 0, k = 0; j < numSamples; j++, k += 2 )
{
l = in[0];
r = in[1];
in += stride;
shiftUV[k + 0] = (uint16_t)(l & mask);
shiftUV[k + 1] = (uint16_t)(r & mask);
l >>= shift;
r >>= shift;
u[j] = l;
v[j] = r;
}
}
}
}
+81
View File
@@ -0,0 +1,81 @@
/*
* Copyright (c) 2011 Apple Inc. All rights reserved.
* Copyright (C) 2012 Erik de Castro Lopo <erikd@mega-nerd.com>
*
* @APPLE_APACHE_LICENSE_HEADER_START@
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @APPLE_APACHE_LICENSE_HEADER_END@
*/
/*
File: matrixlib.h
Contains: ALAC mixing/matrixing routines to/from 32-bit predictor buffers.
Copyright: Copyright (C) 2004 to 2011 Apple, Inc.
*/
#ifndef __MATRIXLIB_H
#define __MATRIXLIB_H
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// 16-bit routines
void mix16( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres );
void unmix16( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres );
// 20-bit routines
void mix20( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples, int32_t mixbits, int32_t mixres );
void unmix20( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples, int32_t mixbits, int32_t mixres );
// 24-bit routines
// - 24-bit data sometimes compresses better by shifting off the bottom byte so these routines deal with
// the specified "unused lower bytes" in the combined "shift" buffer
void mix24( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted );
void unmix24( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted );
// 32-bit routines
// - note that these really expect the internal data width to be < 32-bit but the arrays are 32-bit
// - otherwise, the calculations might overflow into the 33rd bit and be lost
// - therefore, these routines deal with the specified "unused lower" bytes in the combined "shift" buffer
void mix32( int32_t * in, uint32_t stride, int32_t * u, int32_t * v, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted );
void unmix32( int32_t * u, int32_t * v, int32_t * out, uint32_t stride, int32_t numSamples,
int32_t mixbits, int32_t mixres, uint16_t * shiftUV, int32_t bytesShifted );
// 20/24/32-bit <-> 32-bit helper routines (not really matrixing but convenient to put here)
void copy20ToPredictor( int32_t * in, uint32_t stride, int32_t * out, int32_t numSamples );
void copy24ToPredictor( int32_t * in, uint32_t stride, int32_t * out, int32_t numSamples );
void copyPredictorTo24( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples );
void copyPredictorTo24Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted );
void copyPredictorTo20( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples );
void copyPredictorTo32( int32_t * in, int32_t * out, uint32_t stride, int32_t numSamples );
void copyPredictorTo32Shift( int32_t * in, uint16_t * shift, int32_t * out, uint32_t stride, int32_t numSamples, int32_t bytesShifted );
#ifdef __cplusplus
}
#endif
#endif /* __MATRIXLIB_H */
+1 -1
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
+22 -22
View File
@@ -1,21 +1,21 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
@@ -77,20 +77,20 @@ main (int argc, char *argv [])
return 0 ;
} /* main */
static void
static void
g721_test (void)
{
return ;
} /* g721_test */
static void
static void
g723_test (double margin)
{ static double orig_buffer [BUFFER_SIZE] ;
static short orig [BUFFER_SIZE] ;
static short data [BUFFER_SIZE] ;
G72x_STATE encoder_state, decoder_state ;
long k ;
int code, position, max_err ;
@@ -104,10 +104,10 @@ g723_test (double margin)
memset (data, 0, BUFFER_SIZE * sizeof (short)) ;
memset (orig, 0, BUFFER_SIZE * sizeof (short)) ;
printf (" g723_test : ") ;
fflush (stdout) ;
gen_signal_double (orig_buffer, 32000.0, BUFFER_SIZE) ;
for (k = 0 ; k < BUFFER_SIZE ; k++)
orig [k] = (short) orig_buffer [k] ;
@@ -144,13 +144,13 @@ g723_test (double margin)
#define SIGNAL_MAXVAL 30000.0
#define DECAY_COUNT 1000
static void
static void
gen_signal_double (double *gendata, double scale, int gendatalen)
{ int k, ramplen ;
double amp = 0.0 ;
ramplen = DECAY_COUNT ;
for (k = 0 ; k < gendatalen ; k++)
{ if (k <= ramplen)
amp = scale * k / ((double) ramplen) ;
@@ -160,11 +160,11 @@ gen_signal_double (double *gendata, double scale, int gendatalen)
gendata [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
+ 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
} ;
return ;
} /* gen_signal_double */
static int
static int
error_function (double data, double orig, double margin)
{ double error ;
@@ -174,7 +174,7 @@ error_function (double data, double orig, double margin)
error = fabs (data - orig) / 3000.0 ;
else
error = fabs (data - orig) / fabs (orig) ;
if (error > margin)
{ printf ("\n\n*******************\nError : %f\n", error) ;
return 1 ;
@@ -182,21 +182,21 @@ error_function (double data, double orig, double margin)
return 0 ;
} /* error_function */
static int
static int
oct_save_short (short *a, short *b, int len)
{ FILE *file ;
int k ;
if (! (file = fopen ("error.dat", "w")))
return 1 ;
fprintf (file, "# Not created by Octave\n") ;
fprintf (file, "# name: a\n") ;
fprintf (file, "# type: matrix\n") ;
fprintf (file, "# rows: %d\n", len) ;
fprintf (file, "# columns: 1\n") ;
for (k = 0 ; k < len ; k++)
fprintf (file, "% d\n", a [k]) ;
@@ -204,7 +204,7 @@ oct_save_short (short *a, short *b, int len)
fprintf (file, "# type: matrix\n") ;
fprintf (file, "# rows: %d\n", len) ;
fprintf (file, "# columns: 1\n") ;
for (k = 0 ; k < len ; k++)
fprintf (file, "% d\n", b [k]) ;
+80 -46
View File
@@ -1,100 +1,134 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = GSM610 G72x
AUTOMAKE_OPTIONS = subdir-objects
INCLUDES = @EXTERNAL_CFLAGS@
AM_CPPFLAGS = @EXTERNAL_CFLAGS@
lib_LTLIBRARIES = libsndfile.la
include_HEADERS = sndfile.hh
nodist_include_HEADERS = sndfile.h
noinst_LTLIBRARIES = libcommon.la
noinst_LTLIBRARIES = GSM610/libgsm.la G72x/libg72x.la ALAC/libalac.la libcommon.la
OS_SPECIFIC_CFLAGS = @OS_SPECIFIC_CFLAGS@
OS_SPECIFIC_LINKS = @OS_SPECIFIC_LINKS@
SYMBOL_FILES = Symbols.linux Symbols.darwin libsndfile-1.def Symbols.os2
SYMBOL_FILES = Symbols.gnu-binutils Symbols.darwin libsndfile-1.def Symbols.os2 Symbols.static
EXTRA_DIST = sndfile.h.in config.h.in test_endswap.tpl test_endswap.def \
$(SYMBOL_FILES) create_symbols_file.py binheader_writef_check.py
$(SYMBOL_FILES) create_symbols_file.py binheader_writef_check.py \
GSM610/README GSM610/COPYRIGHT GSM610/ChangeLog \
G72x/README G72x/README.original G72x/ChangeLog \
make-static-lib-hidden-privates.sh
noinst_HEADERS = common.h sfconfig.h sfendian.h wav_w64.h sf_unistd.h
noinst_HEADERS = common.h sfconfig.h sfendian.h wav_w64.h sf_unistd.h ogg.h chanmap.h
noinst_PROGRAMS =
check_PROGRAMS = test_main G72x/g72x_test
COMMON = common.c file_io.c command.c pcm.c ulaw.c alaw.c float32.c \
double64.c ima_adpcm.c ms_adpcm.c gsm610.c dwvw.c vox_adpcm.c \
interleave.c strings.c dither.c broadcast.c audio_detect.c \
ima_oki_adpcm.c ima_oki_adpcm.h chunk.c
interleave.c strings.c dither.c cart.c broadcast.c audio_detect.c \
ima_oki_adpcm.c ima_oki_adpcm.h alac.c chunk.c ogg.c chanmap.c \
windows.c id3.c $(WIN_VERSION_FILE)
FILESPECIFIC = sndfile.c aiff.c au.c avr.c caf.c dwd.c flac.c g72x.c htk.c ircam.c \
macbinary3.c macos.c mat4.c mat5.c nist.c ogg.c paf.c pvf.c raw.c rx2.c sd2.c \
sds.c svx.c txw.c voc.c wve.c w64.c wav_w64.c wav.c xi.c mpc2k.c rf64.c
macbinary3.c macos.c mat4.c mat5.c nist.c paf.c pvf.c raw.c rx2.c sd2.c \
sds.c svx.c txw.c voc.c wve.c w64.c wav_w64.c wav.c xi.c mpc2k.c rf64.c \
ogg_vorbis.c ogg_speex.c ogg_pcm.c ogg_opus.c
CLEANFILES = *~ *.exe G72x/*.exe
if USE_WIN_VERSION_FILE
WIN_VERSION_FILE = version-metadata.rc
else
WIN_VERSION_FILE =
endif
#===============================================================================
# MinGW requires -no-undefined if a DLL is to be built.
libsndfile_la_LDFLAGS = -no-undefined -version-info @SHARED_VERSION_INFO@ @SHLIB_VERSION_ARG@
libsndfile_la_SOURCES = $(FILESPECIFIC) $(noinst_HEADERS)
nodist_libsndfile_la_SOURCES = $(nodist_include_HEADERS)
libsndfile_la_LIBADD = libcommon.la GSM610/libgsm.la G72x/libg72x.la \
@EXTERNAL_LIBS@ -lm
libsndfile_la_LIBADD = GSM610/libgsm.la G72x/libg72x.la ALAC/libalac.la \
libcommon.la @EXTERNAL_LIBS@ -lm
libcommon_la_SOURCES = $(COMMON)
#test_main_SOURCES = test_main.c test_main.h test_conversions.c test_float.c test_endswap.c \
# test_audio_detect.c test_log_printf.c test_file_io.c test_ima_oki_adpcm.c
#test_main_LDADD = libcommon.la
#
#
#test_endswap.c: test_endswap.def test_endswap.tpl
# autogen --writable test_endswap.def
#======================================================================
# Subdir libraries.
genfiles : $(SYMBOL_FILES)
GSM610_libgsm_la_SOURCES = GSM610/config.h GSM610/gsm.h GSM610/gsm610_priv.h \
GSM610/add.c GSM610/code.c GSM610/decode.c GSM610/gsm_create.c \
GSM610/gsm_decode.c GSM610/gsm_destroy.c GSM610/gsm_encode.c \
GSM610/gsm_option.c GSM610/long_term.c GSM610/lpc.c GSM610/preprocess.c \
GSM610/rpe.c GSM610/short_term.c GSM610/table.c
# A single test programs.
# It is not possible to place these in the tests/ directory because they
# need access to the internals of the SF_PRIVATE struct.
G72x_libg72x_la_SOURCES = G72x/g72x.h G72x/g72x_priv.h \
G72x/g721.c G72x/g723_16.c G72x/g723_24.c G72x/g723_40.c G72x/g72x.c
check: $(noinst_PROGRAMS)
@echo
@echo
@echo
@echo "============================================================"
@if [ -x /usr/bin/python2.5 ]; then $(srcdir)/binheader_writef_check.py $(srcdir)/*.c ; fi
ALAC_libalac_la_SOURCES = ALAC/ALACAudioTypes.h ALAC/ALACBitUtilities.h \
ALAC/EndianPortable.h ALAC/aglib.h ALAC/dplib.h ALAC/matrixlib.h \
ALAC/alac_codec.h \
ALAC/ALACBitUtilities.c ALAC/ag_dec.c \
ALAC/ag_enc.c ALAC/dp_dec.c ALAC/dp_enc.c ALAC/matrix_dec.c \
ALAC/matrix_enc.c ALAC/alac_decoder.c ALAC/alac_encoder.c
#===============================================================================
# Test programs.
test_main_SOURCES = test_main.c test_main.h test_conversions.c test_float.c test_endswap.c \
test_audio_detect.c test_log_printf.c test_file_io.c test_ima_oki_adpcm.c \
test_strncpy_crlf.c test_broadcast_var.c test_cart_var.c
test_main_LDADD = libcommon.la
G72x_g72x_test_SOURCES = G72x/g72x_test.c
G72x_g72x_test_LDADD = G72x/libg72x.la
test_endswap.c: test_endswap.def test_endswap.tpl
cd $(srcdir) && autogen --writable test_endswap.def && cd $(abs_builddir)
genfiles : $(SYMBOL_FILES) test_endswap.c
check :
@if [ -x /usr/bin/python ]; then $(srcdir)/binheader_writef_check.py $(srcdir)/*.c ; fi
G72x/g72x_test$(EXEEXT) all
./test_main$(EXEEXT)
@echo "============================================================"
@echo
@echo
@echo
# Need this target to force building of test programs.
checkprograms : $(check_PROGRAMS)
#======================================================================
# Generate an OS specific Symbols files. This is done when the author
# builds the distribution tarball. There should be not need for the
# end user to create these files.
Symbols.linux: create_symbols_file.py
./create_symbols_file.py linux $(VERSION) > $@
Symbols.gnu-binutils: create_symbols_file.py
python $(srcdir)/create_symbols_file.py linux $(VERSION) > $@
Symbols.darwin: create_symbols_file.py
./create_symbols_file.py darwin $(VERSION) > $@
python $(srcdir)/create_symbols_file.py darwin $(VERSION) > $@
libsndfile-1.def: create_symbols_file.py
./create_symbols_file.py win32 $(VERSION) > $@
python $(srcdir)/create_symbols_file.py win32 $(VERSION) > $@
Symbols.os2: create_symbols_file.py
./create_symbols_file.py os2 $(VERSION) > $@
python $(srcdir)/create_symbols_file.py os2 $(VERSION) > $@
Symbols.static: create_symbols_file.py
python $(srcdir)/create_symbols_file.py static $(VERSION) > $@
# Fake dependancy to force the creation of these files.
sndfile.o : $(SYMBOL_FILES)
#======================================================================
# Building windows resource files (if needed).
.rc.lo:
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --tag=RC --mode=compile $(RC) $(RCFLAGS) $< -o $@
#======================================================================
# Disable autoheader.
AUTOHEADER=echo
# Dependancies.
aiff.c au.c g72x.c ircam.c mat4.c mat5.c nist.c paf.c pvf.c : sndfile.h common.h
raw.c svx.c voc.c w64.c wav.c wav_w64.c htk.c sd2.c rx2.c txw.c : sndfile.h common.h
sds.c wve.c dwd.c ogg.c xi.c sndfile.c common.c file_io.c : sndfile.h common.h
command.c pcm.c ulaw.c alaw.c float32.c double64.c ima_adpcm.c : sndfile.h common.h
ms_adpcm.c gsm610.c dwvw.c vox_adpcm.c interleave.c strings.c : sndfile.h common.h
dither.c : sndfile.h common.h
+1
View File
@@ -30,6 +30,7 @@ _sf_write_double
_sf_strerror
_sf_get_string
_sf_set_string
_sf_version_string
_sf_open_fd
_sf_open_virtual
_sf_write_sync
+2 -1
View File
@@ -1,6 +1,6 @@
; Auto-generated by create_symbols_file.py
LIBRARY sndfile1.dll
LIBRARY sndfile1
INITINSTANCE TERMINSTANCE
CODE PRELOAD MOVEABLE DISCARDABLE
DATA PRELOAD MOVEABLE MULTIPLE NONSHARED
@@ -36,6 +36,7 @@ _sf_write_double @40
_sf_strerror @50
_sf_get_string @60
_sf_set_string @61
_sf_version_string @68
_sf_open_fd @70
_sf_open_virtual @80
_sf_write_sync @90
+424 -258
View File
File diff suppressed because it is too large. Load diff
+966
View File
@@ -0,0 +1,966 @@
/*
** Copyright (C) 2011-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <errno.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
#include "ALAC/alac_codec.h"
#include "ALAC/ALACBitUtilities.h"
#define ALAC_MAX_FRAME_SIZE 8192
#define ALAC_BYTE_BUFFER_SIZE 82000
typedef struct
{ uint32_t current, count, allocated ;
uint32_t packet_size [] ;
} PAKT_INFO ;
typedef struct
{ sf_count_t input_data_pos ;
PAKT_INFO * pakt_info ;
int channels, final_write_block ;
uint32_t frames_this_block, partial_block_frames, frames_per_block ;
uint32_t bits_per_sample, kuki_size ;
/* Can't have a decoder and an encoder at the same time so stick
** them in an un-named union.
*/
union
{ ALAC_DECODER decoder ;
ALAC_ENCODER encoder ;
} ;
char enctmpname [512] ;
FILE *enctmp ;
int buffer [] ;
} ALAC_PRIVATE ;
/*============================================================================================
*/
static int alac_reader_init (SF_PRIVATE *psf, const ALAC_DECODER_INFO * info) ;
static int alac_writer_init (SF_PRIVATE *psf) ;
static sf_count_t alac_reader_calc_frames (SF_PRIVATE *psf, ALAC_PRIVATE *plac) ;
static sf_count_t alac_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len) ;
static sf_count_t alac_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len) ;
static sf_count_t alac_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len) ;
static sf_count_t alac_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len) ;
static sf_count_t alac_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len) ;
static sf_count_t alac_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len) ;
static sf_count_t alac_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len) ;
static sf_count_t alac_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static sf_count_t alac_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
static int alac_close (SF_PRIVATE *psf) ;
static int alac_byterate (SF_PRIVATE *psf) ;
static int alac_decode_block (SF_PRIVATE *psf, ALAC_PRIVATE *plac) ;
static int alac_encode_block (SF_PRIVATE *psf, ALAC_PRIVATE *plac) ;
static uint32_t alac_kuki_read (SF_PRIVATE * psf, uint32_t kuki_offset, uint8_t * kuki, size_t kuki_maxlen) ;
static PAKT_INFO * alac_pakt_alloc (uint32_t initial_count) ;
static PAKT_INFO * alac_pakt_read_decode (SF_PRIVATE * psf, uint32_t pakt_offset) ;
static PAKT_INFO * alac_pakt_append (PAKT_INFO * info, uint32_t value) ;
static uint8_t * alac_pakt_encode (const SF_PRIVATE *psf, uint32_t * pakt_size) ;
static sf_count_t alac_pakt_block_offset (const PAKT_INFO *info, uint32_t block) ;
/*============================================================================================
** ALAC Reader initialisation function.
*/
int
alac_init (SF_PRIVATE *psf, const ALAC_DECODER_INFO * info)
{ int error ;
if ((psf->codec_data = calloc (1, sizeof (ALAC_PRIVATE) + psf->sf.channels * sizeof (int) * ALAC_MAX_FRAME_SIZE)) == NULL)
return SFE_MALLOC_FAILED ;
psf->codec_close = alac_close ;
switch (psf->file.mode)
{ case SFM_RDWR :
return SFE_BAD_MODE_RW ;
case SFM_READ :
if ((error = alac_reader_init (psf, info)))
return error ;
break ;
case SFM_WRITE :
if ((error = alac_writer_init (psf)))
return error ;
break ;
default :
psf_log_printf (psf, "%s : Bad psf->file.mode.\n", __func__) ;
return SFE_INTERNAL ;
} ;
psf->byterate = alac_byterate ;
return 0 ;
} /* aiff_alac_init */
void
alac_get_desc_chunk_items (int subformat, uint32_t *fmt_flags, uint32_t *frames_per_packet)
{ switch (subformat)
{ case SF_FORMAT_ALAC_16 :
*fmt_flags = 1 ;
break ;
case SF_FORMAT_ALAC_20 :
*fmt_flags = 2 ;
break ;
case SF_FORMAT_ALAC_24 :
*fmt_flags = 3 ;
break ;
case SF_FORMAT_ALAC_32 :
*fmt_flags = 4 ;
break ;
default :
break ;
} ;
*frames_per_packet = ALAC_FRAME_LENGTH ;
} /* alac_get_desc_chunk_items */
static int
alac_close (SF_PRIVATE *psf)
{ ALAC_PRIVATE *plac ;
BUF_UNION ubuf ;
plac = psf->codec_data ;
if (psf->file.mode == SFM_WRITE)
{ ALAC_ENCODER *penc = &plac->encoder ;
SF_CHUNK_INFO chunk_info ;
sf_count_t readcount ;
uint32_t pakt_size = 0, saved_partial_block_frames ;
uint8_t *kuki_data = (uint8_t *)malloc (plac->kuki_size);
if (!kuki_data)
{
return SFE_MALLOC_FAILED ;
}
plac->final_write_block = 1 ;
saved_partial_block_frames = plac->partial_block_frames ;
/* If a block has been partially assembled, write it out as the final block. */
if (plac->partial_block_frames && plac->partial_block_frames < plac->frames_per_block)
alac_encode_block (psf, plac) ;
plac->partial_block_frames = saved_partial_block_frames ;
alac_get_magic_cookie (penc, kuki_data, &plac->kuki_size) ;
memset (&chunk_info, 0, sizeof (chunk_info)) ;
chunk_info.id_size = snprintf (chunk_info.id, sizeof (chunk_info.id), "kuki") ;
chunk_info.data = kuki_data ;
chunk_info.datalen = plac->kuki_size ;
psf_save_write_chunk (&psf->wchunks, &chunk_info) ;
memset (&chunk_info, 0, sizeof (chunk_info)) ;
chunk_info.id_size = snprintf (chunk_info.id, sizeof (chunk_info.id), "pakt") ;
chunk_info.data = alac_pakt_encode (psf, &pakt_size) ;
chunk_info.datalen = pakt_size ;
psf_save_write_chunk (&psf->wchunks, &chunk_info) ;
free (chunk_info.data) ;
chunk_info.data = NULL ;
psf->write_header (psf, 1) ;
if (plac->enctmp != NULL)
{ fseek (plac->enctmp, 0, SEEK_SET) ;
while ((readcount = fread (ubuf.ucbuf, 1, sizeof (ubuf.ucbuf), plac->enctmp)) > 0)
psf_fwrite (ubuf.ucbuf, 1, readcount, psf) ;
fclose (plac->enctmp) ;
remove (plac->enctmpname) ;
} ;
free(kuki_data);
} ;
if (plac->pakt_info)
free (plac->pakt_info) ;
plac->pakt_info = NULL ;
return 0 ;
} /* alac_close */
static int
alac_byterate (SF_PRIVATE *psf)
{
if (psf->file.mode == SFM_READ)
return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ;
return -1 ;
} /* alac_byterate */
/*============================================================================================
** ALAC initialisation Functions.
*/
static int
alac_reader_init (SF_PRIVATE *psf, const ALAC_DECODER_INFO * info)
{ ALAC_PRIVATE *plac ;
uint32_t kuki_size ;
union { uint8_t kuki [512] ; uint32_t alignment ; } u ;
if (info == NULL)
{ psf_log_printf (psf, "%s : ALAC_DECODER_INFO is NULL.\n", __func__) ;
return SFE_INTERNAL ;
} ;
plac = psf->codec_data ;
plac->channels = psf->sf.channels ;
plac->frames_per_block = info->frames_per_packet ;
plac->bits_per_sample = info->bits_per_sample ;
if (plac->pakt_info != NULL)
free (plac->pakt_info) ;
plac->pakt_info = alac_pakt_read_decode (psf, info->pakt_offset) ;
if (plac->pakt_info == NULL)
{ psf_log_printf (psf, "%s : alac_pkt_read() returns NULL.\n", __func__) ;
return SFE_MALLOC_FAILED ;
} ;
/* Read in the ALAC cookie data and pass it to the init function. */
kuki_size = alac_kuki_read (psf, info->kuki_offset, u.kuki, sizeof (u.kuki)) ;
alac_decoder_init (&plac->decoder, u.kuki, kuki_size) ;
switch (info->bits_per_sample)
{ case 16 :
case 20 :
case 24 :
case 32 :
psf->read_short = alac_read_s ;
psf->read_int = alac_read_i ;
psf->read_float = alac_read_f ;
psf->read_double = alac_read_d ;
break ;
default :
printf ("%s : info->bits_per_sample %u\n", __func__, info->bits_per_sample) ;
return SFE_UNSUPPORTED_ENCODING ;
} ;
psf->codec_close = alac_close ;
psf->seek = alac_seek ;
psf->sf.frames = alac_reader_calc_frames (psf, plac) ;
alac_seek (psf, SFM_READ, 0) ;
return 0 ;
} /* alac_reader_init */
static int
alac_writer_init (SF_PRIVATE *psf)
{ ALAC_PRIVATE *plac ;
uint32_t alac_format_flags = 0 ;
plac = psf->codec_data ;
if (psf->file.mode != SFM_WRITE)
return SFE_BAD_MODE_RW ;
plac->channels = psf->sf.channels ;
plac->kuki_size = alac_get_magic_cookie_size (psf->sf.channels) ;
psf->write_short = alac_write_s ;
psf->write_int = alac_write_i ;
psf->write_float = alac_write_f ;
psf->write_double = alac_write_d ;
switch (SF_CODEC (psf->sf.format))
{ case SF_FORMAT_ALAC_16 :
alac_format_flags = 1 ;
plac->bits_per_sample = 16 ;
break ;
case SF_FORMAT_ALAC_20 :
alac_format_flags = 2 ;
plac->bits_per_sample = 20 ;
break ;
case SF_FORMAT_ALAC_24 :
alac_format_flags = 3 ;
plac->bits_per_sample = 24 ;
break ;
case SF_FORMAT_ALAC_32 :
alac_format_flags = 4 ;
plac->bits_per_sample = 32 ;
break ;
default :
psf_log_printf (psf, "%s : Can't figure out bits per sample.\n", __func__) ;
return SFE_UNIMPLEMENTED ;
} ;
plac->frames_per_block = ALAC_FRAME_LENGTH ;
plac->pakt_info = alac_pakt_alloc (2000) ;
if ((plac->enctmp = psf_open_tmpfile (plac->enctmpname, sizeof (plac->enctmpname))) == NULL)
{ psf_log_printf (psf, "Error : Failed to open temp file '%s' : \n", plac->enctmpname, strerror (errno)) ;
return SFE_ALAC_FAIL_TMPFILE ;
} ;
alac_encoder_init (&plac->encoder, psf->sf.samplerate, psf->sf.channels, alac_format_flags, ALAC_FRAME_LENGTH) ;
return 0 ;
} /* alac_writer_init */
/*============================================================================================
** ALAC block decoder and encoder.
*/
static inline uint32_t
alac_reader_next_packet_size (PAKT_INFO * info)
{ if (info->current >= info->count)
return 0 ;
return info->packet_size [info->current++] ;
} /* alac_reader_next_packet_size */
static sf_count_t
alac_reader_calc_frames (SF_PRIVATE *psf, ALAC_PRIVATE *plac)
{ sf_count_t frames = 0 ;
uint32_t current_pos = 1, blocks = 0 ;
plac->pakt_info->current = 0 ;
while (current_pos < psf->filelength && current_pos > 0)
{ current_pos = alac_reader_next_packet_size (plac->pakt_info) ;
blocks = current_pos > 0 ? blocks + 1 : blocks ;
} ;
if (blocks == 0)
return 0 ;
/* Only count full blocks. */
frames = plac->frames_per_block * (blocks - 1) ;
alac_seek (psf, SFM_READ, frames) ;
alac_decode_block (psf, plac) ;
frames += plac->frames_this_block ;
plac->pakt_info->current = 0 ;
return frames ;
} /* alac_reader_calc_frames */
static int
alac_decode_block (SF_PRIVATE *psf, ALAC_PRIVATE *plac)
{ ALAC_DECODER *pdec = &plac->decoder ;
uint8_t byte_buffer [ALAC_BYTE_BUFFER_SIZE] ;
uint32_t packet_size ;
BitBuffer bit_buffer ;
packet_size = alac_reader_next_packet_size (plac->pakt_info) ;
if (packet_size == 0)
{ if (plac->pakt_info->current < plac->pakt_info->count)
psf_log_printf (psf, "packet_size is 0 (%d of %d)\n", plac->pakt_info->current, plac->pakt_info->count) ;
return 0 ;
} ;
psf_fseek (psf, plac->input_data_pos, SEEK_SET) ;
if (packet_size > SIGNED_SIZEOF (byte_buffer))
{ psf_log_printf (psf, "%s : bad packet_size (%u)\n", __func__, packet_size) ;
return 0 ;
} ;
if ((packet_size != psf_fread (byte_buffer, 1, packet_size, psf)))
return 0 ;
BitBufferInit (&bit_buffer, byte_buffer, packet_size) ;
plac->input_data_pos += packet_size ;
plac->frames_this_block = 0 ;
alac_decode (pdec, &bit_buffer, plac->buffer, plac->frames_per_block, psf->sf.channels, &plac->frames_this_block) ;
plac->partial_block_frames = 0 ;
return 1 ;
} /* alac_decode_block */
static int
alac_encode_block (SF_PRIVATE * psf, ALAC_PRIVATE *plac)
{ ALAC_ENCODER *penc = &plac->encoder ;
uint32_t num_bytes = 0 ;
uint8_t* byte_buffer = (uint8_t*)malloc (psf->sf.channels * ALAC_BYTE_BUFFER_SIZE) ;
if (!byte_buffer)
{
return SFE_MALLOC_FAILED ;
}
alac_encode (penc, plac->channels, plac->partial_block_frames, plac->buffer, byte_buffer, &num_bytes) ;
if (fwrite (byte_buffer, 1, num_bytes, plac->enctmp) != num_bytes)
{
free (byte_buffer);
return 0 ;
}
free(byte_buffer);
if ((plac->pakt_info = alac_pakt_append (plac->pakt_info, num_bytes)) == NULL)
return 0 ;
plac->partial_block_frames = 0 ;
return 1 ;
} /* alac_encode_block */
/*============================================================================================
** ALAC read functions.
*/
static sf_count_t
alac_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, readcount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
while (len > 0)
{ if (plac->partial_block_frames >= plac->frames_this_block && alac_decode_block (psf, plac) == 0)
break ;
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = iptr [k] >> 16 ;
plac->partial_block_frames += readcount / plac->channels ;
total += readcount ;
len -= readcount ;
} ;
return total ;
} /* alac_read_s */
static sf_count_t
alac_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, readcount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
while (len > 0)
{ if (plac->partial_block_frames >= plac->frames_this_block && alac_decode_block (psf, plac) == 0)
break ;
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = iptr [k] ;
plac->partial_block_frames += readcount / plac->channels ;
total += readcount ;
len -= readcount ;
} ;
return total ;
} /* alac_read_i */
static sf_count_t
alac_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, readcount ;
sf_count_t total = 0 ;
float normfact ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
while (len > 0)
{ if (plac->partial_block_frames >= plac->frames_this_block && alac_decode_block (psf, plac) == 0)
break ;
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * iptr [k] ;
plac->partial_block_frames += readcount / plac->channels ;
total += readcount ;
len -= readcount ;
} ;
return total ;
} /* alac_read_f */
static sf_count_t
alac_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, readcount ;
sf_count_t total = 0 ;
double normfact ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
while (len > 0)
{ if (plac->partial_block_frames >= plac->frames_this_block && alac_decode_block (psf, plac) == 0)
break ;
readcount = (plac->frames_this_block - plac->partial_block_frames) * plac->channels ;
readcount = readcount > len ? len : readcount ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < readcount ; k++)
ptr [total + k] = normfact * iptr [k] ;
plac->partial_block_frames += readcount / plac->channels ;
total += readcount ;
len -= readcount ;
} ;
return total ;
} /* alac_read_d */
/*============================================================================================
*/
static sf_count_t
alac_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
{ ALAC_PRIVATE *plac ;
int newblock, newsample ;
if (! psf->codec_data)
return 0 ;
plac = (ALAC_PRIVATE*) psf->codec_data ;
if (psf->datalength < 0 || psf->dataoffset < 0)
{ psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} ;
if (offset == 0)
{ psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
plac->frames_this_block = 0 ;
plac->input_data_pos = psf->dataoffset ;
plac->pakt_info->current = 0 ;
return 0 ;
} ;
if (offset < 0 || offset > plac->pakt_info->count * plac->frames_per_block)
{ psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} ;
newblock = offset / plac->frames_per_block ;
newsample = offset % plac->frames_per_block ;
if (mode == SFM_READ)
{ plac->input_data_pos = psf->dataoffset + alac_pakt_block_offset (plac->pakt_info, newblock) ;
plac->pakt_info->current = newblock ;
alac_decode_block (psf, plac) ;
plac->partial_block_frames = newsample ;
}
else
{ /* What to do about write??? */
psf->error = SFE_BAD_SEEK ;
return PSF_SEEK_ERROR ;
} ;
return newblock * plac->frames_per_block + newsample ;
} /* alac_seek */
/*==========================================================================================
** ALAC Write Functions.
*/
static sf_count_t
alac_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, writecount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
while (len > 0)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < writecount ; k++)
iptr [k] = ptr [total + k] << 16 ;
plac->partial_block_frames += writecount / plac->channels ;
total += writecount ;
len -= writecount ;
if (plac->partial_block_frames >= plac->frames_per_block)
alac_encode_block (psf, plac) ;
} ;
return total ;
} /* alac_write_s */
static sf_count_t
alac_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
int *iptr ;
int k, writecount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
while (len > 0)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
for (k = 0 ; k < writecount ; k++)
iptr [k] = ptr [total + k] ;
plac->partial_block_frames += writecount / plac->channels ;
total += writecount ;
len -= writecount ;
if (plac->partial_block_frames >= plac->frames_per_block)
alac_encode_block (psf, plac) ;
} ;
return total ;
} /* alac_write_i */
static sf_count_t
alac_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
void (*convert) (const float *, int *t, int, int) ;
int *iptr ;
int writecount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
convert = (psf->add_clipping) ? psf_f2i_clip_array : psf_f2i_array ;
while (len > 0)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
convert (ptr, iptr, writecount, psf->norm_float) ;
plac->partial_block_frames += writecount / plac->channels ;
total += writecount ;
len -= writecount ;
if (plac->partial_block_frames >= plac->frames_per_block)
alac_encode_block (psf, plac) ;
} ;
return total ;
} /* alac_write_f */
static sf_count_t
alac_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ ALAC_PRIVATE *plac ;
void (*convert) (const double *, int *t, int, int) ;
int *iptr ;
int writecount ;
sf_count_t total = 0 ;
if ((plac = (ALAC_PRIVATE*) psf->codec_data) == NULL)
return 0 ;
convert = (psf->add_clipping) ? psf_d2i_clip_array : psf_d2i_array ;
while (len > 0)
{ writecount = (plac->frames_per_block - plac->partial_block_frames) * plac->channels ;
writecount = (writecount == 0 || writecount > len) ? len : writecount ;
iptr = plac->buffer + plac->partial_block_frames * plac->channels ;
convert (ptr, iptr, writecount, psf->norm_float) ;
plac->partial_block_frames += writecount / plac->channels ;
total += writecount ;
len -= writecount ;
if (plac->partial_block_frames >= plac->frames_per_block)
alac_encode_block (psf, plac) ;
} ;
return total ;
} /* alac_write_d */
/*==============================================================================
** PAKT_INFO handling.
*/
static PAKT_INFO *
alac_pakt_alloc (uint32_t initial_count)
{ PAKT_INFO * info ;
if ((info = calloc (1, sizeof (PAKT_INFO) + initial_count * sizeof (info->packet_size [0]))) == NULL)
return NULL ;
info->allocated = initial_count ;
info->current = 0 ;
info->count = 0 ;
return info ;
} /* alac_pakt_alloc */
static PAKT_INFO *
alac_pakt_append (PAKT_INFO * info, uint32_t value)
{
if (info->count >= info->allocated)
{ PAKT_INFO * temp ;
uint32_t newcount = info->allocated + info->allocated / 2 ;
if ((temp = realloc (info, sizeof (PAKT_INFO) + newcount * sizeof (info->packet_size [0]))) == NULL)
return NULL ;
info = temp ;
info->allocated = newcount ;
} ;
info->packet_size [info->count++] = value ;
return info ;
} /* alac_pakt_append */
static PAKT_INFO *
alac_pakt_read_decode (SF_PRIVATE * psf, uint32_t UNUSED (pakt_offset))
{ SF_CHUNK_INFO chunk_info ;
PAKT_INFO * info = NULL ;
uint8_t *pakt_data = NULL ;
uint32_t bcount, value = 1, pakt_size ;
SF_CHUNK_ITERATOR * chunk_iterator ;
memset (&chunk_info, 0, sizeof (chunk_info)) ;
snprintf (chunk_info.id, sizeof (chunk_info.id), "pakt") ;
chunk_info.id_size = 4 ;
if ((chunk_iterator = psf_get_chunk_iterator (psf, chunk_info.id)) == NULL)
{ printf ("%s %d : no chunk iterator found\n\n", __func__, __LINE__) ;
free (chunk_info.data) ;
chunk_info.data = NULL ;
return NULL ;
} ;
psf->get_chunk_size (psf, chunk_iterator, &chunk_info) ;
pakt_size = chunk_info.datalen ;
chunk_info.data = pakt_data = malloc (pakt_size + 5) ;
if ((bcount = psf->get_chunk_data (psf, chunk_iterator, &chunk_info)) != SF_ERR_NO_ERROR)
{ printf ("%s %d : %s\n\n", __func__, __LINE__, sf_error_number (bcount)) ;
while (chunk_iterator)
chunk_iterator = psf->next_chunk_iterator (psf, chunk_iterator) ;
free (chunk_info.data) ;
chunk_info.data = NULL ;
return NULL ;
} ;
while (chunk_iterator)
chunk_iterator = psf->next_chunk_iterator (psf, chunk_iterator) ;
info = alac_pakt_alloc (pakt_size / 4) ;
/* Start at 24 bytes in, skipping over the 'pakt' chunks header. */
for (bcount = 24 ; bcount < pakt_size && value != 0 ; )
{ uint8_t byte ;
int32_t count = 0 ;
value = 0 ;
do
{ byte = pakt_data [bcount + count] ;
value = (value << 7) + (byte & 0x7F) ;
count ++ ;
if (count > 5 || bcount + count > pakt_size)
{ printf ("%s %d : Ooops! count %d bcount %d\n", __func__, __LINE__, count, bcount) ;
value = 0 ;
break ;
} ;
}
while (byte & 0x80) ;
bcount += count ;
if ((info = alac_pakt_append (info, value)) == NULL)
goto FreeExit ;
} ;
free (pakt_data) ;
return info ;
FreeExit :
free (pakt_data) ;
free (info) ;
return NULL ;
} /* alac_pakt_read_decode */
static uint8_t *
alac_pakt_encode (const SF_PRIVATE *psf, uint32_t * pakt_size_out)
{ const ALAC_PRIVATE *plac ;
const PAKT_INFO *info ;
uint8_t *data ;
uint32_t k, allocated, pakt_size ;
plac = psf->codec_data ;
info = plac->pakt_info ;
allocated = 100 + 2 * info->count ;
if ((data = calloc (1, allocated)) == NULL)
return NULL ;
psf_put_be64 (data, 0, info->count) ;
psf_put_be64 (data, 8, psf->sf.frames) ;
psf_put_be32 (data, 20, kALACDefaultFramesPerPacket - plac->partial_block_frames) ;
/* Real 'pakt' data starts after 24 byte header. */
pakt_size = 24 ;
for (k = 0 ; k < info->count ; k++)
{ int32_t value = info->packet_size [k] ;
if ((value & 0x7f) == value)
{ data [pakt_size++] = value ;
continue ;
} ;
if ((value & 0x3fff) == value)
{ data [pakt_size++] = (value >> 7) | 0x80 ;
data [pakt_size++] = value & 0x7f ;
continue ;
} ;
if ((value & 0x1fffff) == value)
{ data [pakt_size++] = (value >> 14) | 0x80 ;
data [pakt_size++] = ((value >> 7) & 0x7f) | 0x80 ;
data [pakt_size++] = value & 0x7f ;
continue ;
} ;
if ((value & 0x0fffffff) == value)
{ data [pakt_size++] = (value >> 21) | 0x80 ;
data [pakt_size++] = ((value >> 14) & 0x7f) | 0x80 ;
data [pakt_size++] = ((value >> 7) & 0x7f) | 0x80 ;
data [pakt_size++] = value & 0x7f ;
continue ;
} ;
*pakt_size_out = 0 ;
free (data) ;
return NULL ;
} ;
*pakt_size_out = pakt_size ;
return data ;
} /* alac_pakt_encode */
static sf_count_t
alac_pakt_block_offset (const PAKT_INFO *info, uint32_t block)
{ sf_count_t offset = 0 ;
uint32_t k ;
for (k = 0 ; k < block ; k++)
offset += info->packet_size [k] ;
return offset ;
} /* alac_pakt_block_offset */
static uint32_t
alac_kuki_read (SF_PRIVATE * psf, uint32_t kuki_offset, uint8_t * kuki, size_t kuki_maxlen)
{ uint32_t marker ;
uint64_t kuki_size ;
if (psf_fseek (psf, kuki_offset, SEEK_SET) != kuki_offset)
return 0 ;
psf_fread (&marker, 1, sizeof (marker), psf) ;
if (marker != MAKE_MARKER ('k', 'u', 'k', 'i'))
return 0 ;
psf_fread (&kuki_size, 1, sizeof (kuki_size), psf) ;
kuki_size = BE2H_64 (kuki_size) ;
if (kuki_size == 0 || kuki_size > kuki_maxlen)
{ psf_log_printf (psf, "%s : Bad size (%D) of 'kuki' chunk.\n", __func__, kuki_size) ;
return 0 ;
} ;
psf_fread (kuki, 1, kuki_size, psf) ;
return kuki_size ;
} /* alac_kuki_read */
+45 -37
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -47,14 +47,14 @@ static void d2alaw_array (const double *buffer, int count, unsigned char *ptr, d
int
alaw_init (SF_PRIVATE *psf)
{
if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ psf->read_short = alaw_read_alaw2s ;
psf->read_int = alaw_read_alaw2i ;
psf->read_float = alaw_read_alaw2f ;
psf->read_double = alaw_read_alaw2d ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->write_short = alaw_write_s2alaw ;
psf->write_int = alaw_write_i2alaw ;
psf->write_float = alaw_write_f2alaw ;
@@ -69,7 +69,7 @@ alaw_init (SF_PRIVATE *psf)
else
psf->datalength = 0 ;
psf->sf.frames = psf->datalength / psf->blockwidth ;
psf->sf.frames = psf->blockwidth > 0 ? psf->datalength / psf->blockwidth : 0 ;
return 0 ;
} /* alaw_init */
@@ -286,7 +286,7 @@ unsigned char alaw_encode [2048 + 1] =
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x2a
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
} ; /* alaw_encode */
static inline void
@@ -358,16 +358,17 @@ d2alaw_array (const double *ptr, int count, unsigned char *buffer, double normfa
static sf_count_t
alaw_read_alaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
bufferlen = ARRAY_LEN (ubuf.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
alaw2s_array (psf->u.ucbuf, readcount, ptr + total) ;
readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
alaw2s_array (ubuf.ucbuf, readcount, ptr + total) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -379,16 +380,17 @@ alaw_read_alaw2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
static sf_count_t
alaw_read_alaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
bufferlen = ARRAY_LEN (ubuf.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
alaw2i_array (psf->u.ucbuf, readcount, ptr + total) ;
readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
alaw2i_array (ubuf.ucbuf, readcount, ptr + total) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -400,19 +402,20 @@ alaw_read_alaw2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
alaw_read_alaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
float normfact ;
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
bufferlen = ARRAY_LEN (ubuf.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
alaw2f_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
alaw2f_array (ubuf.ucbuf, readcount, ptr + total, normfact) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -424,18 +427,19 @@ alaw_read_alaw2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
alaw_read_alaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
double normfact ;
normfact = (psf->norm_double) ? 1.0 / ((double) 0x8000) : 1.0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
bufferlen = ARRAY_LEN (ubuf.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.ucbuf, 1, bufferlen, psf) ;
alaw2d_array (psf->u.ucbuf, readcount, ptr + total, normfact) ;
readcount = psf_fread (ubuf.ucbuf, 1, bufferlen, psf) ;
alaw2d_array (ubuf.ucbuf, readcount, ptr + total, normfact) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -450,16 +454,17 @@ alaw_read_alaw2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
static sf_count_t
alaw_write_s2alaw (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
bufferlen = ARRAY_LEN (ubuf.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
s2alaw_array (ptr + total, bufferlen, psf->u.ucbuf) ;
writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
s2alaw_array (ptr + total, bufferlen, ubuf.ucbuf) ;
writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -471,16 +476,17 @@ alaw_write_s2alaw (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
static sf_count_t
alaw_write_i2alaw (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
bufferlen = ARRAY_LEN (ubuf.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
i2alaw_array (ptr + total, bufferlen, psf->u.ucbuf) ;
writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
i2alaw_array (ptr + total, bufferlen, ubuf.ucbuf) ;
writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -492,19 +498,20 @@ alaw_write_i2alaw (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
alaw_write_f2alaw (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
float normfact ;
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) / 16.0 : 1.0 / 16 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
bufferlen = ARRAY_LEN (ubuf.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
f2alaw_array (ptr + total, bufferlen, psf->u.ucbuf, normfact) ;
writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
f2alaw_array (ptr + total, bufferlen, ubuf.ucbuf, normfact) ;
writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -516,19 +523,20 @@ alaw_write_f2alaw (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
alaw_write_d2alaw (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
double normfact ;
normfact = (psf->norm_double) ? (1.0 * 0x7FFF) / 16.0 : 1.0 / 16.0 ;
bufferlen = ARRAY_LEN (psf->u.ucbuf) ;
bufferlen = ARRAY_LEN (ubuf.ucbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
d2alaw_array (ptr + total, bufferlen, psf->u.ucbuf, normfact) ;
writecount = psf_fwrite (psf->u.ucbuf, 1, bufferlen, psf) ;
d2alaw_array (ptr + total, bufferlen, ubuf.ucbuf, normfact) ;
writecount = psf_fwrite (ubuf.ucbuf, 1, bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
+6 -8
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -81,8 +81,8 @@ typedef struct
{ int dataoffset ;
int datasize ;
int encoding ;
int samplerate ;
int channels ;
int samplerate ;
int channels ;
} AU_FMT ;
@@ -106,7 +106,7 @@ au_open (SF_PRIVATE *psf)
{ int subformat ;
int error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = au_read_header (psf)))
return error ;
} ;
@@ -116,7 +116,7 @@ au_open (SF_PRIVATE *psf)
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->endian = SF_ENDIAN (psf->sf.format) ;
if (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU)
psf->endian = SF_ENDIAN_LITTLE ;
@@ -189,7 +189,7 @@ au_open (SF_PRIVATE *psf)
static int
au_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
au_write_header (psf, SF_TRUE) ;
return 0 ;
@@ -211,8 +211,6 @@ au_write_header (SF_PRIVATE *psf, int calc_length)
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->dataend)
psf->datalength -= psf->filelength - psf->dataend ;
psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
} ;
encoding = au_format_to_encoding (SF_CODEC (psf->sf.format)) ;
+2 -2
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -60,7 +60,7 @@ audio_detect (SF_PRIVATE * psf, AUDIO_DETECT *ad, const unsigned char * data, in
" be_int_24_32 : %d\n",
vote.le_float, vote.be_float, vote.le_int_24_32, vote.be_int_24_32) ;
if (0) puts (psf->logbuffer) ;
if (0) puts (psf->parselog.buf) ;
if (ad->endianness == SF_ENDIAN_LITTLE && vote.le_float > (3 * datalen) / 4)
{ /* Almost certainly 32 bit floats. */
+5 -6
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2004-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2004-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -80,7 +80,7 @@ int
avr_open (SF_PRIVATE *psf)
{ int error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = avr_read_header (psf)))
return error ;
} ;
@@ -88,9 +88,8 @@ avr_open (SF_PRIVATE *psf)
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_AVR)
return SFE_BAD_OPEN_FORMAT ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ psf->endian = SF_ENDIAN (psf->sf.format) ;
psf->endian = SF_ENDIAN_BIG ;
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->endian = SF_ENDIAN_BIG ;
if (avr_write_header (psf, SF_FALSE))
return psf->error ;
@@ -239,7 +238,7 @@ avr_write_header (SF_PRIVATE *psf, int calc_length)
static int
avr_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
avr_write_header (psf, SF_TRUE) ;
return 0 ;
+18 -17
View File
@@ -1,6 +1,6 @@
#!/usr/bin/python2.5
#!/usr/bin/python
# Copyright (C) 2006 Erik de Castro Lopo <erikd@mega-nerd.com>
# Copyright (C) 2006-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
#
# All rights reserved.
#
@@ -48,19 +48,19 @@ def find_binheader_writefs (data):
def find_format_string (s):
fmt = re.search ('"([^"]+)"', s)
if not fmt:
print "Bad format in :\n\n\t%s\n\n" % s
print ("Bad format in :\n\n\t%s\n\n" % s)
sys.exit (1)
fmt = fmt.groups ()
if len (fmt) != 1:
print "Bad format in :\n\n\t%s\n\n" % s
print ("Bad format in :\n\n\t%s\n\n" % s)
sys.exit (1)
return _whitespace_re.sub ("", fmt [0])
def get_param_list (data):
dlist = re.search ("\((.+)\)\s*;", data)
dlist = dlist.groups ()[0]
dlist = string.split (dlist, ",")
dlist = [string.strip (x) for x in dlist]
dlist = dlist.split(",")
dlist = [x.strip() for x in dlist]
return dlist [2:]
def handle_file (fname):
@@ -88,29 +88,30 @@ def handle_file (fname):
# print item
# print " param [%d] %c : %s <-> %s" % (param_index, ch, params [param_index], params [param_index + 1])
if string.find (params [param_index + 1], "sizeof") < 0 \
and string.find (params [param_index + 1], "make_size_t") < 0 \
and string.find (params [param_index + 1], "strlen") < 0:
if errors == 0: print
print "\n%s :" % fname
print " param [%d] %c : %s <-> %s" % (param_index, ch, params [param_index], params [param_index + 1])
print " %s" % item
# print (params [param_index + 1])
if params [param_index + 1].find ("sizeof") < 0 \
and params [param_index + 1].find ("make_size_t") < 0 \
and params [param_index + 1].find ("strlen") < 0:
if errors == 0: sys.stdout.write ("\n")
print ("\n%s :" % fname)
print (" param [%d] %c : %s <-> %s" % (param_index, ch, params [param_index], params [param_index + 1]))
print (" %s" % item)
errors += 1
param_index += 2
return errors
#===============================================================================
if len (sys.argv) > 1:
print "%s\n binheader_writef_check :" % sys.argv [0],
sys.stdout.write ("\n binheader_writef_check :")
sys.stdout.flush ()
errors = 0
for fname in sys.argv [1:]:
errors += handle_file (fname)
if errors > 0:
print "\nErrors : %d\n" % errors
print ("\nErrors : %d\n" % errors)
sys.exit (1)
print "ok"
print ("ok\n")
+47 -94
View File
@@ -1,6 +1,6 @@
/*
** Copyright (C) 2006-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2006 Paul Davis <paul@linuxaudiosystems.com>
** Copyright (C) 2006-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -17,13 +17,15 @@
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include "common.h"
static void strncpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax) ;
static int gen_coding_history (char * added_history, int added_history_max, const SF_INFO * psfinfo) ;
static inline size_t
@@ -32,29 +34,16 @@ bc_min_size (const SF_BROADCAST_INFO* info)
return 0 ;
return offsetof (SF_BROADCAST_INFO, coding_history) + info->coding_history_size ;
} /* broadcast_size */
} /* bc_min_size */
static inline size_t
bc_var_coding_hist_size (const SF_BROADCAST_VAR* var)
{ return var->size - offsetof (SF_BROADCAST_VAR, binfo.coding_history) ;
} /* broadcast_size */
SF_BROADCAST_VAR*
broadcast_var_alloc (size_t datasize)
{ SF_BROADCAST_VAR * data ;
if ((data = calloc (1, datasize)) != NULL)
data->size = datasize ;
return data ;
SF_BROADCAST_INFO_16K*
broadcast_var_alloc (void)
{ return calloc (1, sizeof (SF_BROADCAST_INFO_16K)) ;
} /* broadcast_var_alloc */
int
broadcast_var_set (SF_PRIVATE *psf, const SF_BROADCAST_INFO * info, size_t datasize)
{ char added_history [256] ;
int added_history_len, len ;
{ size_t len ;
if (info == NULL)
return SF_FALSE ;
@@ -64,42 +53,41 @@ broadcast_var_set (SF_PRIVATE *psf, const SF_BROADCAST_INFO * info, size_t datas
return SF_FALSE ;
} ;
added_history_len = gen_coding_history (added_history, sizeof (added_history), &(psf->sf)) ;
if (datasize >= sizeof (SF_BROADCAST_INFO_16K))
{ psf->error = SFE_BAD_BROADCAST_INFO_TOO_BIG ;
return SF_FALSE ;
} ;
if (psf->broadcast_var != NULL)
{ size_t coding_hist_offset = offsetof (SF_BROADCAST_INFO, coding_history) ;
if (psf->broadcast_var->binfo.coding_history_size + added_history_len < datasize - coding_hist_offset)
{ free (psf->broadcast_var) ;
psf->broadcast_var = NULL ;
if (psf->broadcast_16k == NULL)
{ if ((psf->broadcast_16k = broadcast_var_alloc ()) == NULL)
{ psf->error = SFE_MALLOC_FAILED ;
return SF_FALSE ;
} ;
} ;
if (psf->broadcast_var == NULL)
{ int size = datasize + added_history_len + 512 ;
/* Only copy the first part of the struct. */
memcpy (psf->broadcast_16k, info, offsetof (SF_BROADCAST_INFO, coding_history)) ;
psf->broadcast_var = calloc (1, size) ;
psf->broadcast_var->size = size ;
psf_strlcpy_crlf (psf->broadcast_16k->coding_history, info->coding_history, sizeof (psf->broadcast_16k->coding_history), datasize - offsetof (SF_BROADCAST_INFO, coding_history)) ;
len = strlen (psf->broadcast_16k->coding_history) ;
if (len > 0 && psf->broadcast_16k->coding_history [len - 1] != '\n')
psf_strlcat (psf->broadcast_16k->coding_history, sizeof (psf->broadcast_16k->coding_history), "\r\n") ;
if (psf->file.mode == SFM_WRITE)
{ char added_history [256] ;
gen_coding_history (added_history, sizeof (added_history), &(psf->sf)) ;
psf_strlcat (psf->broadcast_16k->coding_history, sizeof (psf->broadcast_16k->coding_history), added_history) ;
} ;
memcpy (&(psf->broadcast_var->binfo), info, offsetof (SF_BROADCAST_INFO, coding_history)) ;
strncpy_crlf (psf->broadcast_var->binfo.coding_history, info->coding_history, bc_var_coding_hist_size (psf->broadcast_var), info->coding_history_size) ;
len = strlen (psf->broadcast_var->binfo.coding_history) ;
if (len > 0 && psf->broadcast_var->binfo.coding_history [len] != '\n')
strncat (psf->broadcast_var->binfo.coding_history, "\r\n", 2) ;
if (psf->mode == SFM_WRITE)
strncat (psf->broadcast_var->binfo.coding_history, added_history, strlen (added_history)) ;
psf->broadcast_var->binfo.coding_history_size = strlen (psf->broadcast_var->binfo.coding_history) ;
/* Fore coding_history_size to be even. */
psf->broadcast_var->binfo.coding_history_size += (psf->broadcast_var->binfo.coding_history_size & 1) ? 1 : 0 ;
/* Force coding_history_size to be even. */
len = strlen (psf->broadcast_16k->coding_history) ;
len += (len & 1) ? 1 : 0 ;
psf->broadcast_16k->coding_history_size = len ;
/* Currently writing this version. */
psf->broadcast_var->binfo.version = 1 ;
psf->broadcast_16k->version = 1 ;
return SF_TRUE ;
} /* broadcast_var_set */
@@ -109,54 +97,19 @@ int
broadcast_var_get (SF_PRIVATE *psf, SF_BROADCAST_INFO * data, size_t datasize)
{ size_t size ;
if (psf->broadcast_var == NULL)
if (psf->broadcast_16k == NULL)
return SF_FALSE ;
size = SF_MIN (datasize, bc_min_size (&(psf->broadcast_var->binfo))) ;
size = SF_MIN (datasize, bc_min_size ((const SF_BROADCAST_INFO *) psf->broadcast_16k)) ;
memcpy (data, &(psf->broadcast_var->binfo), size) ;
memcpy (data, psf->broadcast_16k, size) ;
return SF_TRUE ;
} /* broadcast_var_set */
} /* broadcast_var_get */
/*------------------------------------------------------------------------------
** Strncpy which converts all line endings to CR/LF.
*/
static void
strncpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax)
{ char * destend = dest + destmax - 1 ;
const char * srcend = src + srcmax ;
while (dest < destend && src < srcend)
{ if ((src [0] == '\r' && src [1] == '\n') || (src [0] == '\n' && src [1] == '\r'))
{ *dest++ = '\r' ;
*dest++ = '\n' ;
src += 2 ;
continue ;
} ;
if (src [0] == '\r')
{ *dest++ = '\r' ;
*dest++ = '\n' ;
src += 1 ;
continue ;
} ;
if (src [0] == '\n')
{ *dest++ = '\r' ;
*dest++ = '\n' ;
src += 1 ;
continue ;
} ;
*dest++ = *src++ ;
} ;
/* Make sure dest is terminated. */
*dest = 0 ;
} /* strncpy_crlf */
static int
gen_coding_history (char * added_history, int added_history_max, const SF_INFO * psfinfo)
{ char chnstr [16] ;
@@ -168,16 +121,16 @@ gen_coding_history (char * added_history, int added_history_max, const SF_INFO *
** Parameter Variable string <allowed option> Unit
** ==========================================================================================
** Coding Algorithm A=<ANALOGUE, PCM, MPEG1L1, MPEG1L2, MPEG1L3,
** MPEG2L1, MPEG2L2, MPEG2L3>
** MPEG2L1, MPEG2L2, MPEG2L3>
** Sampling frequency F=<11000,22050,24000,32000,44100,48000> [Hz]
** Bit-rate B=<any bit-rate allowed in MPEG 2 (ISO/IEC [kbit/s per channel]
** 13818-3)>
** 13818-3)>
** Word Length W=<8, 12, 14, 16, 18, 20, 22, 24> [bits]
** Mode M=<mono, stereo, dual-mono, joint-stereo>
** Text, free string T=<a free ASCII-text string for in house use.
** This string should contain no commas (ASCII
** 2Chex). Examples of the contents: ID-No; codec
** type; A/D type>
** This string should contain no commas (ASCII
** 2Chex). Examples of the contents: ID-No; codec
** type; A/D type>
*/
switch (psfinfo->channels)
@@ -185,11 +138,11 @@ gen_coding_history (char * added_history, int added_history_max, const SF_INFO *
return SF_FALSE ;
case 1 :
strncpy (chnstr, "mono", sizeof (chnstr)) ;
psf_strlcpy (chnstr, sizeof (chnstr), "mono") ;
break ;
case 2 :
strncpy (chnstr, "stereo", sizeof (chnstr)) ;
psf_strlcpy (chnstr, sizeof (chnstr), "stereo") ;
break ;
default :
@@ -227,7 +180,7 @@ gen_coding_history (char * added_history, int added_history_max, const SF_INFO *
} ;
count = snprintf (added_history, added_history_max,
"A=PCM,F=%u,W=%hu,M=%s,T=%s-%s\r\n",
"A=PCM,F=%u,W=%d,M=%s,T=%s-%s\r\n",
psfinfo->samplerate, width, chnstr, PACKAGE, VERSION) ;
if (count >= added_history_max)
+337 -69
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2005-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2005-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -23,10 +23,14 @@
#include <string.h>
#include <ctype.h>
#include <math.h>
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
#include "chanmap.h"
/*------------------------------------------------------------------------------
** Macros to handle big/little endian issues.
@@ -73,15 +77,21 @@
*/
typedef struct
{ unsigned char srate [8] ;
unsigned int fmt_id ;
unsigned int fmt_flags ;
unsigned int pkt_bytes ;
unsigned int pkt_frames ;
unsigned int channels_per_frame ;
unsigned int bits_per_chan ;
{ uint8_t srate [8] ;
uint32_t fmt_id ;
uint32_t fmt_flags ;
uint32_t pkt_bytes ;
uint32_t frames_per_packet ;
uint32_t channels_per_frame ;
uint32_t bits_per_chan ;
} DESC_CHUNK ;
typedef struct
{ int chanmap_tag ;
ALAC_DECODER_INFO alac ;
} CAF_PRIVATE ;
/*------------------------------------------------------------------------------
** Private static functions.
*/
@@ -89,6 +99,13 @@ typedef struct
static int caf_close (SF_PRIVATE *psf) ;
static int caf_read_header (SF_PRIVATE *psf) ;
static int caf_write_header (SF_PRIVATE *psf, int calc_length) ;
static int caf_command (SF_PRIVATE *psf, int command, void *data, int datasize) ;
static int caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size) ;
static int caf_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info) ;
static SF_CHUNK_ITERATOR * caf_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator) ;
static int caf_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ;
static int caf_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ;
/*------------------------------------------------------------------------------
** Public function.
@@ -96,16 +113,26 @@ static int caf_write_header (SF_PRIVATE *psf, int calc_length) ;
int
caf_open (SF_PRIVATE *psf)
{ int subformat, format, error = 0 ;
{ CAF_PRIVATE * pcaf ;
int subformat, format, error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if ((psf->container_data = calloc (1, sizeof (CAF_PRIVATE))) == NULL)
return SFE_MALLOC_FAILED ;
pcaf = psf->container_data ;
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = caf_read_header (psf)))
return error ;
psf->next_chunk_iterator = caf_next_chunk_iterator ;
psf->get_chunk_size = caf_get_chunk_size ;
psf->get_chunk_data = caf_get_chunk_data ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
@@ -115,20 +142,20 @@ caf_open (SF_PRIVATE *psf)
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
if (psf->mode != SFM_RDWR || psf->filelength < 44)
if (psf->file.mode != SFM_RDWR || psf->filelength < 44)
{ psf->filelength = 0 ;
psf->datalength = 0 ;
psf->dataoffset = 0 ;
psf->sf.frames = 0 ;
} ;
psf->str_flags = SF_STR_ALLOW_START ;
psf->strings.flags = SF_STR_ALLOW_START ;
/*
** By default, add the peak chunk to floating point files. Default behaviour
** can be switched off using sf_command (SFC_SET_PEAK_CHUNK, SF_FALSE).
*/
if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
if (psf->file.mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
{ if ((psf->peak_info = peak_info_calloc (psf->sf.channels)) == NULL)
return SFE_MALLOC_FAILED ;
psf->peak_info->peak_loc = SF_PEAK_START ;
@@ -137,11 +164,12 @@ caf_open (SF_PRIVATE *psf)
if ((error = caf_write_header (psf, SF_FALSE)) != 0)
return error ;
psf->write_header = caf_write_header ;
psf->write_header = caf_write_header ;
psf->set_chunk = caf_set_chunk ;
} ;
psf->container_close = caf_close ;
/*psf->command = caf_command ;*/
psf->command = caf_command ;
switch (subformat)
{ case SF_FORMAT_PCM_S8 :
@@ -167,6 +195,18 @@ caf_open (SF_PRIVATE *psf)
case SF_FORMAT_DOUBLE :
error = double64_init (psf) ;
break ;
case SF_FORMAT_ALAC_16 :
case SF_FORMAT_ALAC_20 :
case SF_FORMAT_ALAC_24 :
case SF_FORMAT_ALAC_32 :
if (psf->file.mode == SFM_READ)
/* Only pass the ALAC_DECODER_INFO in read mode. */
error = alac_init (psf, &pcaf->alac) ;
else
error = alac_init (psf, NULL) ;
break ;
/* Lite remove end */
default :
@@ -179,22 +219,72 @@ caf_open (SF_PRIVATE *psf)
static int
caf_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
caf_write_header (psf, SF_TRUE) ;
return 0 ;
} /* caf_close */
static int
caf_command (SF_PRIVATE * psf, int command, void * UNUSED (data), int UNUSED (datasize))
{ CAF_PRIVATE *pcaf ;
if ((pcaf = psf->container_data) == NULL)
return SFE_INTERNAL ;
switch (command)
{ case SFC_SET_CHANNEL_MAP_INFO :
pcaf->chanmap_tag = aiff_caf_find_channel_layout_tag (psf->channel_map, psf->sf.channels) ;
return (pcaf->chanmap_tag != 0) ;
default :
break ;
} ;
return 0 ;
} /* caf_command */
/*------------------------------------------------------------------------------
*/
static int
decode_desc_chunk (SF_PRIVATE *psf, const DESC_CHUNK *desc)
{ int format ;
{ int format = SF_FORMAT_CAF ;
psf->sf.channels = desc->channels_per_frame ;
format = SF_FORMAT_CAF | (psf->endian == SF_ENDIAN_LITTLE ? SF_ENDIAN_LITTLE : 0) ;
if (desc->fmt_id == alac_MARKER)
{ CAF_PRIVATE *pcaf ;
if ((pcaf = psf->container_data) != NULL)
{ switch (desc->fmt_flags)
{ case 1 :
pcaf->alac.bits_per_sample = 16 ;
format |= SF_FORMAT_ALAC_16 ;
break ;
case 2 :
pcaf->alac.bits_per_sample = 20 ;
format |= SF_FORMAT_ALAC_20 ;
break ;
case 3 :
pcaf->alac.bits_per_sample = 24 ;
format |= SF_FORMAT_ALAC_24 ;
break ;
case 4 :
pcaf->alac.bits_per_sample = 32 ;
format |= SF_FORMAT_ALAC_32 ;
break ;
default :
psf_log_printf (psf, "Bad ALAC format flag value of %d\n", desc->fmt_flags) ;
} ;
pcaf->alac.frames_per_packet = desc->frames_per_packet ;
} ;
return format ;
} ;
format |= psf->endian == SF_ENDIAN_LITTLE ? SF_ENDIAN_LITTLE : 0 ;
if (desc->fmt_id == lpcm_MARKER && desc->fmt_flags & 1)
{ /* Floating point data. */
@@ -208,12 +298,7 @@ decode_desc_chunk (SF_PRIVATE *psf, const DESC_CHUNK *desc)
} ;
} ;
if ((desc->fmt_flags & 1) != 0)
{ psf_log_printf (psf, "**** Ooops, 'desc' chunk suggests float data, but other info invalid.\n") ;
return 0 ;
} ;
if (desc->fmt_id == lpcm_MARKER)
if (desc->fmt_id == lpcm_MARKER && (desc->fmt_flags & 1) == 0)
{ /* Integer data. */
if (desc->bits_per_chan == 32 && desc->pkt_bytes == 4 * desc->channels_per_frame)
{ psf->bytewidth = 4 ;
@@ -243,16 +328,23 @@ decode_desc_chunk (SF_PRIVATE *psf, const DESC_CHUNK *desc)
return format | SF_FORMAT_ULAW ;
} ;
psf_log_printf (psf, "**** Unknown format identifier.\n") ;
return 0 ;
} /* decode_desc_chunk */
static int
caf_read_header (SF_PRIVATE *psf)
{ DESC_CHUNK desc ;
{ CAF_PRIVATE *pcaf ;
BUF_UNION ubuf ;
DESC_CHUNK desc ;
sf_count_t chunk_size ;
double srate ;
short version, flags ;
int marker, k, have_data = 0 ;
int marker, k, have_data = 0, error ;
if ((pcaf = psf->container_data) == NULL)
return SFE_INTERNAL ;
memset (&desc, 0, sizeof (desc)) ;
@@ -262,10 +354,10 @@ caf_read_header (SF_PRIVATE *psf)
if (marker != caff_MARKER)
return SFE_CAF_NOT_CAF ;
psf_binheader_readf (psf, "mE8b", &marker, &chunk_size, psf->u.ucbuf, 8) ;
srate = double64_be_read (psf->u.ucbuf) ;
snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), "%5.3f", srate) ;
psf_log_printf (psf, "%M : %D\n Sample rate : %s\n", marker, chunk_size, psf->u.cbuf) ;
psf_binheader_readf (psf, "mE8b", &marker, &chunk_size, ubuf.ucbuf, 8) ;
srate = double64_be_read (ubuf.ucbuf) ;
snprintf (ubuf.cbuf, sizeof (ubuf.cbuf), "%5.3f", srate) ;
psf_log_printf (psf, "%M : %D\n Sample rate : %s\n", marker, chunk_size, ubuf.cbuf) ;
if (marker != desc_MARKER)
return SFE_CAF_NO_DESC ;
@@ -276,13 +368,13 @@ caf_read_header (SF_PRIVATE *psf)
psf->sf.samplerate = lrint (srate) ;
psf_binheader_readf (psf, "mE44444", &desc.fmt_id, &desc.fmt_flags, &desc.pkt_bytes, &desc.pkt_frames,
psf_binheader_readf (psf, "mE44444", &desc.fmt_id, &desc.fmt_flags, &desc.pkt_bytes, &desc.frames_per_packet,
&desc.channels_per_frame, &desc.bits_per_chan) ;
psf_log_printf (psf, " Format id : %M\n Format flags : %x\n Bytes / packet : %u\n"
" Frames / packet : %u\n Channels / frame : %u\n Bits / channel : %u\n",
desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.frames_per_packet, desc.channels_per_frame, desc.bits_per_chan) ;
if (desc.channels_per_frame > 200)
if (desc.channels_per_frame > SF_MAX_CHANNELS)
{ psf_log_printf (psf, "**** Bad channels per frame value %u.\n", desc.channels_per_frame) ;
return SFE_MALFORMED_FILE ;
} ;
@@ -292,14 +384,23 @@ caf_read_header (SF_PRIVATE *psf)
psf->sf.channels = desc.channels_per_frame ;
while (have_data == 0 && psf_ftell (psf) < psf->filelength - SIGNED_SIZEOF (marker))
{ psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ;
while (psf_ftell (psf) < psf->filelength)
{ marker = 0 ;
chunk_size = 0 ;
psf_binheader_readf (psf, "mE8", &marker, &chunk_size) ;
if (marker == 0)
{ psf_log_printf (psf, "Have 0 marker.\n") ;
break ;
} ;
psf_store_read_chunk_u32 (&psf->rchunks, marker, psf_ftell (psf), chunk_size) ;
switch (marker)
{ case peak_MARKER :
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
if (chunk_size != CAF_PEAK_CHUNK_SIZE (psf->sf.channels))
{ psf_binheader_readf (psf, "j", (int) chunk_size) ;
{ psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
psf_log_printf (psf, "*** File PEAK chunk %D should be %d.\n", chunk_size, CAF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
return SFE_CAF_BAD_PEAK ;
} ;
@@ -311,7 +412,7 @@ caf_read_header (SF_PRIVATE *psf)
psf_binheader_readf (psf, "E4", & (psf->peak_info->edit_number)) ;
psf_log_printf (psf, " edit count : %d\n", psf->peak_info->edit_number) ;
psf_log_printf (psf, " Ch Position Value\n") ;
psf_log_printf (psf, " Ch Position Value\n") ;
for (k = 0 ; k < psf->sf.channels ; k++)
{ sf_count_t position ;
float value ;
@@ -320,29 +421,95 @@ caf_read_header (SF_PRIVATE *psf)
psf->peak_info->peaks [k].value = value ;
psf->peak_info->peaks [k].position = position ;
snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), " %2d %-12ld %g\n", k, (long) position, value) ;
psf_log_printf (psf, psf->u.cbuf) ;
snprintf (ubuf.cbuf, sizeof (ubuf.cbuf), " %2d %-12" PRId64 " %g\n", k, position, value) ;
psf_log_printf (psf, ubuf.cbuf) ;
} ;
psf->peak_info->peak_loc = SF_PEAK_START ;
break ;
case chan_MARKER :
if (chunk_size < 12)
{ psf_log_printf (psf, "%M : %D (should be >= 12)\n", marker, chunk_size) ;
psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
break ;
}
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
if ((error = caf_read_chanmap (psf, chunk_size)))
return error ;
break ;
case free_MARKER :
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
psf_binheader_readf (psf, "j", (int) chunk_size) ;
psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
break ;
case data_MARKER :
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
psf_binheader_readf (psf, "E4", &k) ;
psf_log_printf (psf, " edit : %u\n", k) ;
if (chunk_size == -1)
{ psf_log_printf (psf, "%M : -1\n") ;
chunk_size = psf->filelength - psf->headindex ;
}
else if (psf->filelength > 0 && psf->filelength < psf->headindex + chunk_size - 16)
psf_log_printf (psf, "%M : %D (should be %D)\n", marker, chunk_size, psf->filelength - psf->headindex - 8) ;
else
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
psf->dataoffset = psf->headindex ;
/* Subtract the 4 bytes of the 'edit' field above. */
psf->datalength = chunk_size - 4 ;
psf_binheader_readf (psf, "j", psf->datalength) ;
have_data = 1 ;
break ;
default :
psf_log_printf (psf, " %M : %D (skipped)\n", marker, chunk_size) ;
psf_binheader_readf (psf, "j", (int) chunk_size) ;
case kuki_MARKER :
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
pcaf->alac.kuki_offset = psf_ftell (psf) - 12 ;
psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
break ;
case pakt_MARKER :
psf_log_printf (psf, "%M : %D\n", marker, chunk_size) ;
psf_binheader_readf (psf, "E8844", &pcaf->alac.packets, &pcaf->alac.valid_frames,
&pcaf->alac.priming_frames, &pcaf->alac.remainder_frames) ;
psf_log_printf (psf,
" Packets : %D\n"
" Valid frames : %D\n"
" Priming frames : %d\n"
" Remainder frames : %d\n",
pcaf->alac.packets, pcaf->alac.valid_frames, pcaf->alac.priming_frames,
pcaf->alac.remainder_frames
) ;
if (pcaf->alac.packets == 0 && pcaf->alac.valid_frames == 0
&& pcaf->alac.priming_frames == 0 && pcaf->alac.remainder_frames == 0)
psf_log_printf (psf, "*** 'pakt' chunk header is all zero.\n") ;
pcaf->alac.pakt_offset = psf_ftell (psf) - 12 ;
psf_binheader_readf (psf, "j", make_size_t (chunk_size) - 24) ;
break ;
default :
psf_log_printf (psf, "%M : %D (skipped)\n", marker, chunk_size) ;
psf_binheader_readf (psf, "j", make_size_t (chunk_size)) ;
break ;
} ;
if (! psf->sf.seekable && have_data)
break ;
if (psf_ftell (psf) >= psf->filelength - SIGNED_SIZEOF (chunk_size))
{ psf_log_printf (psf, "End\n") ;
break ;
} ;
} ;
@@ -351,12 +518,10 @@ caf_read_header (SF_PRIVATE *psf)
return SFE_MALFORMED_FILE ;
} ;
psf_log_printf (psf, "End\n") ;
psf->dataoffset = psf_ftell (psf) ;
psf->datalength = psf->filelength - psf->dataoffset ;
psf->endian = (desc.fmt_flags & 2) ? SF_ENDIAN_LITTLE : SF_ENDIAN_BIG ;
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
if ((psf->sf.format = decode_desc_chunk (psf, &desc)) == 0)
return SFE_UNSUPPORTED_ENCODING ;
@@ -371,9 +536,15 @@ caf_read_header (SF_PRIVATE *psf)
static int
caf_write_header (SF_PRIVATE *psf, int calc_length)
{ DESC_CHUNK desc ;
{ BUF_UNION ubuf ;
CAF_PRIVATE *pcaf ;
DESC_CHUNK desc ;
sf_count_t current, free_len ;
int subformat ;
uint32_t uk ;
int subformat, append_free_block = SF_TRUE ;
if ((pcaf = psf->container_data) == NULL)
return SFE_INTERNAL ;
memset (&desc, 0, sizeof (desc)) ;
@@ -402,8 +573,8 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
/* 'desc' marker and chunk size. */
psf_binheader_writef (psf, "Em8", desc_MARKER, (sf_count_t) (sizeof (DESC_CHUNK))) ;
double64_be_write (1.0 * psf->sf.samplerate, psf->u.ucbuf) ;
psf_binheader_writef (psf, "b", psf->u.ucbuf, make_size_t (8)) ;
double64_be_write (1.0 * psf->sf.samplerate, ubuf.ucbuf) ;
psf_binheader_writef (psf, "b", ubuf.ucbuf, make_size_t (8)) ;
subformat = SF_CODEC (psf->sf.format) ;
@@ -425,7 +596,7 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
desc.fmt_id = lpcm_MARKER ;
psf->bytewidth = 1 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.frames_per_packet = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 8 ;
break ;
@@ -434,7 +605,7 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
desc.fmt_id = lpcm_MARKER ;
psf->bytewidth = 2 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.frames_per_packet = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 16 ;
break ;
@@ -442,7 +613,7 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
case SF_FORMAT_PCM_24 :
psf->bytewidth = 3 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.frames_per_packet = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 24 ;
desc.fmt_id = lpcm_MARKER ;
@@ -452,7 +623,7 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
desc.fmt_id = lpcm_MARKER ;
psf->bytewidth = 4 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.frames_per_packet = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 32 ;
break ;
@@ -462,7 +633,7 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
desc.fmt_flags |= 1 ;
psf->bytewidth = 4 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.frames_per_packet = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 32 ;
break ;
@@ -472,7 +643,7 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
desc.fmt_flags |= 1 ;
psf->bytewidth = 8 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.frames_per_packet = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 64 ;
break ;
@@ -481,7 +652,7 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
desc.fmt_id = alaw_MARKER ;
psf->bytewidth = 1 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.frames_per_packet = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 8 ;
break ;
@@ -490,19 +661,30 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
desc.fmt_id = ulaw_MARKER ;
psf->bytewidth = 1 ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.pkt_frames = 1 ;
desc.frames_per_packet = 1 ;
desc.channels_per_frame = psf->sf.channels ;
desc.bits_per_chan = 8 ;
break ;
case SF_FORMAT_ALAC_16 :
case SF_FORMAT_ALAC_20 :
case SF_FORMAT_ALAC_24 :
case SF_FORMAT_ALAC_32 :
desc.fmt_id = alac_MARKER ;
desc.pkt_bytes = psf->bytewidth * psf->sf.channels ;
desc.channels_per_frame = psf->sf.channels ;
alac_get_desc_chunk_items (subformat, &desc.fmt_flags, &desc.frames_per_packet) ;
append_free_block = SF_FALSE ;
break ;
default :
return SFE_UNIMPLEMENTED ;
} ;
psf_binheader_writef (psf, "mE44444", desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.pkt_frames, desc.channels_per_frame, desc.bits_per_chan) ;
psf_binheader_writef (psf, "mE44444", desc.fmt_id, desc.fmt_flags, desc.pkt_bytes, desc.frames_per_packet, desc.channels_per_frame, desc.bits_per_chan) ;
#if 0
if (psf->str_flags & SF_STR_LOCATE_START)
if (psf->strings.flags & SF_STR_LOCATE_START)
caf_write_strings (psf, SF_STR_LOCATE_START) ;
#endif
@@ -513,13 +695,22 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
psf_binheader_writef (psf, "Ef8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
} ;
/* Add free chunk so that the actual audio data starts at a multiple 0x1000. */
free_len = 0x1000 - psf->headindex - 16 - 12 ;
while (free_len < 0)
free_len += 0x1000 ;
psf_binheader_writef (psf, "Em8z", free_MARKER, free_len, (int) free_len) ;
if (psf->channel_map && pcaf->chanmap_tag)
psf_binheader_writef (psf, "Em8444", chan_MARKER, (sf_count_t) 12, pcaf->chanmap_tag, 0, 0) ;
psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength, 0) ;
/* Write custom headers. */
for (uk = 0 ; uk < psf->wchunks.used ; uk++)
psf_binheader_writef (psf, "m44b", (int) psf->wchunks.chunks [uk].mark32, 0, psf->wchunks.chunks [uk].len, psf->wchunks.chunks [uk].data, make_size_t (psf->wchunks.chunks [uk].len)) ;
if (append_free_block)
{ /* Add free chunk so that the actual audio data starts at a multiple 0x1000. */
free_len = 0x1000 - psf->headindex - 16 - 12 ;
while (free_len < 0)
free_len += 0x1000 ;
psf_binheader_writef (psf, "Em8z", free_MARKER, free_len, (int) free_len) ;
} ;
psf_binheader_writef (psf, "Em84", data_MARKER, psf->datalength + 4, 0) ;
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
if (psf->error)
@@ -534,3 +725,80 @@ caf_write_header (SF_PRIVATE *psf, int calc_length)
return psf->error ;
} /* caf_write_header */
static int
caf_read_chanmap (SF_PRIVATE * psf, sf_count_t chunk_size)
{ const AIFF_CAF_CHANNEL_MAP * map_info ;
unsigned channel_bitmap, channel_decriptions, bytesread ;
int layout_tag ;
bytesread = psf_binheader_readf (psf, "E444", &layout_tag, &channel_bitmap, &channel_decriptions) ;
map_info = aiff_caf_of_channel_layout_tag (layout_tag) ;
psf_log_printf (psf, " Tag : %x\n", layout_tag) ;
if (map_info)
psf_log_printf (psf, " Layout : %s\n", map_info->name) ;
if (bytesread < chunk_size)
psf_binheader_readf (psf, "j", chunk_size - bytesread) ;
if (map_info->channel_map != NULL)
{ size_t chanmap_size = psf->sf.channels * sizeof (psf->channel_map [0]) ;
free (psf->channel_map) ;
if ((psf->channel_map = malloc (chanmap_size)) == NULL)
return SFE_MALLOC_FAILED ;
memcpy (psf->channel_map, map_info->channel_map, chanmap_size) ;
} ;
return 0 ;
} /* caf_read_chanmap */
/*==============================================================================
*/
static int
caf_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info)
{ return psf_save_write_chunk (&psf->wchunks, chunk_info) ;
} /* caf_set_chunk */
static SF_CHUNK_ITERATOR *
caf_next_chunk_iterator (SF_PRIVATE *psf, SF_CHUNK_ITERATOR * iterator)
{ return psf_next_chunk_iterator (&psf->rchunks, iterator) ;
} /* caf_next_chunk_iterator */
static int
caf_get_chunk_size (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info)
{ int indx ;
if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0)
return SFE_UNKNOWN_CHUNK ;
chunk_info->datalen = psf->rchunks.chunks [indx].len ;
return SFE_NO_ERROR ;
} /* caf_get_chunk_size */
static int
caf_get_chunk_data (SF_PRIVATE *psf, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info)
{ int indx ;
sf_count_t pos ;
if ((indx = psf_find_read_chunk_iterator (&psf->rchunks, iterator)) < 0)
return SFE_UNKNOWN_CHUNK ;
if (chunk_info->data == NULL)
return SFE_BAD_CHUNK_DATA_PTR ;
chunk_info->id_size = psf->rchunks.chunks [indx].id_size ;
memcpy (chunk_info->id, psf->rchunks.chunks [indx].id, sizeof (chunk_info->id) / sizeof (*chunk_info->id)) ;
pos = psf_ftell (psf) ;
psf_fseek (psf, psf->rchunks.chunks [indx].offset, SEEK_SET) ;
psf_fread (chunk_info->data, SF_MIN (chunk_info->datalen, psf->rchunks.chunks [indx].len), 1, psf) ;
psf_fseek (psf, pos, SEEK_SET) ;
return SFE_NO_ERROR ;
} /* caf_get_chunk_data */
+101
View File
@@ -0,0 +1,101 @@
/*
** Copyright (C) 2012 Chris Roberts <c.roberts@csrfm.com>
** Copyright (C) 2006-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2006 Paul Davis <paul@linuxaudiosystems.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
static inline size_t
cart_min_size (const SF_CART_INFO* info)
{ if (info == NULL)
return 0 ;
return offsetof (SF_CART_INFO, tag_text) + info->tag_text_size ;
} /* cart_min_size */
SF_CART_INFO_16K*
cart_var_alloc (void)
{ SF_CART_INFO_16K* thing ;
thing = malloc (sizeof (SF_CART_INFO_16K)) ;
return thing ;
} /* cart_var_alloc */
int
cart_var_set (SF_PRIVATE *psf, const SF_CART_INFO * info, size_t datasize)
{ size_t len ;
if (info == NULL)
return SF_FALSE ;
if (cart_min_size (info) > datasize)
{ psf->error = SFE_BAD_CART_INFO_SIZE ;
return SF_FALSE ;
} ;
if (datasize >= sizeof (SF_CART_INFO_16K))
{ psf->error = SFE_BAD_CART_INFO_TOO_BIG ;
return SF_FALSE ;
} ;
if (psf->cart_16k == NULL)
{ if ((psf->cart_16k = cart_var_alloc ()) == NULL)
{ psf->error = SFE_MALLOC_FAILED ;
return SF_FALSE ;
} ;
} ;
memcpy (psf->cart_16k, info, offsetof (SF_CART_INFO, tag_text)) ;
psf_strlcpy_crlf (psf->cart_16k->tag_text, info->tag_text, sizeof (psf->cart_16k->tag_text), datasize - offsetof (SF_CART_INFO, tag_text)) ;
len = strlen (psf->cart_16k->tag_text) ;
if (len > 0 && psf->cart_16k->tag_text [len - 1] != '\n')
psf_strlcat (psf->cart_16k->tag_text, sizeof (psf->cart_16k->tag_text), "\r\n") ;
/* Force tag_text_size to be even. */
len = strlen (psf->cart_16k->tag_text) ;
len += (len & 1) ? 1 : 2 ;
psf->cart_16k->tag_text_size = len ;
return SF_TRUE ;
} /* cart_var_set */
int
cart_var_get (SF_PRIVATE *psf, SF_CART_INFO * data, size_t datasize)
{ size_t size ;
if (psf->cart_16k == NULL)
return SF_FALSE ;
size = SF_MIN (datasize, cart_min_size ((const SF_CART_INFO *) psf->cart_16k)) ;
memcpy (data, psf->cart_16k, size) ;
return SF_TRUE ;
} /* cart_var_get */
+262
View File
@@ -0,0 +1,262 @@
/*
** Copyright (C) 2009-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
** Mostly from "Apple Core Audio Format Specification 1.0":
**
** http://developer.apple.com/documentation/MusicAudio/Reference/CAFSpec/CAFSpec.pdf
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sndfile.h"
#include "common.h"
#include "chanmap.h"
static const AIFF_CAF_CHANNEL_MAP zero_chan [] =
{ { (0 << 16) | 0, NULL, "Use channel descriptions." },
{ (1 << 16) | 0, NULL, "Use channel bitmap." }
} ; /* zero_chan */
static const int one_chan_mono [1] = { SF_CHANNEL_MAP_MONO } ;
static const AIFF_CAF_CHANNEL_MAP one_chan [] =
{ { (100 << 16) | 1, one_chan_mono, "mono" }
} ; /* one_chan */
static const int two_channel_stereo [2] = { SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT } ;
static const AIFF_CAF_CHANNEL_MAP two_chan [] =
{ { (101 << 16) | 2, two_channel_stereo, "stereo (L, R)" },
{ (102 << 16) | 2, two_channel_stereo, "stereo headphones (L, R)" },
#if 0
{ (103 << 16) | 2, NULL, "matrix stereo (Lt, Rt)" },
{ (104 << 16) | 2, NULL, "2 channels (mid, side)" },
{ (105 << 16) | 2, NULL, "coincident mic pair" },
{ (106 << 16) | 2, NULL, "binaural stereo (L, R)"
}
#endif
} ; /* two_chan */
static const int three_channel_mpeg_30a [3] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER } ;
static const int three_channel_mpeg_30b [3] =
{ SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT } ;
static const int three_channel_itu_21 [3] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_CENTER } ;
static const int three_channel_dvd_4 [3] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE } ;
static const AIFF_CAF_CHANNEL_MAP three_chan [] =
{ { (113 << 16) | 3, three_channel_mpeg_30a, "MPEG 3 0 A (L, R, C)" },
{ (114 << 16) | 3, three_channel_mpeg_30b, "MPEG 3 0 B (C, L, R)" },
{ (131 << 16) | 3, three_channel_itu_21, "ITU 2.1 (L, R, Cs)" },
{ (133 << 16) | 3, three_channel_dvd_4, "DVD 4 (L, R, LFE)" }
} ; /* three_chan */
static const int four_channel_ambisonc_b [4] =
{ SF_CHANNEL_MAP_AMBISONIC_B_W, SF_CHANNEL_MAP_AMBISONIC_B_X, SF_CHANNEL_MAP_AMBISONIC_B_Y, SF_CHANNEL_MAP_AMBISONIC_B_Z } ;
static const int four_channel_quad [4] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
static const int four_channel_mpeg_40a [4] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_REAR_CENTER } ;
static const int four_channel_mpeg_40b [4] =
{ SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_CENTER } ;
static const int four_channel_itu_23 [4] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
static const int four_channel_dvd_5 [4] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE, SF_CHANNEL_MAP_REAR_CENTER } ;
static const int four_channel_dvd_10 [4] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE } ;
static const AIFF_CAF_CHANNEL_MAP four_chan [] =
{ { (107 << 16) | 4, four_channel_ambisonc_b, "ambisonic B (W, X, Y, Z)" },
{ (108 << 16) | 4, four_channel_quad, "quad (Lfront, Rfront, Lrear, Rrear)" },
{ (115 << 16) | 4, four_channel_mpeg_40a, "MPEG 4.0 A (L, R, C, Cs)" },
{ (116 << 16) | 4, four_channel_mpeg_40b, "MPEG 4.0 B (C, L, R, Cs)" },
{ (132 << 16) | 4, four_channel_itu_23, "ITU 2.3 (L, R, Ls, Rs)" },
{ (134 << 16) | 4, four_channel_dvd_5, "DVD 5 (L, R, LFE, Cs)" },
{ (136 << 16) | 4, four_channel_dvd_10, "DVD 10 (L, R, C, LFE)" }
} ; /* four_chan */
static const int five_channel_pentagonal [5] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_CENTER } ;
static const int five_channel_mpeg_50_a [5] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
static const int five_channel_mpeg_50_b [5] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_CENTER } ;
static const int five_channel_mpeg_50_c [5] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
static const int five_channel_mpeg_50_d [5] =
{ SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
static const int five_channel_dvd_6 [5] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_LFE, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
static const int five_channel_dvd_11 [5] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE, SF_CHANNEL_MAP_REAR_CENTER } ;
static const int five_channel_dvd_18 [5] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_LFE } ;
static const AIFF_CAF_CHANNEL_MAP five_chan [] =
{ { (109 << 16) | 5, five_channel_pentagonal, "pentagonal (L, R, Lrear, Rrear, C)" },
{ (117 << 16) | 5, five_channel_mpeg_50_a, "MPEG 5.0 A (L, R, C, Ls, Rs)" },
{ (118 << 16) | 5, five_channel_mpeg_50_b, "MPEG 5.0 B (L, R, Ls, Rs, C)" },
{ (119 << 16) | 5, five_channel_mpeg_50_c, "MPEG 5.0 C (L, C, R, Ls, Rs,)" },
{ (120 << 16) | 5, five_channel_mpeg_50_d, "MPEG 5.0 D (C, L, R, Ls, Rs)" },
{ (135 << 16) | 5, five_channel_dvd_6, "DVD 6 (L, R, LFE, Ls, Rs)" },
{ (137 << 16) | 5, five_channel_dvd_11, "DVD 11 (L, R, C, LFE, Cs)" },
{ (138 << 16) | 5, five_channel_dvd_18, "DVD 18 (L, R, Ls, Rs, LFE)" }
} ; /* five_chan */
static const int six_channel_mpeg_51_a [6] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ;
static const int six_channel_mpeg_51_b [6] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE } ;
static const int six_channel_mpeg_51_c [6] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_LFE } ;
static const int six_channel_mpeg_51_d [6] =
{ SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_LFE } ;
static const int six_channel_audio_unit_60 [6] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_REAR_CENTER } ;
static const int six_channel_aac_60 [6] =
{ SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_REAR_CENTER } ;
static const AIFF_CAF_CHANNEL_MAP six_chan [] =
{ { (110 << 16) | 6, NULL, "hexagonal (L, R, Lr, Rr, C, Rear)" },
{ (121 << 16) | 6, six_channel_mpeg_51_a, "MPEG 5.1 A (L, R, C, LFE, Ls, Rs)" },
{ (122 << 16) | 6, six_channel_mpeg_51_b, "MPEG 5.1 B (L, R, Ls, Rs, C, LFE)" },
{ (123 << 16) | 6, six_channel_mpeg_51_c, "MPEG 5.1 C (L, C, R, Ls, Rs, LFE)" },
{ (124 << 16) | 6, six_channel_mpeg_51_d, "MPEG 5.1 D (C, L, R, Ls, Rs, LFE)" },
{ (139 << 16) | 6, six_channel_audio_unit_60, "AudioUnit 6.0 (L, R, Ls, Rs, C, Cs)" },
{ (141 << 16) | 6, six_channel_aac_60, "AAC 6.0 (C, L, R, Ls, Rs, Cs)" }
} ; /* six_chan */
static const int six_channel_mpeg_61a [7] =
{ SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LFE, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_REAR_CENTER } ;
static const int six_channel_aac_61 [7] =
{ SF_CHANNEL_MAP_CENTER, SF_CHANNEL_MAP_LEFT, SF_CHANNEL_MAP_RIGHT, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT, SF_CHANNEL_MAP_REAR_CENTER, SF_CHANNEL_MAP_LFE } ;
static const AIFF_CAF_CHANNEL_MAP seven_chan [] =
{ { (125 << 16) | 7, six_channel_mpeg_61a, "MPEG 6.1 A (L, R, C, LFE, Ls, Rs, Cs)" },
{ (140 << 16) | 7, NULL, "AudioUnit 7.0 (L, R, Ls, Rs, C, Rls, Rrs)" },
{ (142 << 16) | 7, six_channel_aac_61, "AAC 6.1 (C, L, R, Ls, Rs, Cs, Lfe)" },
{ (143 << 16) | 7, NULL, "AAC 7.0 (C, L, R, Ls, Rs, Rls, Rrs,)" }
} ; /* seven_chan */
static const AIFF_CAF_CHANNEL_MAP eight_chan [] =
{ { (111 << 16) | 8, NULL,
// front left, front right, rear left, rear right,
// front center, rear center, side left, side right
"octagonal (Lf, Rf, Lr, Rr, Cf, Cr, Ls, Rs)"
},
{ (112 << 16) | 8, NULL,
// left, right, rear left, rear right
// top left, top right, top rear left, top rear right
"cube (L, R, Lrear, Rrear, Ltop, Rtop, Ltoprear, Rtoprear)"
},
{ (126 << 16) | 8, NULL, "MPEG 7.1 A (L, R, C, LFE, Ls, Rs, Lc, Rc)" },
{ (127 << 16) | 8, NULL, "MPEG 7.1 B (C, Lc, Rc, L, R, Ls, Rs, LFE)" },
{ (128 << 16) | 8, NULL, "MPEG 7.1 C (L, R, C, LFE, Ls, R, Rls, Rrs)" },
{ (129 << 16) | 8, NULL, "Emagic Default 7.1 (L, R, Ls, Rs, C, LFE, Lc, Rc)" },
{ (130 << 16) | 8, NULL,
// (ITU_5_1 plus a matrix encoded stereo mix)
"SMPTE DTV (L, R, C, LFE, Ls, Rs, Lt, Rt)"
},
{ (144 << 16) | 8, NULL, "AAC octagonal (C, L, R, Ls, Rs, Rls, Rrs, Cs)" }
} ; /* eight_chan */
#if 0
TMH_10_2_std = (145 << 16) | 16,
// L R C Vhc Lsd Rsd Ls Rs Vhl Vhr Lw Rw Csd Cs LFE1 LFE2
TMH_10_2_full = (146 << 16) | 21,
// TMH_10_2_std plus: Lc Rc HI VI Haptic
#endif
typedef struct
{ const AIFF_CAF_CHANNEL_MAP * map ;
int len ;
} MAP_MAP ;
static const MAP_MAP map [] =
{ { zero_chan, ARRAY_LEN (zero_chan) },
{ one_chan, ARRAY_LEN (one_chan) },
{ two_chan, ARRAY_LEN (two_chan) },
{ three_chan, ARRAY_LEN (three_chan) },
{ four_chan, ARRAY_LEN (four_chan) },
{ five_chan, ARRAY_LEN (five_chan) },
{ six_chan, ARRAY_LEN (six_chan) },
{ seven_chan, ARRAY_LEN (seven_chan) },
{ eight_chan, ARRAY_LEN (eight_chan) }
} ; /* map */
int
aiff_caf_find_channel_layout_tag (const int *chan_map, int channels)
{ const AIFF_CAF_CHANNEL_MAP * curr_map ;
unsigned k, len ;
if (channels < 1 || channels > ARRAY_LEN (map))
return 0 ;
curr_map = map [channels].map ;
len = map [channels].len ;
for (k = 0 ; k < len ; k++)
if (curr_map [k].channel_map != NULL)
if (memcmp (chan_map, curr_map [k].channel_map, channels * sizeof (chan_map [0])) == 0)
return curr_map [k].channel_layout_tag ;
return 0 ;
} /* aiff_caf_find_channel_layout_tag */
const AIFF_CAF_CHANNEL_MAP *
aiff_caf_of_channel_layout_tag (int tag)
{ const AIFF_CAF_CHANNEL_MAP * curr_map ;
unsigned k, len ;
int channels = tag & 0xffff ;
if (channels < 0 || channels > ARRAY_LEN (map))
return NULL ;
curr_map = map [channels].map ;
len = map [channels].len ;
for (k = 0 ; k < len ; k++)
if (curr_map [k].channel_layout_tag == tag)
return curr_map + k ;
return NULL ;
} /* aiff_caf_of_channel_layout_tag */
+32
View File
@@ -0,0 +1,32 @@
/*
** Copyright (C) 2009-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
typedef struct
{ /* The tag in the AIFF or CAF file. */
int channel_layout_tag ;
/* The equivalent array of SF_CHANNEL_MAP_* entries. */
const int * channel_map ;
const char * name ;
} AIFF_CAF_CHANNEL_MAP ;
int aiff_caf_find_channel_layout_tag (const int *chan_map, int channels) ;
const AIFF_CAF_CHANNEL_MAP * aiff_caf_of_channel_layout_tag (int tag) ;
+218 -17
View File
@@ -1,5 +1,6 @@
/*
** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2008-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2012 IOhannes m zmoelnig, IEM <zmoelnig@iem.at>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -25,30 +26,230 @@
#include "sfendian.h"
#include "common.h"
static int64_t
hash_of_str (const char * str)
{ int64_t marker = 0 ;
int k ;
void
pchk4_store (PRIV_CHUNK4 * pchk, int marker, sf_count_t offset, sf_count_t len)
{
if (pchk->count >= ARRAY_LEN (pchk->l))
return ;
for (k = 0 ; str [k] ; k++)
marker = marker * 0x7f + ((const uint8_t *) str) [k] ;
pchk->l [pchk->count].chunk = marker ;
pchk->l [pchk->count].offset = offset ;
pchk->l [pchk->count].len = len ;
return marker ;
} /* hash_of_str */
pchk->count ++ ;
SF_CHUNK_ITERATOR *
psf_get_chunk_iterator (SF_PRIVATE * psf, const char * marker_str)
{ const READ_CHUNKS * pchk = &psf->rchunks ;
int idx ;
return ;
} /* pchk4_store */
if (marker_str)
idx = psf_find_read_chunk_str (pchk, marker_str) ;
else
idx = pchk->used > 0 ? 0 : -1 ;
if (idx < 0)
return NULL ;
if (psf->iterator == NULL)
{ psf->iterator = calloc (1, sizeof (SF_CHUNK_ITERATOR)) ;
if (psf->iterator == NULL)
return NULL ;
} ;
psf->iterator->sndfile = (SNDFILE *) psf ;
if (marker_str)
{ int64_t hash ;
size_t marker_len ;
union
{ uint32_t marker ;
char str [5] ;
} u ;
snprintf (u.str, sizeof (u.str), "%s", marker_str) ;
marker_len = strlen (marker_str) ;
if (marker_len > 64)
marker_len = 64 ;
hash = marker_len > 4 ? hash_of_str (marker_str) : u.marker ;
memcpy (psf->iterator->id, marker_str, marker_len) ;
psf->iterator->id_size = marker_len ;
psf->iterator->hash = hash ;
}
psf->iterator->current = idx ;
return psf->iterator ;
} /* psf_get_chunk_iterator */
SF_CHUNK_ITERATOR *
psf_next_chunk_iterator (const READ_CHUNKS * pchk , SF_CHUNK_ITERATOR * iterator)
{ int64_t hash = iterator->hash ;
uint32_t k ;
iterator->current++ ;
if (hash)
{ for (k = iterator->current ; k < pchk->used ; k++)
if (pchk->chunks [k].hash == hash)
{ iterator->current = k ;
return iterator ;
}
}
else if (iterator->current < pchk->used)
return iterator ;
/* No match, clear iterator and return NULL */
memset (iterator, 0, sizeof (*iterator)) ;
return NULL ;
} /* psf_next_chunk_iterator */
static int
psf_store_read_chunk (READ_CHUNKS * pchk, const READ_CHUNK * rchunk)
{ if (pchk->count == 0)
{ pchk->used = 0 ;
pchk->count = 20 ;
pchk->chunks = calloc (pchk->count, sizeof (READ_CHUNK)) ;
}
else if (pchk->used > pchk->count)
return SFE_INTERNAL ;
else if (pchk->used == pchk->count)
{ READ_CHUNK * old_ptr = pchk->chunks ;
int new_count = 3 * (pchk->count + 1) / 2 ;
pchk->chunks = realloc (old_ptr, new_count * sizeof (READ_CHUNK)) ;
if (pchk->chunks == NULL)
{ pchk->chunks = old_ptr ;
return SFE_MALLOC_FAILED ;
} ;
pchk->count = new_count ;
} ;
pchk->chunks [pchk->used] = *rchunk ;
pchk->used ++ ;
return SFE_NO_ERROR ;
} /* psf_store_read_chunk */
int
pchk4_find (PRIV_CHUNK4 * pchk, int marker)
{ int k ;
psf_store_read_chunk_u32 (READ_CHUNKS * pchk, uint32_t marker, sf_count_t offset, uint32_t len)
{ READ_CHUNK rchunk ;
for (k = 0 ; k < pchk->count ; k++)
if (pchk->l [k].chunk == marker)
memset (&rchunk, 0, sizeof (rchunk)) ;
rchunk.hash = marker ;
rchunk.mark32 = marker ;
rchunk.offset = offset ;
rchunk.len = len ;
rchunk.id_size = 4 ;
memcpy (rchunk.id, &marker, rchunk.id_size) ;
return psf_store_read_chunk (pchk, &rchunk) ;
} /* psf_store_read_chunk_u32 */
int
psf_find_read_chunk_str (const READ_CHUNKS * pchk, const char * marker_str)
{ int64_t hash ;
uint32_t k ;
union
{ uint32_t marker ;
char str [5] ;
} u ;
snprintf (u.str, sizeof (u.str), "%s", marker_str) ;
hash = strlen (marker_str) > 4 ? hash_of_str (marker_str) : u.marker ;
for (k = 0 ; k < pchk->used ; k++)
if (pchk->chunks [k].hash == hash)
return k ;
return -1 ;
} /* pchk4_find */
} /* psf_find_read_chunk_str */
int
psf_find_read_chunk_m32 (const READ_CHUNKS * pchk, uint32_t marker)
{ uint32_t k ;
for (k = 0 ; k < pchk->used ; k++)
if (pchk->chunks [k].mark32 == marker)
return k ;
return -1 ;
} /* psf_find_read_chunk_m32 */
int
psf_find_read_chunk_iterator (const READ_CHUNKS * pchk, const SF_CHUNK_ITERATOR * marker)
{ if (marker->current < pchk->used)
return marker->current ;
return -1 ;
} /* psf_find_read_chunk_iterator */
int
psf_store_read_chunk_str (READ_CHUNKS * pchk, const char * marker_str, sf_count_t offset, uint32_t len)
{ READ_CHUNK rchunk ;
union
{ uint32_t marker ;
char str [5] ;
} u ;
size_t marker_len ;
memset (&rchunk, 0, sizeof (rchunk)) ;
snprintf (u.str, sizeof (u.str), "%s", marker_str) ;
marker_len = strlen (marker_str) ;
rchunk.hash = marker_len > 4 ? hash_of_str (marker_str) : u.marker ;
rchunk.mark32 = u.marker ;
rchunk.offset = offset ;
rchunk.len = len ;
rchunk.id_size = marker_len > 64 ? 64 : marker_len ;
memcpy (rchunk.id, marker_str, rchunk.id_size) ;
return psf_store_read_chunk (pchk, &rchunk) ;
} /* psf_store_read_chunk_str */
int
psf_save_write_chunk (WRITE_CHUNKS * pchk, const SF_CHUNK_INFO * chunk_info)
{ union
{ uint32_t marker ;
char str [5] ;
} u ;
uint32_t len ;
if (pchk->count == 0)
{ pchk->used = 0 ;
pchk->count = 20 ;
pchk->chunks = calloc (pchk->count, sizeof (WRITE_CHUNK)) ;
}
else if (pchk->used >= pchk->count)
{ WRITE_CHUNK * old_ptr = pchk->chunks ;
int new_count = 3 * (pchk->count + 1) / 2 ;
pchk->chunks = realloc (old_ptr, new_count * sizeof (WRITE_CHUNK)) ;
if (pchk->chunks == NULL)
{ pchk->chunks = old_ptr ;
return SFE_MALLOC_FAILED ;
} ;
} ;
len = chunk_info->datalen ;
while (len & 3) len ++ ;
snprintf (u.str, sizeof (u.str), "%s", chunk_info->id) ;
pchk->chunks [pchk->used].hash = strlen (chunk_info->id) > 4 ? hash_of_str (chunk_info->id) : u.marker ;
pchk->chunks [pchk->used].mark32 = u.marker ;
pchk->chunks [pchk->used].len = len ;
pchk->chunks [pchk->used].data = psf_memdup (chunk_info->data, chunk_info->datalen) ;
pchk->used ++ ;
return SFE_NO_ERROR ;
} /* psf_save_write_chunk */
+29 -13
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2001-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -47,6 +47,10 @@ static SF_FORMAT_INFO const simple_formats [] =
"AU (Sun/Next 8-bit u-law)", "au"
},
{ SF_FORMAT_CAF | SF_FORMAT_ALAC_16,
"CAF (Apple 16 bit ALAC)", "caf"
},
{ SF_FORMAT_CAF | SF_FORMAT_PCM_16,
"CAF (Apple 16 bit PCM)", "caf"
},
@@ -115,28 +119,30 @@ static SF_FORMAT_INFO const major_formats [] =
{
{ SF_FORMAT_AIFF, "AIFF (Apple/SGI)", "aiff" },
{ SF_FORMAT_AU, "AU (Sun/NeXT)", "au" },
{ SF_FORMAT_AVR, "AVR (Audio Visual Research)", "avr" },
{ SF_FORMAT_CAF, "CAF (Apple Core Audio File)", "caf" },
{ SF_FORMAT_AVR, "AVR (Audio Visual Research)", "avr" },
{ SF_FORMAT_CAF, "CAF (Apple Core Audio File)", "caf" },
#if HAVE_EXTERNAL_LIBS
{ SF_FORMAT_FLAC, "FLAC (FLAC Lossless Audio Codec)", "flac" },
{ SF_FORMAT_FLAC, "FLAC (Free Lossless Audio Codec)", "flac" },
#endif
{ SF_FORMAT_HTK, "HTK (HMM Tool Kit)", "htk" },
{ SF_FORMAT_SVX, "IFF (Amiga IFF/SVX8/SV16)", "iff" },
{ SF_FORMAT_MAT4, "MAT4 (GNU Octave 2.0 / Matlab 4.2)", "mat" },
{ SF_FORMAT_MAT5, "MAT5 (GNU Octave 2.1 / Matlab 5.0)", "mat" },
{ SF_FORMAT_MPC2K, "MPC (Akai MPC 2k)", "mpc" },
#if HAVE_EXTERNAL_LIBS
{ SF_FORMAT_OGG, "OGG (OGG Container format)", "oga" },
{ SF_FORMAT_OGG, "OGG (OGG Container format)", "oga" },
#endif
{ SF_FORMAT_PAF, "PAF (Ensoniq PARIS)", "paf" },
{ SF_FORMAT_PVF, "PVF (Portable Voice Format)", "pvf" },
{ SF_FORMAT_RAW, "RAW (header-less)", "raw" },
{ SF_FORMAT_RAW, "RAW (header-less)", "raw" },
{ SF_FORMAT_RF64, "RF64 (RIFF 64)", "rf64" },
{ SF_FORMAT_SD2, "SD2 (Sound Designer II)", "sd2" },
{ SF_FORMAT_SDS, "SDS (Midi Sample Dump Standard)", "sds" },
{ SF_FORMAT_IRCAM, "SF (Berkeley/IRCAM/CARL)", "sf" },
{ SF_FORMAT_VOC, "VOC (Creative Labs)", "voc" },
{ SF_FORMAT_W64, "W64 (SoundFoundry WAVE 64)", "w64" },
{ SF_FORMAT_WAV, "WAV (Microsoft)", "wav" },
{ SF_FORMAT_NIST, "WAV (NIST Sphere)", "wav" },
{ SF_FORMAT_NIST, "WAV (NIST Sphere)", "wav" },
{ SF_FORMAT_WAVEX, "WAVEX (Microsoft)", "wav" },
{ SF_FORMAT_WVE, "WVE (Psion Series 3)", "wve" },
{ SF_FORMAT_XI, "XI (FastTracker 2)", "xi" },
@@ -198,6 +204,11 @@ static SF_FORMAT_INFO subtype_formats [] =
#if HAVE_EXTERNAL_LIBS
{ SF_FORMAT_VORBIS, "Vorbis", NULL },
#endif
{ SF_FORMAT_ALAC_16, "16 bit ALAC", NULL },
{ SF_FORMAT_ALAC_20, "20 bit ALAC", NULL },
{ SF_FORMAT_ALAC_24, "24 bit ALAC", NULL },
{ SF_FORMAT_ALAC_32, "32 bit ALAC", NULL },
} ; /* subtype_formats */
int
@@ -210,7 +221,9 @@ psf_get_format_subtype (SF_FORMAT_INFO *data)
{ int indx ;
if (data->format < 0 || data->format >= (SIGNED_SIZEOF (subtype_formats) / SIGNED_SIZEOF (SF_FORMAT_INFO)))
{ data->format = 0 ;
return SFE_BAD_COMMAND_PARAM ;
} ;
indx = data->format ;
memcpy (data, &(subtype_formats [indx]), sizeof (SF_FORMAT_INFO)) ;
@@ -256,7 +269,8 @@ psf_get_format_info (SF_FORMAT_INFO *data)
double
psf_calc_signal_max (SF_PRIVATE *psf, int normalize)
{ sf_count_t position ;
{ BUF_UNION ubuf ;
sf_count_t position ;
double max_val, temp, *data ;
int k, len, readcount, save_state ;
@@ -280,8 +294,9 @@ psf_calc_signal_max (SF_PRIVATE *psf, int normalize)
/* Go to start of file. */
sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ;
data = psf->u.dbuf ;
len = ARRAY_LEN (psf->u.dbuf) ;
data = ubuf.dbuf ;
/* Make sure len is an integer multiple of the channel count. */
len = ARRAY_LEN (ubuf.dbuf) - (ARRAY_LEN (ubuf.dbuf) % psf->sf.channels) ;
for (readcount = 1, max_val = 0.0 ; readcount > 0 ; /* nothing */)
{ readcount = sf_read_double ((SNDFILE*) psf, data, len) ;
@@ -300,7 +315,8 @@ psf_calc_signal_max (SF_PRIVATE *psf, int normalize)
int
psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize)
{ sf_count_t position ;
{ BUF_UNION ubuf ;
sf_count_t position ;
double temp, *data ;
int k, len, readcount, save_state ;
int chan ;
@@ -321,9 +337,9 @@ psf_calc_max_all_channels (SF_PRIVATE *psf, double *peaks, int normalize)
position = sf_seek ((SNDFILE*) psf, 0, SEEK_CUR) ; /* Get current position in file */
sf_seek ((SNDFILE*) psf, 0, SEEK_SET) ; /* Go to start of file. */
len = ARRAY_LEN (psf->u.dbuf) ;
len = ARRAY_LEN (ubuf.dbuf) ;
data = psf->u.dbuf ;
data = ubuf.dbuf ;
chan = 0 ;
readcount = len ;
+280 -33
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -20,30 +20,35 @@
#include <stdarg.h>
#include <string.h>
#ifndef MSC_VER
#include <unistd.h>
#endif
#include <ctype.h>
#include <math.h>
#include <time.h>
#ifndef _MSC_VER
#include <sys/time.h>
#endif
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
/*-----------------------------------------------------------------------------------------------
** psf_log_printf allows libsndfile internal functions to print to an internal logbuffer which
** psf_log_printf allows libsndfile internal functions to print to an internal parselog which
** can later be displayed.
** The format specifiers are as for printf but without the field width and other modifiers.
** Printing is performed to the logbuffer char array of the SF_PRIVATE struct.
** Printing is performed to the parselog char array of the SF_PRIVATE struct.
** Printing is done in such a way as to guarantee that the log never overflows the end of the
** logbuffer array.
** parselog array.
*/
static inline void
log_putchar (SF_PRIVATE *psf, char ch)
{ if (psf->logindex < SIGNED_SIZEOF (psf->logbuffer) - 1)
{ psf->logbuffer [psf->logindex++] = ch ;
psf->logbuffer [psf->logindex] = 0 ;
{ if (psf->parselog.indx < SIGNED_SIZEOF (psf->parselog.buf) - 1)
{ psf->parselog.buf [psf->parselog.indx++] = ch ;
psf->parselog.buf [psf->parselog.indx] = 0 ;
} ;
return ;
} /* log_putchar */
@@ -757,37 +762,37 @@ psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...)
#if (CPU_IS_BIG_ENDIAN == 1)
#define GET_MARKER(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
((ptr) [2] << 8) | ((ptr) [3]) )
((ptr) [2] << 8) | ((ptr) [3]))
#elif (CPU_IS_LITTLE_ENDIAN == 1)
#define GET_MARKER(ptr) ( ((ptr) [0]) | ((ptr) [1] << 8) | \
((ptr) [2] << 16) | ((ptr) [3] << 24) )
((ptr) [2] << 16) | ((ptr) [3] << 24))
#else
# error "Cannot determine endian-ness of processor."
#endif
#define GET_LE_SHORT(ptr) ( ((ptr) [1] << 8) | ((ptr) [0]) )
#define GET_BE_SHORT(ptr) ( ((ptr) [0] << 8) | ((ptr) [1]) )
#define GET_LE_SHORT(ptr) (((ptr) [1] << 8) | ((ptr) [0]))
#define GET_BE_SHORT(ptr) (((ptr) [0] << 8) | ((ptr) [1]))
#define GET_LE_3BYTE(ptr) ( ((ptr) [2] << 16) | ((ptr) [1] << 8) | ((ptr) [0]) )
#define GET_BE_3BYTE(ptr) ( ((ptr) [0] << 16) | ((ptr) [1] << 8) | ((ptr) [2]) )
#define GET_LE_3BYTE(ptr) ( ((ptr) [2] << 16) | ((ptr) [1] << 8) | ((ptr) [0]))
#define GET_BE_3BYTE(ptr) ( ((ptr) [0] << 16) | ((ptr) [1] << 8) | ((ptr) [2]))
#define GET_LE_INT(ptr) ( ((ptr) [3] << 24) | ((ptr) [2] << 16) | \
((ptr) [1] << 8) | ((ptr) [0]) )
#define GET_LE_INT(ptr) ( ((ptr) [3] << 24) | ((ptr) [2] << 16) | \
((ptr) [1] << 8) | ((ptr) [0]))
#define GET_BE_INT(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
((ptr) [2] << 8) | ((ptr) [3]) )
#define GET_BE_INT(ptr) ( ((ptr) [0] << 24) | ((ptr) [1] << 16) | \
((ptr) [2] << 8) | ((ptr) [3]))
#define GET_LE_8BYTE(ptr) ( (((sf_count_t) (ptr) [7]) << 56) | (((sf_count_t) (ptr) [6]) << 48) | \
(((sf_count_t) (ptr) [5]) << 40) | (((sf_count_t) (ptr) [4]) << 32) | \
(((sf_count_t) (ptr) [3]) << 24) | (((sf_count_t) (ptr) [2]) << 16) | \
(((sf_count_t) (ptr) [1]) << 8 ) | ((ptr) [0]))
#define GET_LE_8BYTE(ptr) ( (((sf_count_t) (ptr) [7]) << 56) | (((sf_count_t) (ptr) [6]) << 48) | \
(((sf_count_t) (ptr) [5]) << 40) | (((sf_count_t) (ptr) [4]) << 32) | \
(((sf_count_t) (ptr) [3]) << 24) | (((sf_count_t) (ptr) [2]) << 16) | \
(((sf_count_t) (ptr) [1]) << 8) | ((ptr) [0]))
#define GET_BE_8BYTE(ptr) ( (((sf_count_t) (ptr) [0]) << 56) | (((sf_count_t) (ptr) [1]) << 48) | \
(((sf_count_t) (ptr) [2]) << 40) | (((sf_count_t) (ptr) [3]) << 32) | \
(((sf_count_t) (ptr) [4]) << 24) | (((sf_count_t) (ptr) [5]) << 16) | \
(((sf_count_t) (ptr) [6]) << 8 ) | ((ptr) [7]))
#define GET_BE_8BYTE(ptr) ( (((sf_count_t) (ptr) [0]) << 56) | (((sf_count_t) (ptr) [1]) << 48) | \
(((sf_count_t) (ptr) [2]) << 40) | (((sf_count_t) (ptr) [3]) << 32) | \
(((sf_count_t) (ptr) [4]) << 24) | (((sf_count_t) (ptr) [5]) << 16) | \
(((sf_count_t) (ptr) [6]) << 8) | ((ptr) [7]))
@@ -1026,7 +1031,7 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
strptr = va_arg (argptr, char *) ;
size = strlen (strptr) + 1 ;
size += (size & 1) ;
longdata = H2LE_INT (size) ;
longdata = H2LE_32 (size) ;
get_int (psf, longdata) ;
memcpy (&(psf->header [psf->headindex]), strptr, size) ;
psf->headindex += size ;
@@ -1035,14 +1040,14 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
case 'b' :
charptr = va_arg (argptr, char*) ;
count = va_arg (argptr, int) ;
count = va_arg (argptr, size_t) ;
if (count > 0)
byte_count += header_read (psf, charptr, count) ;
break ;
case 'G' :
charptr = va_arg (argptr, char*) ;
count = va_arg (argptr, int) ;
count = va_arg (argptr, size_t) ;
if (count > 0)
byte_count += header_gets (psf, charptr, count) ;
break ;
@@ -1061,14 +1066,14 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
case 'p' :
/* Get the seek position first. */
count = va_arg (argptr, int) ;
count = va_arg (argptr, size_t) ;
header_seek (psf, count, SEEK_SET) ;
byte_count = count ;
break ;
case 'j' :
/* Get the seek position first. */
count = va_arg (argptr, int) ;
count = va_arg (argptr, size_t) ;
header_seek (psf, count, SEEK_CUR) ;
byte_count += count ;
break ;
@@ -1133,7 +1138,7 @@ psf_hexdump (const void *ptr, int len)
printf ("%08X: ", k) ;
for (m = 0 ; m < 16 && k + m < len ; m++)
{ printf (m == 8 ? " %02X " : "%02X ", data [k + m] & 0xFF) ;
ascii [m] = isprint (data [k + m]) ? data [k + m] : '.' ;
ascii [m] = psf_isprint (data [k + m]) ? data [k + m] : '.' ;
} ;
if (m <= 8) printf (" ") ;
@@ -1151,7 +1156,10 @@ psf_log_SF_INFO (SF_PRIVATE *psf)
{ psf_log_printf (psf, "---------------------------------\n") ;
psf_log_printf (psf, " Sample rate : %d\n", psf->sf.samplerate) ;
psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ;
if (psf->sf.frames == SF_COUNT_MAX)
psf_log_printf (psf, " Frames : unknown\n") ;
else
psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ;
psf_log_printf (psf, " Channels : %d\n", psf->sf.channels) ;
psf_log_printf (psf, " Format : 0x%X\n", psf->sf.format) ;
@@ -1208,7 +1216,7 @@ psf_sanitize_string (char * cptr, int len)
do
{
len -- ;
cptr [len] = isprint (cptr [len]) ? cptr [len] : '.' ;
cptr [len] = psf_isprint (cptr [len]) ? cptr [len] : '.' ;
}
while (len > 0) ;
} /* psf_sanitize_string */
@@ -1315,6 +1323,79 @@ psf_rand_int32 (void)
return value ;
} /* psf_rand_int32 */
void
append_snprintf (char * dest, size_t maxlen, const char * fmt, ...)
{ size_t len = strlen (dest) ;
if (len < maxlen)
{ va_list ap ;
va_start (ap, fmt) ;
vsnprintf (dest + len, maxlen - len, fmt, ap) ;
va_end (ap) ;
} ;
return ;
} /* append_snprintf */
void
psf_strlcpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax)
{ /* Must be minus 2 so it can still expand a single trailing '\n' or '\r'. */
char * destend = dest + destmax - 2 ;
const char * srcend = src + srcmax ;
while (dest < destend && src < srcend)
{ if ((src [0] == '\r' && src [1] == '\n') || (src [0] == '\n' && src [1] == '\r'))
{ *dest++ = '\r' ;
*dest++ = '\n' ;
src += 2 ;
continue ;
} ;
if (src [0] == '\r')
{ *dest++ = '\r' ;
*dest++ = '\n' ;
src += 1 ;
continue ;
} ;
if (src [0] == '\n')
{ *dest++ = '\r' ;
*dest++ = '\n' ;
src += 1 ;
continue ;
} ;
*dest++ = *src++ ;
} ;
/* Make sure dest is terminated. */
*dest = 0 ;
} /* psf_strlcpy_crlf */
sf_count_t
psf_decode_frame_count (SF_PRIVATE *psf)
{ sf_count_t count, readlen, total = 0 ;
BUF_UNION ubuf ;
/* If we're reading from a pipe or the file is too long, just return SF_COUNT_MAX. */
if (psf_is_pipe (psf) || psf->datalength > 0x1000000)
return SF_COUNT_MAX ;
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
readlen = ARRAY_LEN (ubuf.ibuf) / psf->sf.channels ;
readlen *= psf->sf.channels ;
while ((count = psf->read_int (psf, ubuf.ibuf, readlen)) > 0)
total += count ;
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
return total / psf->sf.channels ;
} /* psf_decode_frame_count */
/*==============================================================================
*/
@@ -1413,3 +1494,169 @@ str_of_endianness (int end)
/* Zero length string for SF_ENDIAN_FILE. */
return "" ;
} /* str_of_endianness */
/*==============================================================================
*/
void
psf_f2s_array (const float *src, short *dest, int count, int normalize)
{ float normfact ;
normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
while (--count >= 0)
dest [count] = lrintf (src [count] * normfact) ;
return ;
} /* psf_f2s_array */
void
psf_f2s_clip_array (const float *src, short *dest, int count, int normalize)
{ float normfact, scaled_value ;
normfact = normalize ? (1.0 * 0x8000) : 1.0 ;
while (--count >= 0)
{ scaled_value = src [count] * normfact ;
if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF))
{ dest [count] = 0x7FFF ;
continue ;
} ;
if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000))
{ dest [count] = 0x8000 ;
continue ;
} ;
dest [count] = lrintf (scaled_value) ;
} ;
return ;
} /* psf_f2s_clip_array */
void
psf_d2s_array (const double *src, short *dest, int count, int normalize)
{ double normfact ;
normfact = normalize ? (1.0 * 0x7FFF) : 1.0 ;
while (--count >= 0)
dest [count] = lrint (src [count] * normfact) ;
return ;
} /* psf_f2s_array */
void
psf_d2s_clip_array (const double *src, short *dest, int count, int normalize)
{ double normfact, scaled_value ;
normfact = normalize ? (1.0 * 0x8000) : 1.0 ;
while (--count >= 0)
{ scaled_value = src [count] * normfact ;
if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF))
{ dest [count] = 0x7FFF ;
continue ;
} ;
if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000))
{ dest [count] = 0x8000 ;
continue ;
} ;
dest [count] = lrint (scaled_value) ;
} ;
return ;
} /* psf_d2s_clip_array */
void
psf_f2i_array (const float *src, int *dest, int count, int normalize)
{ float normfact ;
normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
while (--count >= 0)
dest [count] = lrintf (src [count] * normfact) ;
return ;
} /* psf_f2i_array */
void
psf_f2i_clip_array (const float *src, int *dest, int count, int normalize)
{ float normfact, scaled_value ;
normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
while (--count >= 0)
{ scaled_value = src [count] * normfact ;
if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
{ dest [count] = 0x7FFFFFFF ;
continue ;
} ;
if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
{ dest [count] = 0x80000000 ;
continue ;
} ;
dest [count] = lrintf (scaled_value) ;
} ;
return ;
} /* psf_f2i_clip_array */
void
psf_d2i_array (const double *src, int *dest, int count, int normalize)
{ double normfact ;
normfact = normalize ? (1.0 * 0x7FFFFFFF) : 1.0 ;
while (--count >= 0)
dest [count] = lrint (src [count] * normfact) ;
return ;
} /* psf_f2i_array */
void
psf_d2i_clip_array (const double *src, int *dest, int count, int normalize)
{ double normfact, scaled_value ;
normfact = normalize ? (8.0 * 0x10000000) : 1.0 ;
while (--count >= 0)
{ scaled_value = src [count] * normfact ;
if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFFFFFF))
{ dest [count] = 0x7FFFFFFF ;
continue ;
} ;
if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x10000000))
{ dest [count] = 0x80000000 ;
continue ;
} ;
dest [count] = lrint (scaled_value) ;
} ;
return ;
} /* psf_d2i_clip_array */
FILE *
psf_open_tmpfile (char * fname, size_t fnamelen)
{ const char * tmpdir ;
FILE * file ;
if (OS_IS_WIN32)
tmpdir = getenv ("TEMP") ;
else
{ tmpdir = getenv ("TMPDIR") ;
tmpdir = tmpdir == NULL ? "/tmp" : tmpdir ;
} ;
// if (tmpdir && access (tmpdir, R_OK | W_OK | X_OK) == 0)
{ snprintf (fname, fnamelen, "%s/%x%x-alac.tmp", tmpdir, psf_rand_int32 (), psf_rand_int32 ()) ;
if ((file = fopen (fname, "wb+")) != NULL)
return file ;
} ;
snprintf (fname, fnamelen, "%x%x-alac.tmp", psf_rand_int32 (), psf_rand_int32 ()) ;
if ((file = fopen (fname, "wb+")) != NULL)
return file ;
memset (fname, 0, fnamelen) ;
return NULL ;
} /* psf_open_tmpfile */
+309 -103
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -22,15 +22,16 @@
#include "sfconfig.h"
#include <stdlib.h>
#include <string.h>
#if HAVE_STDINT_H
#include <stdint.h>
#elif HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifndef SNDFILE_H
#include "sndfile.h"
#elif HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#ifdef __cplusplus
@@ -39,7 +40,9 @@
#if (SIZEOF_LONG == 8)
# define SF_PLATFORM_S64(x) x##l
#elif COMPILER_IS_GCC || __SUNPRO_C
#elif (SIZEOF_LONG_LONG == 8)
# define SF_PLATFORM_S64(x) x##ll
#elif COMPILER_IS_GCC
# define SF_PLATFORM_S64(x) x##ll
#elif OS_IS_WIN32
# define SF_PLATFORM_S64(x) x##I64
@@ -67,16 +70,15 @@
# define WARN_UNUSED
#endif
#define SF_BUFFER_LEN (8192*2)
#define SF_BUFFER_LEN (8192)
#define SF_FILENAME_LEN (512)
#define SF_SYSERR_LEN (256)
#define SF_MAX_STRINGS (32)
#define SF_STR_BUFFER_LEN (8192)
#define SF_HEADER_LEN (4100 + SF_STR_BUFFER_LEN)
#define SF_HEADER_LEN (12292)
#define SF_PARSELOG_LEN (2048)
#define PSF_SEEK_ERROR ((sf_count_t) -1)
#define BITWIDTH2BYTES(x) (((x) + 7) / 8)
/* For some reason sizeof returns an unsigned value which causes
@@ -87,32 +89,40 @@
#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
#define NOT(x) (! (x))
#if (COMPILER_IS_GCC == 1)
#define SF_MAX(x,y) ({ \
#define SF_MAX(x, y) ({ \
typeof (x) sf_max_x1 = (x) ; \
typeof (y) sf_max_y1 = (y) ; \
(void) (&sf_max_x1 == &sf_max_y1) ; \
sf_max_x1 > sf_max_y1 ? sf_max_x1 : sf_max_y1 ; })
#define SF_MIN(x,y) ({ \
#define SF_MIN(x, y) ({ \
typeof (x) sf_min_x2 = (x) ; \
typeof (y) sf_min_y2 = (y) ; \
(void) (&sf_min_x2 == &sf_min_y2) ; \
sf_min_x2 < sf_min_y2 ? sf_min_x2 : sf_min_y2 ; })
#else
#define SF_MAX(a,b) ((a) > (b) ? (a) : (b))
#define SF_MIN(a,b) ((a) < (b) ? (a) : (b))
#define SF_MAX(a, b) ((a) > (b) ? (a) : (b))
#define SF_MIN(a, b) ((a) < (b) ? (a) : (b))
#endif
#define COMPILE_TIME_ASSERT(e) (sizeof (struct { int : - !! (e) ; }))
#define SF_MAX_CHANNELS 256
/*
* Macros for spliting the format file of SF_INFI into contrainer type,
* Macros for spliting the format file of SF_INFO into container type,
** codec type and endian-ness.
*/
#define SF_CONTAINER(x) ((x) & SF_FORMAT_TYPEMASK)
#define SF_CODEC(x) ((x) & SF_FORMAT_SUBMASK)
#define SF_ENDIAN(x) ((x) & SF_FORMAT_ENDMASK)
enum
{ /* PEAK chunk location. */
SF_PEAK_START = 42,
@@ -143,6 +153,8 @@ enum
enum
{ /* Work in progress. */
SF_FORMAT_SPEEX = 0x5000000,
SF_FORMAT_OGGFLAC = 0x5000001,
/* Formats supported read only. */
SF_FORMAT_TXW = 0x4030000, /* Yamaha TX16 sampler file */
@@ -162,6 +174,22 @@ enum
SF_FORMAT_PCM_N = 0x1030
} ;
/*---------------------------------------------------------------------------------------
*/
typedef struct
{ unsigned kuki_offset ;
unsigned pakt_offset ;
unsigned bits_per_sample ;
unsigned frames_per_packet ;
int64_t packets ;
int64_t valid_frames ;
int32_t priming_frames ;
int32_t remainder_frames ;
} ALAC_DECODER_INFO ;
/*---------------------------------------------------------------------------------------
** PEAK_CHUNK - This chunk type is common to both AIFF and WAVE files although their
** endian encodings are different.
@@ -183,19 +211,8 @@ typedef struct
/* CAF */
unsigned int edit_number ;
#if HAVE_FLEXIBLE_ARRAY
/* the per channel peak info */
PEAK_POS peaks [] ;
#else
/*
** This is not ISO compliant C. It works on some compilers which
** don't support the ISO standard flexible struct array which is
** used above. If your compiler doesn't like this I suggest you find
** youself a 1999 ISO C standards compilant compiler. GCC-3.X is
** highly recommended.
*/
PEAK_POS peaks [0] ;
#endif
} PEAK_INFO ;
static inline PEAK_INFO *
@@ -206,94 +223,180 @@ peak_info_calloc (int channels)
typedef struct
{ int type ;
int flags ;
char *str ;
size_t offset ;
} STR_DATA ;
typedef struct
{ int64_t hash ;
char id [64] ;
unsigned id_size ;
uint32_t mark32 ;
sf_count_t offset ;
uint32_t len ;
} READ_CHUNK ;
typedef struct
{ int64_t hash ;
uint32_t mark32 ;
uint32_t len ;
void *data ;
} WRITE_CHUNK ;
typedef struct
{ uint32_t count ;
uint32_t used ;
READ_CHUNK *chunks ;
} READ_CHUNKS ;
typedef struct
{ uint32_t count ;
uint32_t used ;
WRITE_CHUNK *chunks ;
} WRITE_CHUNKS ;
struct SF_CHUNK_ITERATOR
{ uint32_t current ;
int64_t hash ;
char id [64] ;
unsigned id_size ;
SNDFILE *sndfile ;
} ;
static inline size_t
make_size_t (int x)
{ return (size_t) x ;
} /* size_t_of_int */
typedef SF_BROADCAST_INFO_VAR (16 * 1024) SF_BROADCAST_INFO_16K ;
typedef SF_CART_INFO_VAR (16 * 1024) SF_CART_INFO_16K ;
#if SIZEOF_WCHAR_T == 2
typedef wchar_t sfwchar_t ;
#else
typedef int16_t sfwchar_t ;
#endif
static inline void *
psf_memdup (const void *src, size_t n)
{ void * mem = calloc (1, n & 3 ? n + 4 - (n & 3) : n) ;
return memcpy (mem, src, n) ;
} /* psf_memdup */
/*
** This version of isprint specifically ignores any locale info. Its used for
** determining which characters can be printed in things like hexdumps.
*/
static inline int
psf_isprint (int ch)
{ return (ch >= ' ' && ch <= '~') ;
} /* psf_isprint */
/*=======================================================================================
** SF_PRIVATE stuct - a pointer to this struct is passed back to the caller of the
** sf_open_XXXX functions. The caller however has no knowledge of the struct's
** contents.
*/
typedef struct
{ int size ;
SF_BROADCAST_INFO binfo ;
} SF_BROADCAST_VAR ;
typedef struct sf_private_tag
{
/* Canary in a coal mine. */
char canary [64] ;
/* Force the compiler to double align the start of buffer. */
union
{ double dbuf [SF_BUFFER_LEN / sizeof (double)] ;
#if (defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
int64_t lbuf [SF_BUFFER_LEN / sizeof (int64_t)] ;
#else
long lbuf [SF_BUFFER_LEN / sizeof (double)] ;
#endif
float fbuf [SF_BUFFER_LEN / sizeof (float)] ;
int ibuf [SF_BUFFER_LEN / sizeof (int)] ;
short sbuf [SF_BUFFER_LEN / sizeof (short)] ;
char cbuf [SF_BUFFER_LEN / sizeof (char)] ;
signed char scbuf [SF_BUFFER_LEN / sizeof (signed char)] ;
unsigned char ucbuf [SF_BUFFER_LEN / sizeof (signed char)] ;
} u ;
{ char c [SF_FILENAME_LEN] ;
sfwchar_t wc [SF_FILENAME_LEN] ;
} path ;
char filepath [SF_FILENAME_LEN] ;
char rsrcpath [SF_FILENAME_LEN] ;
char directory [SF_FILENAME_LEN] ;
char filename [SF_FILENAME_LEN / 4] ;
union
{ char c [SF_FILENAME_LEN] ;
sfwchar_t wc [SF_FILENAME_LEN] ;
} dir ;
char syserr [SF_SYSERR_LEN] ;
/* logbuffer and logindex should only be changed within the logging functions
** of common.c
*/
char logbuffer [SF_BUFFER_LEN] ;
unsigned char header [SF_HEADER_LEN] ; /* Must be unsigned */
int rwf_endian ; /* Header endian-ness flag. */
/* Storage and housekeeping data for adding/reading strings from
** sound files.
*/
STR_DATA strings [SF_MAX_STRINGS] ;
char str_storage [SF_STR_BUFFER_LEN] ;
char *str_end ;
int str_flags ;
/* Guard value. If this changes the buffers above have overflowed. */
int Magick ;
unsigned unique_id ;
/* Index variables for maintaining logbuffer and header above. */
int logindex ;
int headindex, headend ;
int has_text ;
int do_not_close_descriptor ;
union
{ char c [SF_FILENAME_LEN / 4] ;
sfwchar_t wc [SF_FILENAME_LEN / 4] ;
} name ;
#if USE_WINDOWS_API
/*
** These fields can only be used in src/file_io.c.
** They are basically the same as a windows file HANDLE.
*/
void *hfile, *hrsrc, *hsaved ;
void *handle, *hsaved ;
int use_wchar ;
#else
/* These fields can only be used in src/file_io.c. */
int filedes, rsrcdes, savedes ;
int filedes, savedes ;
#endif
int do_not_close_descriptor ;
int mode ; /* Open mode : SFM_READ, SFM_WRITE or SFM_RDWR. */
} PSF_FILE ;
typedef union
{ double dbuf [SF_BUFFER_LEN / sizeof (double)] ;
#if (defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
int64_t lbuf [SF_BUFFER_LEN / sizeof (int64_t)] ;
#else
long lbuf [SF_BUFFER_LEN / sizeof (double)] ;
#endif
float fbuf [SF_BUFFER_LEN / sizeof (float)] ;
int ibuf [SF_BUFFER_LEN / sizeof (int)] ;
short sbuf [SF_BUFFER_LEN / sizeof (short)] ;
char cbuf [SF_BUFFER_LEN / sizeof (char)] ;
signed char scbuf [SF_BUFFER_LEN / sizeof (signed char)] ;
unsigned char ucbuf [SF_BUFFER_LEN / sizeof (signed char)] ;
} BUF_UNION ;
typedef struct sf_private_tag
{
/* Canary in a coal mine. */
union
{ /* Place a double here to encourage double alignment. */
double d [2] ;
char c [16] ;
} canary ;
PSF_FILE file, rsrc ;
char syserr [SF_SYSERR_LEN] ;
/* parselog and indx should only be changed within the logging functions
** of common.c
*/
struct
{ char buf [SF_PARSELOG_LEN] ;
int indx ;
} parselog ;
unsigned char header [SF_HEADER_LEN] ; /* Must be unsigned */
int rwf_endian ; /* Header endian-ness flag. */
/* Storage and housekeeping data for adding/reading strings from
** sound files.
*/
struct
{ STR_DATA data [SF_MAX_STRINGS] ;
char *storage ;
size_t storage_len ;
size_t storage_used ;
uint32_t flags ;
} strings ;
/* Guard value. If this changes the buffers above have overflowed. */
int Magick ;
unsigned unique_id ;
/* Index variables for maintaining parselog and header above. */
int headindex, headend ;
int has_text ;
int error ;
int mode ; /* Open mode : SFM_READ, SFM_WRITE or SFM_RDWR. */
int endian ; /* File endianness : SF_ENDIAN_LITTLE or SF_ENDIAN_BIG. */
int data_endswap ; /* Need to endswap data? */
@@ -323,7 +426,10 @@ typedef struct sf_private_tag
SF_INSTRUMENT *instrument ;
/* Broadcast (EBU) Info */
SF_BROADCAST_VAR *broadcast_var ;
SF_BROADCAST_INFO_16K *broadcast_16k ;
/* Cart (AES46) Info */
SF_CART_INFO_16K *cart_16k ;
/* Channel map data (if present) : an array of ints. */
int *channel_map ;
@@ -379,6 +485,7 @@ typedef struct sf_private_tag
sf_count_t (*seek) (struct sf_private_tag*, int mode, sf_count_t samples_from_start) ;
int (*write_header) (struct sf_private_tag*, int calc_length) ;
int (*command) (struct sf_private_tag*, int command, void *data, int datasize) ;
int (*byterate) (struct sf_private_tag*) ;
/*
** Separate close functions for the codec and the container.
@@ -393,6 +500,17 @@ typedef struct sf_private_tag
int virtual_io ;
SF_VIRTUAL_IO vio ;
void *vio_user_data ;
/* Chunk get/set. */
SF_CHUNK_ITERATOR *iterator ;
READ_CHUNKS rchunks ;
WRITE_CHUNKS wchunks ;
int (*set_chunk) (struct sf_private_tag*, const SF_CHUNK_INFO * chunk_info) ;
SF_CHUNK_ITERATOR * (*next_chunk_iterator) (struct sf_private_tag*, SF_CHUNK_ITERATOR * iterator) ;
int (*get_chunk_size) (struct sf_private_tag*, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ;
int (*get_chunk_data) (struct sf_private_tag*, const SF_CHUNK_ITERATOR * iterator, SF_CHUNK_INFO * chunk_info) ;
} SF_PRIVATE ;
@@ -415,6 +533,7 @@ enum
SFE_BAD_FILE_PTR,
SFE_BAD_INT_PTR,
SFE_BAD_STAT_SIZE,
SFE_NO_TEMP_DIR,
SFE_MALLOC_FAILED,
SFE_UNIMPLEMENTED,
SFE_BAD_READ_ALIGN,
@@ -453,6 +572,9 @@ enum
SFE_RDWR_BAD_HEADER,
SFE_CMD_HAS_DATA,
SFE_BAD_BROADCAST_INFO_SIZE,
SFE_BAD_BROADCAST_INFO_TOO_BIG,
SFE_BAD_CART_INFO_SIZE,
SFE_BAD_CART_INFO_TOO_BIG,
SFE_STR_NO_SUPPORT,
SFE_STR_NOT_WRITE,
@@ -506,6 +628,7 @@ enum
SFE_PAF_VERSION,
SFE_PAF_UNKNOWN_FORMAT,
SFE_PAF_SHORT_HEADER,
SFE_PAF_BAD_CHANNELS,
SFE_SVX_NO_FORM,
SFE_SVX_NO_BODY,
@@ -584,6 +707,13 @@ enum
SFE_VORBIS_ENCODER_BUG,
SFE_RF64_NOT_RF64,
SFE_BAD_CHUNK_PTR,
SFE_UNKNOWN_CHUNK,
SFE_BAD_CHUNK_FORMAT,
SFE_BAD_CHUNK_MARKER,
SFE_BAD_CHUNK_DATA_PTR,
SFE_ALAC_FAIL_TMPFILE,
SFE_MAX_ERROR /* This must be last in list. */
} ;
@@ -595,13 +725,13 @@ int u_bitwidth_to_subformat (int bits) ;
/* Functions for reading and writing floats and doubles on processors
** with non-IEEE floats/doubles.
*/
float float32_be_read (unsigned char *cptr) ;
float float32_le_read (unsigned char *cptr) ;
float float32_be_read (const unsigned char *cptr) ;
float float32_le_read (const unsigned char *cptr) ;
void float32_be_write (float in, unsigned char *out) ;
void float32_le_write (float in, unsigned char *out) ;
double double64_be_read (unsigned char *cptr) ;
double double64_le_read (unsigned char *cptr) ;
double double64_be_read (const unsigned char *cptr) ;
double double64_le_read (const unsigned char *cptr) ;
void double64_be_write (double in, unsigned char *out) ;
void double64_le_write (double in, unsigned char *out) ;
@@ -612,6 +742,11 @@ void psf_log_SF_INFO (SF_PRIVATE *psf) ;
int32_t psf_rand_int32 (void) ;
void append_snprintf (char * dest, size_t maxlen, const char * fmt, ...) ;
void psf_strlcpy_crlf (char *dest, const char *src, size_t destmax, size_t srcmax) ;
sf_count_t psf_decode_frame_count (SF_PRIVATE *psf) ;
/* Functions used when writing file headers. */
int psf_binheader_writef (SF_PRIVATE *psf, const char *format, ...) ;
@@ -665,13 +800,15 @@ int macos_guess_file_type (SF_PRIVATE *psf, const char *filename) ;
** some 32 bit OSes. Implementation in file_io.c.
*/
int psf_fopen (SF_PRIVATE *psf, const char *pathname, int flags) ;
int psf_set_stdio (SF_PRIVATE *psf, int mode) ;
int psf_fopen (SF_PRIVATE *psf) ;
int psf_set_stdio (SF_PRIVATE *psf) ;
int psf_file_valid (SF_PRIVATE *psf) ;
void psf_set_file (SF_PRIVATE *psf, int fd) ;
void psf_init_files (SF_PRIVATE *psf) ;
void psf_use_rsrc (SF_PRIVATE *psf, int on_off) ;
SNDFILE * psf_open_file (SF_PRIVATE *psf, SF_INFO *sfinfo) ;
sf_count_t psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence) ;
sf_count_t psf_fread (void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
sf_count_t psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t count, SF_PRIVATE *psf) ;
@@ -687,7 +824,7 @@ int psf_ftruncate (SF_PRIVATE *psf, sf_count_t len) ;
int psf_fclose (SF_PRIVATE *psf) ;
/* Open and close the resource fork of a file. */
int psf_open_rsrc (SF_PRIVATE *psf, int mode) ;
int psf_open_rsrc (SF_PRIVATE *psf) ;
int psf_close_rsrc (SF_PRIVATE *psf) ;
/*
@@ -722,10 +859,16 @@ int caf_open (SF_PRIVATE *psf) ;
int mpc2k_open (SF_PRIVATE *psf) ;
int rf64_open (SF_PRIVATE *psf) ;
int ogg_vorbis_open (SF_PRIVATE *psf) ;
int ogg_speex_open (SF_PRIVATE *psf) ;
int ogg_pcm_open (SF_PRIVATE *psf) ;
int ogg_opus_open (SF_PRIVATE *psf) ;
int ogg_open (SF_PRIVATE *psf) ;
/* In progress. Do not currently work. */
int mpeg_open (SF_PRIVATE *psf) ;
int ogg_open (SF_PRIVATE *psf) ;
int rx2_open (SF_PRIVATE *psf) ;
int txw_open (SF_PRIVATE *psf) ;
int wve_open (SF_PRIVATE *psf) ;
@@ -747,6 +890,7 @@ int gsm610_init (SF_PRIVATE *psf) ;
int vox_adpcm_init (SF_PRIVATE *psf) ;
int flac_init (SF_PRIVATE *psf) ;
int g72x_init (SF_PRIVATE * psf) ;
int alac_init (SF_PRIVATE *psf, const ALAC_DECODER_INFO * info) ;
int dither_init (SF_PRIVATE *psf, int mode) ;
@@ -761,18 +905,51 @@ int interleave_init (SF_PRIVATE *psf) ;
** Chunk logging functions.
*/
typedef struct
{ struct
{ int chunk ;
sf_count_t offset ;
sf_count_t len ;
} l [100] ;
SF_CHUNK_ITERATOR * psf_get_chunk_iterator (SF_PRIVATE * psf, const char * marker_str) ;
SF_CHUNK_ITERATOR * psf_next_chunk_iterator (const READ_CHUNKS * pchk , SF_CHUNK_ITERATOR *iterator) ;
int psf_store_read_chunk_u32 (READ_CHUNKS * pchk, uint32_t marker, sf_count_t offset, uint32_t len) ;
int psf_store_read_chunk_str (READ_CHUNKS * pchk, const char * marker, sf_count_t offset, uint32_t len) ;
int psf_save_write_chunk (WRITE_CHUNKS * pchk, const SF_CHUNK_INFO * chunk_info) ;
int psf_find_read_chunk_str (const READ_CHUNKS * pchk, const char * marker) ;
int psf_find_read_chunk_m32 (const READ_CHUNKS * pchk, uint32_t marker) ;
int psf_find_read_chunk_iterator (const READ_CHUNKS * pchk, const SF_CHUNK_ITERATOR * marker) ;
int count ;
} PRIV_CHUNK4 ;
int psf_find_write_chunk (WRITE_CHUNKS * pchk, const char * marker) ;
void pchk4_store (PRIV_CHUNK4 * pchk, int marker, sf_count_t offset, sf_count_t len) ;
int pchk4_find (PRIV_CHUNK4 * pchk, int marker) ;
static inline int
fourcc_to_marker (const SF_CHUNK_INFO * chunk_info)
{ const unsigned char * cptr ;
if (chunk_info->id_size != 4)
return 0 ;
cptr = (const unsigned char *) chunk_info->id ;
return (cptr [3] << 24) + (cptr [2] << 16) + (cptr [1] << 8) + cptr [0] ;
} /* fourcc_to_marker */
/*------------------------------------------------------------------------------------
** Functions that work like OpenBSD's strlcpy/strlcat to replace strncpy/strncat.
**
** See : http://www.gratisoft.us/todd/papers/strlcpy.html
**
** These functions are available on *BSD, but are not avaialble everywhere so we
** implement them here.
**
** The argument order has been changed to that of strncpy/strncat to cause
** compiler errors if code is carelessly converted from one to the other.
*/
static inline void
psf_strlcat (char *dest, size_t n, const char *src)
{ strncat (dest, src, n - strlen (dest) - 1) ;
dest [n - 1] = 0 ;
} /* psf_strlcat */
static inline void
psf_strlcpy (char *dest, size_t n, const char *src)
{ strncpy (dest, src, n - 1) ;
dest [n - 1] = 0 ;
} /* psf_strlcpy */
/*------------------------------------------------------------------------------------
** Other helper functions.
@@ -787,18 +964,26 @@ void psf_sanitize_string (char * cptr, int len) ;
/* Generate the current date as a string. */
void psf_get_date_str (char *str, int maxlen) ;
SF_BROADCAST_VAR* broadcast_var_alloc (size_t datasize) ;
SF_BROADCAST_INFO_16K * broadcast_var_alloc (void) ;
int broadcast_var_set (SF_PRIVATE *psf, const SF_BROADCAST_INFO * data, size_t datasize) ;
int broadcast_var_get (SF_PRIVATE *psf, SF_BROADCAST_INFO * data, size_t datasize) ;
SF_CART_INFO_16K * cart_var_alloc (void) ;
int cart_var_set (SF_PRIVATE *psf, const SF_CART_INFO * date, size_t datasize) ;
int cart_var_get (SF_PRIVATE *psf, SF_CART_INFO * data, size_t datasize) ;
typedef struct
{ int channels ;
int endianness ;
} AUDIO_DETECT ;
int audio_detect (SF_PRIVATE * psf, AUDIO_DETECT *ad, const unsigned char * data, int datalen) ;
int id3_skip (SF_PRIVATE * psf) ;
void alac_get_desc_chunk_items (int subformat, uint32_t *fmt_flags, uint32_t *frames_per_packet) ;
FILE * psf_open_tmpfile (char * fname, size_t fnamelen) ;
/*------------------------------------------------------------------------------------
** Helper/debug functions.
@@ -834,5 +1019,26 @@ int sf_dither_float (const SF_DITHER_INFO *dither, const float *in, float *out,
int sf_dither_double (const SF_DITHER_INFO *dither, const double *in, double *out, int count) ;
#endif
/*------------------------------------------------------------------------------------
** Data conversion functions.
*/
static inline short
psf_short_of_int (int x)
{ return (x >> 16) ;
}
void psf_f2s_array (const float *src, short *dest, int count, int normalize) ;
void psf_f2s_clip_array (const float *src, short *dest, int count, int normalize) ;
void psf_d2s_array (const double *src, short *dest, int count, int normalize) ;
void psf_d2s_clip_array (const double *src, short *dest, int count, int normalize) ;
void psf_f2i_array (const float *src, int *dest, int count, int normalize) ;
void psf_f2i_clip_array (const float *src, int *dest, int count, int normalize) ;
void psf_d2i_array (const double *src, int *dest, int count, int normalize) ;
void psf_d2i_clip_array (const double *src, int *dest, int count, int normalize) ;
#endif /* SNDFILE_COMMON_H */
+95 -74
View File
@@ -1,6 +1,6 @@
#!/usr/bin/python
# Copyright (C) 2003-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
# Copyright (C) 2003-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
#
# All rights reserved.
#
@@ -39,89 +39,107 @@ import re, sys
# the ordinal values in the second column.
ALL_SYMBOLS = (
( "sf_command", 1 ),
( "sf_open", 2 ),
( "sf_close", 3 ),
( "sf_seek", 4 ),
( "sf_error", 7 ),
( "sf_perror", 8 ),
( "sf_error_str", 9 ),
( "sf_error_number", 10 ),
( "sf_format_check", 11 ),
( "sf_read_raw", 16 ),
( "sf_readf_short", 17 ),
( "sf_readf_int", 18 ),
( "sf_readf_float", 19 ),
( "sf_readf_double", 20 ),
( "sf_read_short", 21 ),
( "sf_read_int", 22 ),
( "sf_read_float", 23 ),
( "sf_read_double", 24 ),
( "sf_write_raw", 32 ),
( "sf_writef_short", 33 ),
( "sf_writef_int", 34 ),
( "sf_writef_float", 35 ),
( "sf_writef_double", 36 ),
( "sf_write_short", 37 ),
( "sf_write_int", 38 ),
( "sf_write_float", 39 ),
( "sf_write_double", 40 ),
( "sf_strerror", 50 ),
( "sf_get_string", 60 ),
( "sf_set_string", 61 ),
( "sf_open_fd", 70 ),
( "sf_open_virtual", 80 ),
( "sf_write_sync", 90 )
( "sf_command", 1 ),
( "sf_open", 2 ),
( "sf_close", 3 ),
( "sf_seek", 4 ),
( "sf_error", 7 ),
( "sf_perror", 8 ),
( "sf_error_str", 9 ),
( "sf_error_number", 10 ),
( "sf_format_check", 11 ),
( "sf_read_raw", 16 ),
( "sf_readf_short", 17 ),
( "sf_readf_int", 18 ),
( "sf_readf_float", 19 ),
( "sf_readf_double", 20 ),
( "sf_read_short", 21 ),
( "sf_read_int", 22 ),
( "sf_read_float", 23 ),
( "sf_read_double", 24 ),
( "sf_write_raw", 32 ),
( "sf_writef_short", 33 ),
( "sf_writef_int", 34 ),
( "sf_writef_float", 35 ),
( "sf_writef_double", 36 ),
( "sf_write_short", 37 ),
( "sf_write_int", 38 ),
( "sf_write_float", 39 ),
( "sf_write_double", 40 ),
( "sf_strerror", 50 ),
( "sf_get_string", 60 ),
( "sf_set_string", 61 ),
( "sf_version_string", 68 ),
( "sf_open_fd", 70 ),
( "sf_wchar_open", 71 ),
( "sf_open_virtual", 80 ),
( "sf_write_sync", 90 ),
( "sf_set_chunk", 100 ),
( "sf_get_chunk_size", 101 ),
( "sf_get_chunk_data", 102 ),
( "sf_get_chunk_iterator", 103 ),
( "sf_next_chunk_iterator", 104 ),
( "sf_current_byterate", 110 )
)
#-------------------------------------------------------------------------------
def linux_symbols (progname, version):
print "# Auto-generated by %s\n" %progname
print "libsndfile.so.%s" % version
print "{"
print " global:"
print ("# Auto-generated by %s\n" %progname)
print ("libsndfile.so.%s" % version)
print ("{")
print (" global:")
for name, ordinal in ALL_SYMBOLS:
print " %s ;" % name
print " local:"
print " * ;"
print "} ;"
print
if name == "sf_wchar_open":
continue
print (" %s ;" % name)
print (" local:")
print (" * ;")
print ("} ;")
sys.stdout.write ("\n")
return
def darwin_symbols (progname, version):
print "# Auto-generated by %s\n" %progname
print ("# Auto-generated by %s\n" %progname)
for name, ordinal in ALL_SYMBOLS:
print "_%s" % name
print
if name == "sf_wchar_open":
continue
print ("_%s" % name)
sys.stdout.write ("\n")
return
def win32_symbols (progname, version, name):
print "; Auto-generated by %s\n" %progname
print "LIBRARY %s-%s.dll" % (name, re.sub ("\..*", "", version))
print "EXPORTS\n"
print ("; Auto-generated by %s\n" %progname)
print ("LIBRARY %s-%s.dll" % (name, re.sub ("\..*", "", version)))
print ("EXPORTS\n")
for name, ordinal in ALL_SYMBOLS:
print "%-20s @%s" % (name, ordinal)
print
print ("%-20s @%s" % (name, ordinal))
sys.stdout.write ("\n")
return
def os2_symbols (progname, version, name):
print "; Auto-generated by %s\n" %progname
print "LIBRARY %s%s.dll" % (name, re.sub ("\..*", "", version))
print "INITINSTANCE TERMINSTANCE"
print "CODE PRELOAD MOVEABLE DISCARDABLE"
print "DATA PRELOAD MOVEABLE MULTIPLE NONSHARED"
print "EXPORTS\n"
print ("; Auto-generated by %s\n" %progname)
print ("LIBRARY %s%s" % (name, re.sub ("\..*", "", version)))
print ("INITINSTANCE TERMINSTANCE")
print ("CODE PRELOAD MOVEABLE DISCARDABLE")
print ("DATA PRELOAD MOVEABLE MULTIPLE NONSHARED")
print ("EXPORTS\n")
for name, ordinal in ALL_SYMBOLS:
print "_%-20s @%s" % (name, ordinal)
print
if name == "sf_wchar_open":
continue
print ("_%-20s @%s" % (name, ordinal))
sys.stdout.write ("\n")
return
def plain_symbols (progname, version, name):
for name, ordinal in ALL_SYMBOLS:
print (name)
def no_symbols (os_name):
print
print "No known way of restricting exported symbols on '%s'." % os_name
print "If you know a way, please contact the author."
print
sys.stdout.write ("\n")
print ("No known way of restricting exported symbols on '%s'." % os_name)
print ("If you know a way, please contact the author.")
sys.stdout.write ("\n")
return
#-------------------------------------------------------------------------------
@@ -129,22 +147,23 @@ def no_symbols (os_name):
progname = re.sub (".*[\\/]", "", sys.argv [0])
if len (sys.argv) != 3:
print
print "Usage : %s <target OS name> <libsndfile version>." % progname
print
print " Currently supported values for target OS are:"
print " linux"
print " darwin (ie MacOSX)"
print " win32 (ie wintendo)"
print " cygwin (Cygwin on wintendo)"
print " os2 (OS/2)"
print
sys.stdout.write ("\n")
print ("Usage : %s <target OS name> <libsndfile version>." % progname)
sys.stdout.write ("\n")
print (" Currently supported values for target OS are:")
print (" linux")
print (" darwin (ie MacOSX)")
print (" win32 (ie wintendo)")
print (" cygwin (Cygwin on wintendo)")
print (" os2 (OS/2)")
print (" plain (plain list of symbols)")
sys.stdout.write ("\n")
sys.exit (1)
os_name = sys.argv [1]
version = re.sub ("\.[a-z0-9]+$", "", sys.argv [2])
if os_name == "linux":
if os_name == "linux" or os_name == "gnu" or os_name == "binutils":
linux_symbols (progname, version)
elif os_name == "darwin":
darwin_symbols (progname, version)
@@ -154,6 +173,8 @@ elif os_name == "cygwin":
win32_symbols (progname, version, "cygsndfile")
elif os_name == "os2":
os2_symbols (progname, version, "sndfile")
elif os_name == "static":
plain_symbols (progname, version, "")
else:
no_symbols (os_name)
+1 -1
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2003-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
+107 -92
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -95,7 +95,7 @@ double64_init (SF_PRIVATE *psf)
psf->blockwidth = sizeof (double) * psf->sf.channels ;
if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ switch (psf->endian + double64_caps)
{ case (SF_ENDIAN_BIG + DOUBLE_CAN_RW_BE) :
psf->data_endswap = SF_FALSE ;
@@ -166,7 +166,7 @@ double64_init (SF_PRIVATE *psf)
} ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ switch (psf->endian + double64_caps)
{ case (SF_ENDIAN_LITTLE + DOUBLE_CAN_RW_LE) :
psf->data_endswap = SF_FALSE ;
@@ -276,7 +276,7 @@ double64_init (SF_PRIVATE *psf)
*/
double
double64_be_read (unsigned char *cptr)
double64_be_read (const unsigned char *cptr)
{ int exponent, negative, upper, lower ;
double dvalue ;
@@ -309,7 +309,7 @@ double64_be_read (unsigned char *cptr)
} /* double64_be_read */
double
double64_le_read (unsigned char *cptr)
double64_le_read (const unsigned char *cptr)
{ int exponent, negative, upper, lower ;
double dvalue ;
@@ -554,24 +554,25 @@ f2d_array (const float *src, double *dest, int count)
static sf_count_t
host_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ void (*convert) (const double *, int, short *, double) ;
{ BUF_UNION ubuf ;
void (*convert) (const double *, int, short *, double) ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
double scale ;
convert = (psf->add_clipping) ? d2s_clip_array : d2s_array ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, readcount) ;
endswap_double_array (ubuf.dbuf, readcount) ;
convert (psf->u.dbuf, readcount, ptr + total, scale) ;
convert (ubuf.dbuf, readcount, ptr + total, scale) ;
total += readcount ;
len -= readcount ;
if (readcount < bufferlen)
@@ -583,24 +584,25 @@ host_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
static sf_count_t
host_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ void (*convert) (const double *, int, int *, double) ;
{ BUF_UNION ubuf ;
void (*convert) (const double *, int, int *, double) ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
double scale ;
convert = (psf->add_clipping) ? d2i_clip_array : d2i_array ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
convert (psf->u.dbuf, readcount, ptr + total, scale) ;
convert (ubuf.dbuf, readcount, ptr + total, scale) ;
total += readcount ;
len -= readcount ;
if (readcount < bufferlen)
@@ -612,20 +614,21 @@ host_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
host_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
d2f_array (psf->u.dbuf, readcount, ptr + total) ;
d2f_array (ubuf.dbuf, readcount, ptr + total) ;
total += readcount ;
len -= readcount ;
if (readcount < bufferlen)
@@ -667,26 +670,27 @@ host_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
static sf_count_t
host_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
double scale ;
scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / 0x8000 ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
s2d_array (ptr + total, psf->u.dbuf, bufferlen, scale) ;
s2d_array (ptr + total, ubuf.dbuf, bufferlen, scale) ;
if (psf->peak_info)
double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
double64_peak_update (psf, ubuf.dbuf, bufferlen, total / psf->sf.channels) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -698,25 +702,26 @@ host_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
static sf_count_t
host_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
double scale ;
scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
i2d_array (ptr + total, psf->u.dbuf, bufferlen, scale) ;
i2d_array (ptr + total, ubuf.dbuf, bufferlen, scale) ;
if (psf->peak_info)
double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
double64_peak_update (psf, ubuf.dbuf, bufferlen, total / psf->sf.channels) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -728,23 +733,24 @@ host_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
host_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
f2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
f2d_array (ptr + total, ubuf.dbuf, bufferlen) ;
if (psf->peak_info)
double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
double64_peak_update (psf, ubuf.dbuf, bufferlen, total / psf->sf.channels) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -756,7 +762,8 @@ host_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
host_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
if (psf->peak_info)
@@ -765,15 +772,15 @@ host_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
if (psf->data_endswap != SF_TRUE)
return psf_fwrite (ptr, sizeof (double), len, psf) ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
endswap_double_copy (psf->u.dbuf, ptr + total, bufferlen) ;
endswap_double_copy (ubuf.dbuf, ptr + total, bufferlen) ;
writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -788,24 +795,25 @@ host_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
static sf_count_t
replace_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
double scale ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
d2bd_read (psf->u.dbuf, bufferlen) ;
d2bd_read (ubuf.dbuf, bufferlen) ;
d2s_array (psf->u.dbuf, readcount, ptr + total, scale) ;
d2s_array (ubuf.dbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -817,24 +825,25 @@ replace_read_d2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
static sf_count_t
replace_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
double scale ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
d2bd_read (psf->u.dbuf, bufferlen) ;
d2bd_read (ubuf.dbuf, bufferlen) ;
d2i_array (psf->u.dbuf, readcount, ptr + total, scale) ;
d2i_array (ubuf.dbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -846,22 +855,23 @@ replace_read_d2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
replace_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
d2bd_read (psf->u.dbuf, bufferlen) ;
d2bd_read (ubuf.dbuf, bufferlen) ;
memcpy (ptr + total, psf->u.dbuf, bufferlen * sizeof (double)) ;
memcpy (ptr + total, ubuf.dbuf, bufferlen * sizeof (double)) ;
total += readcount ;
if (readcount < bufferlen)
@@ -874,23 +884,24 @@ replace_read_d2f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
replace_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
/* FIXME : This is probably nowhere near optimal. */
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
readcount = psf_fread (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, readcount) ;
endswap_double_array (ubuf.dbuf, readcount) ;
d2bd_read (psf->u.dbuf, readcount) ;
d2bd_read (ubuf.dbuf, readcount) ;
memcpy (ptr + total, psf->u.dbuf, readcount * sizeof (double)) ;
memcpy (ptr + total, ubuf.dbuf, readcount * sizeof (double)) ;
total += readcount ;
if (readcount < bufferlen)
@@ -903,27 +914,28 @@ replace_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
static sf_count_t
replace_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
double scale ;
scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / 0x8000 ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
s2d_array (ptr + total, psf->u.dbuf, bufferlen, scale) ;
s2d_array (ptr + total, ubuf.dbuf, bufferlen, scale) ;
if (psf->peak_info)
double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
double64_peak_update (psf, ubuf.dbuf, bufferlen, total / psf->sf.channels) ;
bd2d_write (psf->u.dbuf, bufferlen) ;
bd2d_write (ubuf.dbuf, bufferlen) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -935,27 +947,28 @@ replace_write_s2d (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
static sf_count_t
replace_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
double scale ;
scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
i2d_array (ptr + total, psf->u.dbuf, bufferlen, scale) ;
i2d_array (ptr + total, ubuf.dbuf, bufferlen, scale) ;
if (psf->peak_info)
double64_peak_update (psf, psf->u.dbuf, bufferlen, total / psf->sf.channels) ;
double64_peak_update (psf, ubuf.dbuf, bufferlen, total / psf->sf.channels) ;
bd2d_write (psf->u.dbuf, bufferlen) ;
bd2d_write (ubuf.dbuf, bufferlen) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -967,22 +980,23 @@ replace_write_i2d (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
replace_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
f2d_array (ptr + total, psf->u.dbuf, bufferlen) ;
f2d_array (ptr + total, ubuf.dbuf, bufferlen) ;
bd2d_write (psf->u.dbuf, bufferlen) ;
bd2d_write (ubuf.dbuf, bufferlen) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -994,27 +1008,28 @@ replace_write_f2d (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
replace_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
/* FIXME : This is probably nowhere near optimal. */
if (psf->peak_info)
double64_peak_update (psf, ptr, len, 0) ;
bufferlen = ARRAY_LEN (psf->u.dbuf) ;
bufferlen = ARRAY_LEN (ubuf.dbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
memcpy (psf->u.dbuf, ptr + total, bufferlen * sizeof (double)) ;
memcpy (ubuf.dbuf, ptr + total, bufferlen * sizeof (double)) ;
bd2d_write (psf->u.dbuf, bufferlen) ;
bd2d_write (ubuf.dbuf, bufferlen) ;
if (psf->data_endswap == SF_TRUE)
endswap_double_array (psf->u.dbuf, bufferlen) ;
endswap_double_array (ubuf.dbuf, bufferlen) ;
writecount = psf_fwrite (psf->u.dbuf, sizeof (double), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.dbuf, sizeof (double), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
+13 -14
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -69,9 +69,9 @@ static int dwd_close (SF_PRIVATE *psf) ;
int
dwd_open (SF_PRIVATE *psf)
{ int subformat, error = 0 ;
{ int error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = dwd_read_header (psf)))
return error ;
} ;
@@ -79,9 +79,7 @@ dwd_open (SF_PRIVATE *psf)
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_DWD)
return SFE_BAD_OPEN_FORMAT ;
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{
/*-psf->endian = SF_ENDIAN (psf->sf.format) ;
if (CPU_IS_LITTLE_ENDIAN && psf->endian == SF_ENDIAN_CPU)
@@ -124,16 +122,17 @@ typedef struct
static int
dwd_read_header (SF_PRIVATE *psf)
{ DWD_HEADER dwdh ;
{ BUF_UNION ubuf ;
DWD_HEADER dwdh ;
memset (psf->u.cbuf, 0, sizeof (psf->u.cbuf)) ;
memset (ubuf.cbuf, 0, sizeof (ubuf.cbuf)) ;
/* Set position to start of file to begin reading header. */
psf_binheader_readf (psf, "pb", 0, psf->u.cbuf, DWD_IDENTIFIER_LEN) ;
psf_binheader_readf (psf, "pb", 0, ubuf.cbuf, DWD_IDENTIFIER_LEN) ;
if (memcmp (psf->u.cbuf, DWD_IDENTIFIER, DWD_IDENTIFIER_LEN) != 0)
if (memcmp (ubuf.cbuf, DWD_IDENTIFIER, DWD_IDENTIFIER_LEN) != 0)
return SFE_DWD_NO_DWD ;
psf_log_printf (psf, "Read only : DiamondWare Digitized (.dwd)\n", psf->u.cbuf) ;
psf_log_printf (psf, "Read only : DiamondWare Digitized (.dwd)\n", ubuf.cbuf) ;
psf_binheader_readf (psf, "11", &dwdh.major, &dwdh.minor) ;
psf_binheader_readf (psf, "e4j1", &dwdh.id, 1, &dwdh.compression) ;
@@ -152,9 +151,9 @@ dwd_read_header (SF_PRIVATE *psf)
else
psf_log_printf (psf, "None\n") ;
psf_log_printf (psf, " Sample Rate : %d\n Channels : %d\n"
" Bit Width : %d\n",
dwdh.srate, dwdh.channels, dwdh.bitwidth) ;
psf_log_printf (psf, " Sample Rate : %d\n Channels : %d\n"
" Bit Width : %d\n",
dwdh.srate, dwdh.channels, dwdh.bitwidth) ;
switch (dwdh.bitwidth)
{ case 8 :
+54 -42
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -38,7 +38,7 @@
#include "common.h"
typedef struct
{ int dwm_maxsize, bit_width, max_delta, span ;
{ int bit_width, dwm_maxsize, max_delta, span ;
int samplecount ;
int bit_count, bits, last_delta_width, last_sample ;
struct
@@ -61,7 +61,8 @@ static sf_count_t dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t le
static sf_count_t dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static sf_count_t dwvw_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
static int dwvw_close (SF_PRIVATE *psf) ;
static int dwvw_close (SF_PRIVATE *psf) ;
static int dwvw_byterate (SF_PRIVATE *psf) ;
static int dwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len) ;
static int dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count) ;
@@ -86,29 +87,24 @@ dwvw_init (SF_PRIVATE *psf, int bitwidth)
if (bitwidth > 24)
return SFE_DWVW_BAD_BITWIDTH ;
if (psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if ((pdwvw = calloc (1, sizeof (DWVW_PRIVATE))) == NULL)
return SFE_MALLOC_FAILED ;
psf->codec_data = (void*) pdwvw ;
pdwvw->bit_width = bitwidth ;
pdwvw->dwm_maxsize = bitwidth / 2 ;
pdwvw->max_delta = 1 << (bitwidth - 1) ;
pdwvw->span = 1 << bitwidth ;
dwvw_read_reset (pdwvw) ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
{ psf->read_short = dwvw_read_s ;
psf->read_int = dwvw_read_i ;
psf->read_float = dwvw_read_f ;
psf->read_double = dwvw_read_d ;
} ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ psf->write_short = dwvw_write_s ;
psf->write_int = dwvw_write_i ;
psf->write_float = dwvw_write_f ;
@@ -117,11 +113,12 @@ dwvw_init (SF_PRIVATE *psf, int bitwidth)
psf->codec_close = dwvw_close ;
psf->seek = dwvw_seek ;
psf->byterate = dwvw_byterate ;
/* FIXME : This is bogus. */
psf->sf.frames = SF_COUNT_MAX ;
psf->datalength = psf->sf.frames ;
/* EMXIF : This is bogus. */
if (psf->file.mode == SFM_READ)
{ psf->sf.frames = psf_decode_frame_count (psf) ;
dwvw_read_reset (pdwvw) ;
} ;
return 0 ;
} /* dwvw_init */
@@ -137,7 +134,7 @@ dwvw_close (SF_PRIVATE *psf)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ static int last_values [12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
/* Write 8 zero samples to fully flush output. */
@@ -174,6 +171,14 @@ dwvw_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
return PSF_SEEK_ERROR ;
} /* dwvw_seek */
static int
dwvw_byterate (SF_PRIVATE *psf)
{
if (psf->file.mode == SFM_READ)
return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ;
return -1 ;
} /* dwvw_byterate */
/*==============================================================================
*/
@@ -181,6 +186,7 @@ dwvw_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
static sf_count_t
dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
BUF_UNION ubuf ;
int *iptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -189,8 +195,8 @@ dwvw_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
@@ -234,8 +240,9 @@ dwvw_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int *iptr ;
int k, bufferlen, readcount = 0, count ;
BUF_UNION ubuf ;
int *iptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
float normfact ;
@@ -245,8 +252,8 @@ dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x80000000) : 1.0 ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
@@ -265,8 +272,9 @@ dwvw_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
int *iptr ;
int k, bufferlen, readcount = 0, count ;
BUF_UNION ubuf ;
int *iptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
double normfact ;
@@ -276,8 +284,8 @@ dwvw_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x80000000) : 1.0 ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = dwvw_decode_data (psf, pdwvw, iptr, readcount) ;
@@ -307,7 +315,7 @@ dwvw_decode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int *ptr, int len)
delta_width_modifier = dwvw_decode_load_bits (psf, pdwvw, -1) ;
/* Check for end of input bit stream. Break loop if end. */
if (delta_width_modifier < 0)
if (delta_width_modifier < 0 || (pdwvw->b.end == 0 && count == 0))
break ;
if (delta_width_modifier && dwvw_decode_load_bits (psf, pdwvw, 1))
@@ -406,13 +414,14 @@ dwvw_decode_load_bits (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, int bit_count)
static void
dwvw_read_reset (DWVW_PRIVATE *pdwvw)
{ pdwvw->samplecount = 0 ;
pdwvw->b.index = 0 ;
pdwvw->b.end = 0 ;
pdwvw->bit_count = 0 ;
pdwvw->bits = 0 ;
pdwvw->last_delta_width = 0 ;
pdwvw->last_sample = 0 ;
{ int bitwidth = pdwvw->bit_width ;
memset (pdwvw, 0, sizeof (DWVW_PRIVATE)) ;
pdwvw->bit_width = bitwidth ;
pdwvw->dwm_maxsize = bitwidth / 2 ;
pdwvw->max_delta = 1 << (bitwidth - 1) ;
pdwvw->span = 1 << bitwidth ;
} /* dwvw_read_reset */
static void
@@ -461,9 +470,9 @@ dump_bits (DWVW_PRIVATE *pdwvw)
} /* dump_bits */
#endif
#define HIGHEST_BIT(x,count) \
#define HIGHEST_BIT(x, count) \
{ int y = x ; \
(count) = 0 ; \
(count) = 0 ; \
while (y) \
{ (count) ++ ; \
y >>= 1 ; \
@@ -548,6 +557,7 @@ dwvw_encode_data (SF_PRIVATE *psf, DWVW_PRIVATE *pdwvw, const int *ptr, int len)
static sf_count_t
dwvw_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
BUF_UNION ubuf ;
int *iptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -556,8 +566,8 @@ dwvw_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
return 0 ;
pdwvw = (DWVW_PRIVATE*) psf->codec_data ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -601,6 +611,7 @@ dwvw_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
BUF_UNION ubuf ;
int *iptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -612,8 +623,8 @@ dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : 1.0 ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -632,6 +643,7 @@ dwvw_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ DWVW_PRIVATE *pdwvw ;
BUF_UNION ubuf ;
int *iptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -643,8 +655,8 @@ dwvw_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : 1.0 ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
+195 -174
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2003 Ross Bencina <rbencina@iprimus.com.au>
**
** This program is free software; you can redistribute it and/or modify
@@ -73,26 +73,24 @@ static void psf_log_syserr (SF_PRIVATE *psf, int error) ;
*/
static int psf_close_fd (int fd) ;
static int psf_open_fd (const char * path, int mode) ;
static int psf_open_fd (PSF_FILE * pfile) ;
static sf_count_t psf_get_filelen_fd (int fd) ;
int
psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode)
psf_fopen (SF_PRIVATE *psf)
{
psf->error = 0 ;
psf->filedes = psf_open_fd (pathname, open_mode) ;
psf->file.filedes = psf_open_fd (&psf->file) ;
if (psf->filedes == - SFE_BAD_OPEN_MODE)
if (psf->file.filedes == - SFE_BAD_OPEN_MODE)
{ psf->error = SFE_BAD_OPEN_MODE ;
psf->filedes = -1 ;
psf->file.filedes = -1 ;
return psf->error ;
} ;
if (psf->filedes == -1)
if (psf->file.filedes == -1)
psf_log_syserr (psf, errno) ;
psf->mode = open_mode ;
return psf->error ;
} /* psf_fopen */
@@ -100,43 +98,40 @@ int
psf_fclose (SF_PRIVATE *psf)
{ int retval ;
if (psf->filedes == -1)
return -1; /* already closed */
if (psf->virtual_io)
return 0 ;
if (psf->do_not_close_descriptor)
{ psf->filedes = -1 ;
if (psf->file.do_not_close_descriptor)
{ psf->file.filedes = -1 ;
return 0 ;
} ;
if ((retval = psf_close_fd (psf->filedes)) == -1)
if ((retval = psf_close_fd (psf->file.filedes)) == -1)
psf_log_syserr (psf, errno) ;
psf->filedes = -1 ;
psf->file.filedes = -1 ;
return retval ;
} /* psf_fclose */
int
psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
psf_open_rsrc (SF_PRIVATE *psf)
{
if (psf->rsrcdes > 0)
if (psf->rsrc.filedes > 0)
return 0 ;
/* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */
snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s/rsrc", psf->filepath) ;
snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s/..namedfork/rsrc", psf->file.path.c) ;
psf->error = SFE_NO_ERROR ;
if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)
{ psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;
if (psf->rsrclength > 0 || (open_mode & SFM_WRITE))
if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0)
{ psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ;
if (psf->rsrclength > 0 || (psf->rsrc.mode & SFM_WRITE))
return SFE_NO_ERROR ;
psf_close_fd (psf->rsrcdes) ;
psf->rsrcdes = -1 ;
psf_close_fd (psf->rsrc.filedes) ;
psf->rsrc.filedes = -1 ;
} ;
if (psf->rsrcdes == - SFE_BAD_OPEN_MODE)
if (psf->rsrc.filedes == - SFE_BAD_OPEN_MODE)
{ psf->error = SFE_BAD_OPEN_MODE ;
return psf->error ;
} ;
@@ -145,10 +140,10 @@ psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
** Now try for a resource fork stored as a separate file in the same
** directory, but preceded with a dot underscore.
*/
snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s._%s", psf->directory, psf->filename) ;
snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s._%s", psf->file.dir.c, psf->file.name.c) ;
psf->error = SFE_NO_ERROR ;
if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)
{ psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;
if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0)
{ psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ;
return SFE_NO_ERROR ;
} ;
@@ -156,18 +151,18 @@ psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
** Now try for a resource fork stored in a separate file in the
** .AppleDouble/ directory.
*/
snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s.AppleDouble/%s", psf->directory, psf->filename) ;
snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s.AppleDouble/%s", psf->file.dir.c, psf->file.name.c) ;
psf->error = SFE_NO_ERROR ;
if ((psf->rsrcdes = psf_open_fd (psf->rsrcpath, open_mode)) >= 0)
{ psf->rsrclength = psf_get_filelen_fd (psf->rsrcdes) ;
if ((psf->rsrc.filedes = psf_open_fd (&psf->rsrc)) >= 0)
{ psf->rsrclength = psf_get_filelen_fd (psf->rsrc.filedes) ;
return SFE_NO_ERROR ;
} ;
/* No resource file found. */
if (psf->rsrcdes == -1)
if (psf->rsrc.filedes == -1)
psf_log_syserr (psf, errno) ;
psf->rsrcdes = -1 ;
psf->rsrc.filedes = -1 ;
return psf->error ;
} /* psf_open_rsrc */
@@ -179,7 +174,7 @@ psf_get_filelen (SF_PRIVATE *psf)
if (psf->virtual_io)
return psf->vio.get_filelen (psf->vio_user_data) ;
filelen = psf_get_filelen_fd (psf->filedes) ;
filelen = psf_get_filelen_fd (psf->file.filedes) ;
if (filelen == -1)
{ psf_log_syserr (psf, errno) ;
@@ -191,7 +186,7 @@ psf_get_filelen (SF_PRIVATE *psf)
return (sf_count_t) -1 ;
} ;
switch (psf->mode)
switch (psf->file.mode)
{ case SFM_WRITE :
filelen = filelen - psf->fileoffset ;
break ;
@@ -219,28 +214,26 @@ psf_get_filelen (SF_PRIVATE *psf)
int
psf_close_rsrc (SF_PRIVATE *psf)
{
if (psf->rsrcdes >= 0)
psf_close_fd (psf->rsrcdes) ;
psf->rsrcdes = -1 ;
{ psf_close_fd (psf->rsrc.filedes) ;
psf->rsrc.filedes = -1 ;
return 0 ;
} /* psf_close_rsrc */
int
psf_set_stdio (SF_PRIVATE *psf, int mode)
psf_set_stdio (SF_PRIVATE *psf)
{ int error = 0 ;
switch (mode)
switch (psf->file.mode)
{ case SFM_RDWR :
error = SFE_OPEN_PIPE_RDWR ;
break ;
case SFM_READ :
psf->filedes = 0 ;
psf->file.filedes = 0 ;
break ;
case SFM_WRITE :
psf->filedes = 1 ;
psf->file.filedes = 1 ;
break ;
default :
@@ -254,29 +247,31 @@ psf_set_stdio (SF_PRIVATE *psf, int mode)
void
psf_set_file (SF_PRIVATE *psf, int fd)
{ psf->filedes = fd ;
{ psf->file.filedes = fd ;
} /* psf_set_file */
int
psf_file_valid (SF_PRIVATE *psf)
{ return (psf->filedes >= 0) ? SF_TRUE : SF_FALSE ;
{ return (psf->file.filedes >= 0) ? SF_TRUE : SF_FALSE ;
} /* psf_set_file */
sf_count_t
psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
{ sf_count_t new_position ;
{ sf_count_t current_pos, new_position ;
if (psf->virtual_io)
return psf->vio.seek (offset, whence, psf->vio_user_data) ;
current_pos = psf_ftell (psf) ;
switch (whence)
{ case SEEK_SET :
offset += psf->fileoffset ;
break ;
case SEEK_END :
if (psf->mode == SFM_WRITE)
{ new_position = lseek (psf->filedes, offset, whence) ;
if (psf->file.mode == SFM_WRITE)
{ new_position = lseek (psf->file.filedes, offset, whence) ;
if (new_position < 0)
psf_log_syserr (psf, errno) ;
@@ -289,15 +284,25 @@ psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
** get the offset wrt the start of file.
*/
whence = SEEK_SET ;
offset = lseek (psf->filedes, 0, SEEK_END) + offset ;
offset = lseek (psf->file.filedes, 0, SEEK_END) + offset ;
break ;
case SEEK_CUR :
/* Translate a SEEK_CUR into a SEEK_SET. */
offset += current_pos ;
whence = SEEK_SET ;
break ;
default :
/* No need to do anything about SEEK_CUR. */
break ;
/* We really should not be here. */
psf_log_printf (psf, "psf_fseek : whence is %d *****.\n", whence) ;
return 0 ;
} ;
new_position = lseek (psf->filedes, offset, whence) ;
if (current_pos != offset)
new_position = lseek (psf->file.filedes, offset, whence) ;
else
new_position = offset ;
if (new_position < 0)
psf_log_syserr (psf, errno) ;
@@ -325,7 +330,7 @@ psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
{ /* Break the read down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
count = read (psf->filedes, ((char*) ptr) + total, (size_t) count) ;
count = read (psf->file.filedes, ((char*) ptr) + total, (size_t) count) ;
if (count == -1)
{ if (errno == EINTR)
@@ -366,7 +371,7 @@ psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : items ;
count = write (psf->filedes, ((const char*) ptr) + total, count) ;
count = write (psf->file.filedes, ((const char*) ptr) + total, count) ;
if (count == -1)
{ if (errno == EINTR)
@@ -399,7 +404,7 @@ psf_ftell (SF_PRIVATE *psf)
if (psf->is_pipe)
return psf->pipeoffset ;
pos = lseek (psf->filedes, 0, SEEK_CUR) ;
pos = lseek (psf->file.filedes, 0, SEEK_CUR) ;
if (pos == ((sf_count_t) -1))
{ psf_log_syserr (psf, errno) ;
@@ -413,6 +418,9 @@ static int
psf_close_fd (int fd)
{ int retval ;
if (fd < 0)
return 0 ;
while ((retval = close (fd)) == -1 && errno == EINTR)
/* Do nothing. */ ;
@@ -425,7 +433,7 @@ psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf)
sf_count_t count ;
while (k < bufsize - 1)
{ count = read (psf->filedes, &(buffer [k]), 1) ;
{ count = read (psf->file.filedes, &(buffer [k]), 1) ;
if (count == -1)
{ if (errno == EINTR)
@@ -451,7 +459,7 @@ psf_is_pipe (SF_PRIVATE *psf)
if (psf->virtual_io)
return SF_FALSE ;
if (fstat (psf->filedes, &statbuf) == -1)
if (fstat (psf->file.filedes, &statbuf) == -1)
{ psf_log_syserr (psf, errno) ;
/* Default to maximum safety. */
return SF_TRUE ;
@@ -465,19 +473,22 @@ psf_is_pipe (SF_PRIVATE *psf)
static sf_count_t
psf_get_filelen_fd (int fd)
{ struct stat statbuf ;
{
#if (SIZEOF_OFF_T == 4 && SIZEOF_SF_COUNT_T == 8 && HAVE_FSTAT64)
struct stat64 statbuf ;
/*
** Sanity check.
** If everything is OK, this will be optimised out.
*/
if (sizeof (statbuf.st_size) == 4 && sizeof (sf_count_t) == 8)
return (sf_count_t) -SFE_BAD_STAT_SIZE ;
if (fstat64 (fd, &statbuf) == -1)
return (sf_count_t) -1 ;
return statbuf.st_size ;
#else
struct stat statbuf ;
if (fstat (fd, &statbuf) == -1)
return (sf_count_t) -1 ;
return statbuf.st_size ;
#endif
} /* psf_get_filelen_fd */
int
@@ -491,7 +502,7 @@ psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
if ((sizeof (off_t) < sizeof (sf_count_t)) && len > 0x7FFFFFFF)
return -1 ;
retval = ftruncate (psf->filedes, len) ;
retval = ftruncate (psf->file.filedes, len) ;
if (retval == -1)
psf_log_syserr (psf, errno) ;
@@ -501,28 +512,28 @@ psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
void
psf_init_files (SF_PRIVATE *psf)
{ psf->filedes = -1 ;
psf->rsrcdes = -1 ;
psf->savedes = -1 ;
{ psf->file.filedes = -1 ;
psf->rsrc.filedes = -1 ;
psf->file.savedes = -1 ;
} /* psf_init_files */
void
psf_use_rsrc (SF_PRIVATE *psf, int on_off)
{
if (on_off)
{ if (psf->filedes != psf->rsrcdes)
{ psf->savedes = psf->filedes ;
psf->filedes = psf->rsrcdes ;
{ if (psf->file.filedes != psf->rsrc.filedes)
{ psf->file.savedes = psf->file.filedes ;
psf->file.filedes = psf->rsrc.filedes ;
} ;
}
else if (psf->filedes == psf->rsrcdes)
psf->filedes = psf->savedes ;
else if (psf->file.filedes == psf->rsrc.filedes)
psf->file.filedes = psf->file.savedes ;
return ;
} /* psf_use_rsrc */
static int
psf_open_fd (const char * pathname, int open_mode)
psf_open_fd (PSF_FILE * pfile)
{ int fd, oflag, mode ;
/*
@@ -530,13 +541,13 @@ psf_open_fd (const char * pathname, int open_mode)
** be optimised out. This is meant to catch the problems caused by
** "sfconfig.h" being included after <stdio.h>.
*/
if (sizeof (off_t) != sizeof (sf_count_t))
{ puts ("\n\n*** Fatal error : sizeof (off_t) != sizeof (sf_count_t)") ;
if (sizeof (sf_count_t) != 8)
{ puts ("\n\n*** Fatal error : sizeof (sf_count_t) != 8") ;
puts ("*** This means that libsndfile was not configured correctly.\n") ;
exit (1) ;
} ;
switch (open_mode)
switch (pfile->mode)
{ case SFM_READ :
oflag = O_RDONLY | O_BINARY ;
mode = 0 ;
@@ -558,9 +569,9 @@ psf_open_fd (const char * pathname, int open_mode)
} ;
if (mode == 0)
fd = open (pathname, oflag) ;
fd = open (pfile->path.c, oflag) ;
else
fd = open (pathname, oflag, mode) ;
fd = open (pfile->path.c, oflag, mode) ;
return fd ;
} /* psf_open_fd */
@@ -581,10 +592,10 @@ void
psf_fsync (SF_PRIVATE *psf)
{
#if HAVE_FSYNC
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
fsync (psf->filedes) ;
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
fsync (psf->file.filedes) ;
#else
psf = NULL ;
psf = NULL ;
#endif
} /* psf_fsync */
@@ -596,20 +607,18 @@ psf_fsync (SF_PRIVATE *psf)
#include <io.h>
static int psf_close_handle (HANDLE handle) ;
static HANDLE psf_open_handle (const char * path, int mode) ;
static HANDLE psf_open_handle (PSF_FILE * pfile) ;
static sf_count_t psf_get_filelen_handle (HANDLE handle) ;
/* USE_WINDOWS_API */ int
psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode)
psf_fopen (SF_PRIVATE *psf)
{
psf->error = 0 ;
psf->hfile = psf_open_handle (pathname, open_mode) ;
psf->file.handle = psf_open_handle (&psf->file) ;
if (psf->hfile == NULL)
if (psf->file.handle == NULL)
psf_log_syserr (psf, GetLastError ()) ;
psf->mode = open_mode ;
return psf->error ;
} /* psf_fopen */
@@ -620,30 +629,30 @@ psf_fclose (SF_PRIVATE *psf)
if (psf->virtual_io)
return 0 ;
if (psf->do_not_close_descriptor)
{ psf->hfile = NULL ;
if (psf->file.do_not_close_descriptor)
{ psf->file.handle = NULL ;
return 0 ;
} ;
if ((retval = psf_close_handle (psf->hfile)) == -1)
if ((retval = psf_close_handle (psf->file.handle)) == -1)
psf_log_syserr (psf, GetLastError ()) ;
psf->hfile = NULL ;
psf->file.handle = NULL ;
return retval ;
} /* psf_fclose */
/* USE_WINDOWS_API */ int
psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
psf_open_rsrc (SF_PRIVATE *psf)
{
if (psf->hrsrc != NULL)
if (psf->rsrc.handle != NULL)
return 0 ;
/* Test for MacOSX style resource fork on HPFS or HPFS+ filesystems. */
snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s/rsrc", psf->filepath) ;
snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s/rsrc", psf->file.path.c) ;
psf->error = SFE_NO_ERROR ;
if ((psf->hrsrc = psf_open_handle (psf->rsrcpath, open_mode)) != NULL)
{ psf->rsrclength = psf_get_filelen_handle (psf->hrsrc) ;
if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL)
{ psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ;
return SFE_NO_ERROR ;
} ;
@@ -651,10 +660,10 @@ psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
** Now try for a resource fork stored as a separate file in the same
** directory, but preceded with a dot underscore.
*/
snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s._%s", psf->directory, psf->filename) ;
snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s._%s", psf->file.dir.c, psf->file.name.c) ;
psf->error = SFE_NO_ERROR ;
if ((psf->hrsrc = psf_open_handle (psf->rsrcpath, open_mode)) != NULL)
{ psf->rsrclength = psf_get_filelen_handle (psf->hrsrc) ;
if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL)
{ psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ;
return SFE_NO_ERROR ;
} ;
@@ -662,18 +671,18 @@ psf_open_rsrc (SF_PRIVATE *psf, int open_mode)
** Now try for a resource fork stored in a separate file in the
** .AppleDouble/ directory.
*/
snprintf (psf->rsrcpath, sizeof (psf->rsrcpath), "%s.AppleDouble/%s", psf->directory, psf->filename) ;
snprintf (psf->rsrc.path.c, sizeof (psf->rsrc.path.c), "%s.AppleDouble/%s", psf->file.dir.c, psf->file.name.c) ;
psf->error = SFE_NO_ERROR ;
if ((psf->hrsrc = psf_open_handle (psf->rsrcpath, open_mode)) != NULL)
{ psf->rsrclength = psf_get_filelen_handle (psf->hrsrc) ;
if ((psf->rsrc.handle = psf_open_handle (&psf->rsrc)) != NULL)
{ psf->rsrclength = psf_get_filelen_handle (psf->rsrc.handle) ;
return SFE_NO_ERROR ;
} ;
/* No resource file found. */
if (psf->hrsrc == NULL)
if (psf->rsrc.handle == NULL)
psf_log_syserr (psf, GetLastError ()) ;
psf->hrsrc = NULL ;
psf->rsrc.handle = NULL ;
return psf->error ;
} /* psf_open_rsrc */
@@ -685,7 +694,7 @@ psf_get_filelen (SF_PRIVATE *psf)
if (psf->virtual_io)
return psf->vio.get_filelen (psf->vio_user_data) ;
filelen = psf_get_filelen_handle (psf->hfile) ;
filelen = psf_get_filelen_handle (psf->file.handle) ;
if (filelen == -1)
{ psf_log_syserr (psf, errno) ;
@@ -697,7 +706,7 @@ psf_get_filelen (SF_PRIVATE *psf)
return (sf_count_t) -1 ;
} ;
switch (psf->mode)
switch (psf->file.mode)
{ case SFM_WRITE :
filelen = filelen - psf->fileoffset ;
break ;
@@ -725,34 +734,34 @@ psf_get_filelen (SF_PRIVATE *psf)
/* USE_WINDOWS_API */ void
psf_init_files (SF_PRIVATE *psf)
{ psf->hfile = NULL ;
psf->hrsrc = NULL ;
psf->hsaved = NULL ;
{ psf->file.handle = NULL ;
psf->rsrc.handle = NULL ;
psf->file.hsaved = NULL ;
} /* psf_init_files */
/* USE_WINDOWS_API */ void
psf_use_rsrc (SF_PRIVATE *psf, int on_off)
{
if (on_off)
{ if (psf->hfile != psf->hrsrc)
{ psf->hsaved = psf->hfile ;
psf->hfile = psf->hrsrc ;
{ if (psf->file.handle != psf->rsrc.handle)
{ psf->file.hsaved = psf->file.handle ;
psf->file.handle = psf->rsrc.handle ;
} ;
}
else if (psf->hfile == psf->hrsrc)
psf->hfile = psf->hsaved ;
else if (psf->file.handle == psf->rsrc.handle)
psf->file.handle = psf->file.hsaved ;
return ;
} /* psf_use_rsrc */
/* USE_WINDOWS_API */ static HANDLE
psf_open_handle (const char * pathname, int open_mode)
psf_open_handle (PSF_FILE * pfile)
{ DWORD dwDesiredAccess ;
DWORD dwShareMode ;
DWORD dwCreationDistribution ;
HANDLE handle ;
switch (open_mode)
switch (pfile->mode)
{ case SFM_READ :
dwDesiredAccess = GENERIC_READ ;
dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE ;
@@ -775,15 +784,26 @@ psf_open_handle (const char * pathname, int open_mode)
return NULL ;
} ;
handle = CreateFile (
pathname, /* pointer to name of the file */
dwDesiredAccess, /* access (read-write) mode */
dwShareMode, /* share mode */
0, /* pointer to security attributes */
dwCreationDistribution, /* how to create */
FILE_ATTRIBUTE_NORMAL, /* file attributes (could use FILE_FLAG_SEQUENTIAL_SCAN) */
NULL /* handle to file with attributes to copy */
) ;
if (pfile->use_wchar)
handle = CreateFileW (
pfile->path.wc, /* pointer to name of the file */
dwDesiredAccess, /* access (read-write) mode */
dwShareMode, /* share mode */
0, /* pointer to security attributes */
dwCreationDistribution, /* how to create */
FILE_ATTRIBUTE_NORMAL, /* file attributes (could use FILE_FLAG_SEQUENTIAL_SCAN) */
NULL /* handle to file with attributes to copy */
) ;
else
handle = CreateFile (
pfile->path.c, /* pointer to name of the file */
dwDesiredAccess, /* access (read-write) mode */
dwShareMode, /* share mode */
0, /* pointer to security attributes */
dwCreationDistribution, /* how to create */
FILE_ATTRIBUTE_NORMAL, /* file attributes (could use FILE_FLAG_SEQUENTIAL_SCAN) */
NULL /* handle to file with attributes to copy */
) ;
if (handle == INVALID_HANDLE_VALUE)
return NULL ;
@@ -819,32 +839,30 @@ psf_log_syserr (SF_PRIVATE *psf, int error)
/* USE_WINDOWS_API */ int
psf_close_rsrc (SF_PRIVATE *psf)
{
if (psf->hrsrc != NULL)
psf_close_handle (psf->hrsrc) ;
psf->hrsrc = NULL ;
{ psf_close_handle (psf->rsrc.handle) ;
psf->rsrc.handle = NULL ;
return 0 ;
} /* psf_close_rsrc */
/* USE_WINDOWS_API */ int
psf_set_stdio (SF_PRIVATE *psf, int mode)
psf_set_stdio (SF_PRIVATE *psf)
{ HANDLE handle = NULL ;
int error = 0 ;
switch (mode)
switch (psf->file.mode)
{ case SFM_RDWR :
error = SFE_OPEN_PIPE_RDWR ;
break ;
case SFM_READ :
handle = GetStdHandle (STD_INPUT_HANDLE) ;
psf->do_not_close_descriptor = 1 ;
psf->file.do_not_close_descriptor = 1 ;
break ;
case SFM_WRITE :
handle = GetStdHandle (STD_OUTPUT_HANDLE) ;
psf->do_not_close_descriptor = 1 ;
psf->file.do_not_close_descriptor = 1 ;
break ;
default :
@@ -852,7 +870,7 @@ psf_set_stdio (SF_PRIVATE *psf, int mode)
break ;
} ;
psf->hfile = handle ;
psf->file.handle = handle ;
psf->filelength = 0 ;
return error ;
@@ -866,14 +884,14 @@ psf_set_file (SF_PRIVATE *psf, int fd)
osfhandle = _get_osfhandle (fd) ;
handle = (HANDLE) osfhandle ;
psf->hfile = handle ;
psf->file.handle = handle ;
} /* psf_set_file */
/* USE_WINDOWS_API */ int
psf_file_valid (SF_PRIVATE *psf)
{ if (psf->hfile == NULL)
{ if (psf->file.handle == NULL)
return SF_FALSE ;
if (psf->hfile == INVALID_HANDLE_VALUE)
if (psf->file.handle == INVALID_HANDLE_VALUE)
return SF_FALSE ;
return SF_TRUE ;
} /* psf_set_file */
@@ -906,7 +924,7 @@ psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
lDistanceToMove = (DWORD) (offset & 0xFFFFFFFF) ;
lDistanceToMoveHigh = (DWORD) ((offset >> 32) & 0xFFFFFFFF) ;
dwResult = SetFilePointer (psf->hfile, lDistanceToMove, &lDistanceToMoveHigh, dwMoveMethod) ;
dwResult = SetFilePointer (psf->file.handle, lDistanceToMove, &lDistanceToMoveHigh, dwMoveMethod) ;
if (dwResult == 0xFFFFFFFF)
dwError = GetLastError () ;
@@ -942,7 +960,7 @@ psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
if (ReadFile (psf->hfile, ((char*) ptr) + total, count, &dwNumberOfBytesRead, 0) == 0)
if (ReadFile (psf->file.handle, ((char*) ptr) + total, count, &dwNumberOfBytesRead, 0) == 0)
{ psf_log_syserr (psf, GetLastError ()) ;
break ;
}
@@ -965,7 +983,7 @@ psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
/* USE_WINDOWS_API */ sf_count_t
psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
{ sf_count_t total = 0 ;
ssize_t count ;
ssize_t count ;
DWORD dwNumberOfBytesWritten ;
if (psf->virtual_io)
@@ -981,7 +999,7 @@ psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
if (WriteFile (psf->hfile, ((const char*) ptr) + total, count, &dwNumberOfBytesWritten, 0) == 0)
if (WriteFile (psf->file.handle, ((const char*) ptr) + total, count, &dwNumberOfBytesWritten, 0) == 0)
{ psf_log_syserr (psf, GetLastError ()) ;
break ;
}
@@ -1016,7 +1034,7 @@ psf_ftell (SF_PRIVATE *psf)
lDistanceToMoveLow = 0 ;
lDistanceToMoveHigh = 0 ;
dwResult = SetFilePointer (psf->hfile, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_CURRENT) ;
dwResult = SetFilePointer (psf->file.handle, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_CURRENT) ;
if (dwResult == 0xFFFFFFFF)
dwError = GetLastError () ;
@@ -1035,7 +1053,10 @@ psf_ftell (SF_PRIVATE *psf)
/* USE_WINDOWS_API */ static int
psf_close_handle (HANDLE handle)
{ if (CloseHandle (handle) == 0)
{ if (handle == NULL)
return 0 ;
if (CloseHandle (handle) == 0)
return -1 ;
return 0 ;
@@ -1048,7 +1069,7 @@ psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf)
DWORD dwNumberOfBytesRead ;
while (k < bufsize - 1)
{ if (ReadFile (psf->hfile, &(buffer [k]), 1, &dwNumberOfBytesRead, 0) == 0)
{ if (ReadFile (psf->file.handle, &(buffer [k]), 1, &dwNumberOfBytesRead, 0) == 0)
{ psf_log_syserr (psf, GetLastError ()) ;
break ;
}
@@ -1071,7 +1092,7 @@ psf_is_pipe (SF_PRIVATE *psf)
if (psf->virtual_io)
return SF_FALSE ;
if (GetFileType (psf->hfile) == FILE_TYPE_DISK)
if (GetFileType (psf->file.handle) == FILE_TYPE_DISK)
return SF_FALSE ;
/* Default to maximum safety. */
@@ -1098,7 +1119,7 @@ psf_get_filelen_handle (HANDLE handle)
/* USE_WINDOWS_API */ void
psf_fsync (SF_PRIVATE *psf)
{ FlushFileBuffers (psf->hfile) ;
{ FlushFileBuffers (psf->file.handle) ;
} /* psf_fsync */
@@ -1120,7 +1141,7 @@ psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
lDistanceToMoveLow = (DWORD) (len & 0xFFFFFFFF) ;
lDistanceToMoveHigh = (DWORD) ((len >> 32) & 0xFFFFFFFF) ;
dwResult = SetFilePointer (psf->hfile, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_BEGIN) ;
dwResult = SetFilePointer (psf->file.handle, lDistanceToMoveLow, &lDistanceToMoveHigh, FILE_BEGIN) ;
if (dwResult == 0xFFFFFFFF)
dwError = GetLastError () ;
@@ -1135,7 +1156,7 @@ psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
** which guarantees that the new portion of the file will be zeroed.
** Not sure if this is important or not.
*/
if (SetEndOfFile (psf->hfile) == 0)
if (SetEndOfFile (psf->file.handle) == 0)
{ retval = -1 ;
psf_log_syserr (psf, GetLastError ()) ;
} ;
@@ -1191,14 +1212,14 @@ psf_fopen (SF_PRIVATE *psf, const char *pathname, int open_mode)
} ;
if (mode == 0)
psf->filedes = open (pathname, oflag) ;
psf->file.filedes = open (pathname, oflag) ;
else
psf->filedes = open (pathname, oflag, mode) ;
psf->file.filedes = open (pathname, oflag, mode) ;
if (psf->filedes == -1)
if (psf->file.filedes == -1)
psf_log_syserr (psf, errno) ;
return psf->filedes ;
return psf->file.filedes ;
} /* psf_fopen */
/* Win32 */ sf_count_t
@@ -1214,8 +1235,8 @@ psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
break ;
case SEEK_END :
if (psf->mode == SFM_WRITE)
{ new_position = _lseeki64 (psf->filedes, offset, whence) ;
if (psf->file.mode == SFM_WRITE)
{ new_position = _lseeki64 (psf->file.filedes, offset, whence) ;
if (new_position < 0)
psf_log_syserr (psf, errno) ;
@@ -1228,7 +1249,7 @@ psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
** get the offset wrt the start of file.
*/
whence = SEEK_SET ;
offset = _lseeki64 (psf->filedes, 0, SEEK_END) + offset ;
offset = _lseeki64 (psf->file.filedes, 0, SEEK_END) + offset ;
break ;
default :
@@ -1243,9 +1264,9 @@ psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
*** Use the _telli64() function instead.
*/
if (offset == 0 && whence == SEEK_CUR)
new_position = _telli64 (psf->filedes) ;
new_position = _telli64 (psf->file.filedes) ;
else
new_position = _lseeki64 (psf->filedes, offset, whence) ;
new_position = _lseeki64 (psf->file.filedes, offset, whence) ;
if (new_position < 0)
psf_log_syserr (psf, errno) ;
@@ -1258,7 +1279,7 @@ psf_fseek (SF_PRIVATE *psf, sf_count_t offset, int whence)
/* Win32 */ sf_count_t
psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
{ sf_count_t total = 0 ;
ssize_t count ;
ssize_t count ;
if (psf->virtual_io)
return psf->vio.read (ptr, bytes*items, psf->vio_user_data) / bytes ;
@@ -1273,7 +1294,7 @@ psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : (ssize_t) items ;
count = read (psf->filedes, ((char*) ptr) + total, (size_t) count) ;
count = read (psf->file.filedes, ((char*) ptr) + total, (size_t) count) ;
if (count == -1)
{ if (errno == EINTR)
@@ -1296,7 +1317,7 @@ psf_fread (void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
/* Win32 */ sf_count_t
psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf)
{ sf_count_t total = 0 ;
ssize_t count ;
ssize_t count ;
if (psf->virtual_io)
return psf->vio.write (ptr, bytes*items, psf->vio_user_data) / bytes ;
@@ -1311,7 +1332,7 @@ psf_fwrite (const void *ptr, sf_count_t bytes, sf_count_t items, SF_PRIVATE *psf
{ /* Break the writes down to a sensible size. */
count = (items > SENSIBLE_SIZE) ? SENSIBLE_SIZE : items ;
count = write (psf->filedes, ((const char*) ptr) + total, count) ;
count = write (psf->file.filedes, ((const char*) ptr) + total, count) ;
if (count == -1)
{ if (errno == EINTR)
@@ -1338,7 +1359,7 @@ psf_ftell (SF_PRIVATE *psf)
if (psf->virtual_io)
return psf->vio.tell (psf->vio_user_data) ;
pos = _telli64 (psf->filedes) ;
pos = _telli64 (psf->file.filedes) ;
if (pos == ((sf_count_t) -1))
{ psf_log_syserr (psf, errno) ;
@@ -1352,13 +1373,13 @@ psf_ftell (SF_PRIVATE *psf)
psf_fclose (SF_PRIVATE *psf)
{ int retval ;
while ((retval = close (psf->filedes)) == -1 && errno == EINTR)
while ((retval = close (psf->file.filedes)) == -1 && errno == EINTR)
/* Do nothing. */ ;
if (retval == -1)
psf_log_syserr (psf, errno) ;
psf->filedes = -1 ;
psf->file.filedes = -1 ;
return retval ;
} /* psf_fclose */
@@ -1369,7 +1390,7 @@ psf_fgets (char *buffer, sf_count_t bufsize, SF_PRIVATE *psf)
sf_count_t count ;
while (k < bufsize - 1)
{ count = read (psf->filedes, &(buffer [k]), 1) ;
{ count = read (psf->file.filedes, &(buffer [k]), 1) ;
if (count == -1)
{ if (errno == EINTR)
@@ -1396,7 +1417,7 @@ psf_is_pipe (SF_PRIVATE *psf)
return SF_FALSE ;
/* Not sure if this works. */
if (fstat (psf->filedes, &statbuf) == -1)
if (fstat (psf->file.filedes, &statbuf) == -1)
{ psf_log_syserr (psf, errno) ;
/* Default to maximum safety. */
return SF_TRUE ;
@@ -1420,7 +1441,7 @@ psf_get_filelen (SF_PRIVATE *psf)
*/
struct _stati64 statbuf ;
if (_fstati64 (psf->filedes, &statbuf))
if (_fstati64 (psf->file.filedes, &statbuf))
{ psf_log_syserr (psf, errno) ;
return (sf_count_t) -1 ;
} ;
@@ -1432,7 +1453,7 @@ psf_get_filelen (SF_PRIVATE *psf)
if (psf->virtual_io)
return psf->vio.get_filelen (psf->vio_user_data) ;
if ((current = _telli64 (psf->filedes)) < 0)
if ((current = _telli64 (psf->file.filedes)) < 0)
{ psf_log_syserr (psf, errno) ;
return (sf_count_t) -1 ;
} ;
@@ -1450,17 +1471,17 @@ psf_get_filelen (SF_PRIVATE *psf)
** by libsndfile and changing the license to GPL at the same time.
*/
_lseeki64 (psf->filedes, 0, SEEK_END) ;
_lseeki64 (psf->file.filedes, 0, SEEK_END) ;
if ((filelen = _lseeki64 (psf->filedes, 0, SEEK_END)) < 0)
if ((filelen = _lseeki64 (psf->file.filedes, 0, SEEK_END)) < 0)
{ psf_log_syserr (psf, errno) ;
return (sf_count_t) -1 ;
} ;
if (filelen > current)
_lseeki64 (psf->filedes, current, SEEK_SET) ;
_lseeki64 (psf->file.filedes, current, SEEK_SET) ;
switch (psf->mode)
switch (psf->file.mode)
{ case SFM_WRITE :
filelen = filelen - psf->fileoffset ;
break ;
@@ -1504,7 +1525,7 @@ psf_ftruncate (SF_PRIVATE *psf, sf_count_t len)
if (len > 0x7FFFFFFF)
return -1 ;
retval = chsize (psf->filedes, len) ;
retval = chsize (psf->file.filedes, len) ;
if (retval == -1)
psf_log_syserr (psf, errno) ;
+135 -66
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2004-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2004-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2004 Tobias Gehrig <tgehrig@ira.uka.de>
**
** This program is free software ; you can redistribute it and/or modify
@@ -35,12 +35,12 @@
#include <FLAC/stream_encoder.h>
#include <FLAC/metadata.h>
#include "sfendian.h"
/*------------------------------------------------------------------------------
** Private static functions.
*/
#define FLAC_DEFAULT_COMPRESSION_LEVEL 5
#define ENC_BUFFER_SIZE 8192
typedef enum
@@ -69,6 +69,8 @@ typedef struct
const FLAC__Frame *frame ;
FLAC__bool bufferbackup ;
unsigned compression ;
} FLAC_PRIVATE ;
typedef struct
@@ -77,6 +79,7 @@ typedef struct
} FLAC_TAG ;
static sf_count_t flac_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
static int flac_byterate (SF_PRIVATE *psf) ;
static int flac_close (SF_PRIVATE *psf) ;
static int flac_enc_init (SF_PRIVATE *psf) ;
@@ -122,10 +125,6 @@ static FLAC__StreamEncoderSeekStatus sf_flac_enc_seek_callback (const FLAC__Stre
static FLAC__StreamEncoderTellStatus sf_flac_enc_tell_callback (const FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) ;
static FLAC__StreamEncoderWriteStatus sf_flac_enc_write_callback (const FLAC__StreamEncoder *encoder, const FLAC__byte buffer [], size_t bytes, unsigned samples, unsigned current_frame, void *client_data) ;
static const int legal_sample_rates [] =
{ 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000
} ;
static void
s2flac8_array (const short *src, FLAC__int32 *dest, int count)
{ while (--count >= 0)
@@ -153,8 +152,8 @@ i2flac8_array (const int *src, FLAC__int32 *dest, int count)
static void
i2flac16_array (const int *src, FLAC__int32 *dest, int count)
{
while (--count >= 0)
dest [count] = src [count] >> 16 ;
while (--count >= 0)
dest [count] = src [count] >> 16 ;
} /* i2flac16_array */
static void
@@ -306,7 +305,7 @@ sf_flac_read_callback (const FLAC__StreamDecoder * UNUSED (decoder), FLAC__byte
if (*bytes > 0 && psf->error == 0)
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE ;
return FLAC__STREAM_DECODER_READ_STATUS_ABORT ;
return FLAC__STREAM_DECODER_READ_STATUS_ABORT ;
} /* sf_flac_read_callback */
static FLAC__StreamDecoderSeekStatus
@@ -348,7 +347,7 @@ sf_flac_eof_callback (const FLAC__StreamDecoder *UNUSED (decoder), void *client_
if (psf_ftell (psf) == psf->filelength)
return SF_TRUE ;
return SF_FALSE ;
return SF_FALSE ;
} /* sf_flac_eof_callback */
static FLAC__StreamDecoderWriteStatus
@@ -377,7 +376,9 @@ sf_flac_meta_get_vorbiscomments (SF_PRIVATE *psf, const FLAC__StreamMetadata *me
{ "comment", SF_STR_COMMENT },
{ "date", SF_STR_DATE },
{ "album", SF_STR_ALBUM },
{ "license", SF_STR_LICENSE }
{ "license", SF_STR_LICENSE },
{ "tracknumber", SF_STR_TRACKNUMBER },
{ "genre", SF_STR_GENRE }
} ;
const char *value, *cptr ;
@@ -411,7 +412,14 @@ sf_flac_meta_callback (const FLAC__StreamDecoder * UNUSED (decoder), const FLAC_
psf->sf.samplerate = metadata->data.stream_info.sample_rate ;
psf->sf.frames = metadata->data.stream_info.total_samples ;
psf_log_printf (psf, "FLAC Stream Metadata\n Channels : %d\n Sample rate : %d\n Frames : %D\n", psf->sf.channels, psf->sf.samplerate, psf->sf.frames) ;
psf_log_printf (psf, "FLAC Stream Metadata\n Channels : %d\n Sample rate : %d\n", psf->sf.channels, psf->sf.samplerate) ;
if (psf->sf.frames == 0)
{ psf_log_printf (psf, " Frames : 0 (bumping to SF_COUNT_MAX)\n") ;
psf->sf.frames = SF_COUNT_MAX ;
}
else
psf_log_printf (psf, " Frames : %D\n", psf->sf.frames) ;
switch (metadata->data.stream_info.bits_per_sample)
{ case 8 :
@@ -501,7 +509,7 @@ sf_flac_enc_seek_callback (const FLAC__StreamEncoder * UNUSED (encoder), FLAC__u
if (psf->error)
return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR ;
return FLAC__STREAM_ENCODER_SEEK_STATUS_OK ;
return FLAC__STREAM_ENCODER_SEEK_STATUS_OK ;
} /* sf_flac_enc_seek_callback */
static FLAC__StreamEncoderTellStatus
@@ -531,7 +539,7 @@ flac_write_strings (SF_PRIVATE *psf, FLAC_PRIVATE* pflac)
int k, string_count = 0 ;
for (k = 0 ; k < SF_MAX_STRINGS ; k++)
{ if (psf->strings [k].type != 0)
{ if (psf->strings.data [k].type != 0)
string_count ++ ;
} ;
@@ -543,10 +551,10 @@ flac_write_strings (SF_PRIVATE *psf, FLAC_PRIVATE* pflac)
return ;
} ;
for (k = 0 ; k < SF_MAX_STRINGS && psf->strings [k].type != 0 ; k++)
for (k = 0 ; k < SF_MAX_STRINGS && psf->strings.data [k].type != 0 ; k++)
{ const char * key, * value ;
switch (psf->strings [k].type)
switch (psf->strings.data [k].type)
{ case SF_STR_SOFTWARE :
key = "software" ;
break ;
@@ -571,11 +579,17 @@ flac_write_strings (SF_PRIVATE *psf, FLAC_PRIVATE* pflac)
case SF_STR_LICENSE :
key = "license" ;
break ;
case SF_STR_TRACKNUMBER :
key = "tracknumber" ;
break ;
case SF_STR_GENRE :
key = "genre" ;
break ;
default :
continue ;
} ;
value = psf->strings [k].str ;
value = psf->strings.storage + psf->strings.data [k].offset ;
FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair (&entry, key, value) ;
FLAC__metadata_object_vorbiscomment_append_comment (pflac->metadata, entry, /* copy */ SF_FALSE) ;
@@ -620,24 +634,28 @@ flac_open (SF_PRIVATE *psf)
FLAC_PRIVATE* pflac = calloc (1, sizeof (FLAC_PRIVATE)) ;
psf->codec_data = pflac ;
if (psf->mode == SFM_RDWR)
/* Set the default value here. Over-ridden later if necessary. */
pflac->compression = FLAC_DEFAULT_COMPRESSION_LEVEL ;
if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
{ if ((error = flac_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_FLAC)
return SFE_BAD_OPEN_FORMAT ;
psf->endian = SF_ENDIAN_BIG ;
psf->sf.seekable = 0 ;
psf->str_flags = SF_STR_ALLOW_START ;
psf->strings.flags = SF_STR_ALLOW_START ;
if ((error = flac_enc_init (psf)))
return error ;
@@ -647,14 +665,12 @@ flac_open (SF_PRIVATE *psf)
psf->datalength = psf->filelength ;
psf->dataoffset = 0 ;
psf->blockwidth = 0 ;
psf->bytewidth = 1 ;
psf->container_close = flac_close ;
psf->seek = flac_seek ;
psf->command = flac_command ;
psf->byterate = flac_byterate ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
psf->command = flac_command ;
switch (subformat)
{ case SF_FORMAT_PCM_S8 : /* 8-bit FLAC. */
@@ -683,7 +699,7 @@ flac_close (SF_PRIVATE *psf)
if (pflac->metadata != NULL)
FLAC__metadata_object_delete (pflac->metadata) ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ FLAC__stream_encoder_finish (pflac->fse) ;
FLAC__stream_encoder_delete (pflac->fse) ;
@@ -691,7 +707,7 @@ flac_close (SF_PRIVATE *psf)
free (pflac->encbuffer) ;
} ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
{ FLAC__stream_decoder_finish (pflac->fsd) ;
FLAC__stream_decoder_delete (pflac->fsd) ;
} ;
@@ -709,17 +725,16 @@ static int
flac_enc_init (SF_PRIVATE *psf)
{ FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
unsigned bps ;
int k, found ;
found = 0 ;
for (k = 0 ; k < ARRAY_LEN (legal_sample_rates) ; k++)
if (psf->sf.samplerate == legal_sample_rates [k])
{ found = 1 ;
break ;
} ;
if (found == 0)
/* To cite the flac FAQ at
** http://flac.sourceforge.net/faq.html#general__samples
** "FLAC supports linear sample rates from 1Hz - 655350Hz in 1Hz
** increments."
*/
if (psf->sf.samplerate < 1 || psf->sf.samplerate > 655350)
{ psf_log_printf (psf, "flac sample rate out of range.\n", psf->sf.samplerate) ;
return SFE_FLAC_BAD_SAMPLE_RATE ;
} ;
psf_fseek (psf, 0, SEEK_SET) ;
@@ -739,6 +754,8 @@ flac_enc_init (SF_PRIVATE *psf)
break ;
} ;
if (pflac->fse)
FLAC__stream_encoder_delete (pflac->fse) ;
if ((pflac->fse = FLAC__stream_encoder_new ()) == NULL)
return SFE_FLAC_NEW_DECODER ;
@@ -757,6 +774,11 @@ flac_enc_init (SF_PRIVATE *psf)
return SFE_FLAC_INIT_DECODER ;
} ;
if (! FLAC__stream_encoder_set_compression_level (pflac->fse, pflac->compression))
{ psf_log_printf (psf, "FLAC__stream_encoder_set_compression_level (%d) return false.\n", pflac->compression) ;
return SFE_FLAC_INIT_DECODER ;
} ;
return 0 ;
} /* flac_enc_init */
@@ -765,6 +787,8 @@ flac_read_header (SF_PRIVATE *psf)
{ FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
psf_fseek (psf, 0, SEEK_SET) ;
if (pflac->fsd)
FLAC__stream_decoder_delete (pflac->fsd) ;
if ((pflac->fsd = FLAC__stream_decoder_new ()) == NULL)
return SFE_FLAC_NEW_DECODER ;
@@ -788,34 +812,59 @@ flac_read_header (SF_PRIVATE *psf)
} /* flac_read_header */
static int
flac_command (SF_PRIVATE * UNUSED (psf), int UNUSED (command), void * UNUSED (data), int UNUSED (datasize))
{
return 0 ;
flac_command (SF_PRIVATE * psf, int command, void * data, int datasize)
{ FLAC_PRIVATE* pflac = (FLAC_PRIVATE*) psf->codec_data ;
double quality ;
switch (command)
{ case SFC_SET_COMPRESSION_LEVEL :
if (data == NULL || datasize != sizeof (double))
return SF_FALSE ;
if (psf->have_written)
return SF_FALSE ;
/* FLAC compression level is in the range [0, 8] while libsndfile takes
** values in the range [0.0, 1.0]. Massage the libsndfile value here.
*/
quality = (*((double *) data)) * 8.0 ;
/* Clip range. */
pflac->compression = lrint (SF_MAX (0.0, SF_MIN (8.0, quality))) ;
psf_log_printf (psf, "%s : Setting SFC_SET_COMPRESSION_LEVEL to %u.\n", __func__, pflac->compression) ;
if (flac_enc_init (psf))
return SF_FALSE ;
return SF_TRUE ;
default :
return SF_FALSE ;
} ;
return SF_FALSE ;
} /* flac_command */
int
flac_init (SF_PRIVATE *psf)
{
if (psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
{ psf->read_short = flac_read_flac2s ;
psf->read_int = flac_read_flac2i ;
psf->read_float = flac_read_flac2f ;
psf->read_double = flac_read_flac2d ;
} ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ psf->write_short = flac_write_s2flac ;
psf->write_int = flac_write_i2flac ;
psf->write_float = flac_write_f2flac ;
psf->write_double = flac_write_d2flac ;
} ;
psf->bytewidth = 1 ;
psf->blockwidth = psf->sf.channels ;
if (psf->filelength > psf->dataoffset)
psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset : psf->filelength - psf->dataoffset ;
else
@@ -954,7 +1003,7 @@ flac_write_s2flac (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
convert (ptr + total, buffer, writecount) ;
if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount / psf->sf.channels))
thiswrite = writecount ;
else
break ;
@@ -996,7 +1045,7 @@ flac_write_i2flac (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
convert (ptr + total, buffer, writecount) ;
if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount / psf->sf.channels))
thiswrite = writecount ;
else
break ;
@@ -1038,7 +1087,7 @@ flac_write_f2flac (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
convert (ptr + total, buffer, writecount, psf->norm_float) ;
if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount / psf->sf.channels))
thiswrite = writecount ;
else
break ;
@@ -1076,23 +1125,22 @@ f2flac8_clip_array (const float *src, FLAC__int32 *dest, int count, int normaliz
static void
f2flac16_clip_array (const float *src, FLAC__int32 *dest, int count, int normalize)
{
float normfact, scaled_value ;
{ float normfact, scaled_value ;
normfact = normalize ? (8.0 * 0x1000) : 1.0 ;
normfact = normalize ? (8.0 * 0x1000) : 1.0 ;
while (--count >= 0) {
scaled_value = src [count] * normfact ;
if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF)) {
dest [count] = 0x7FFF ;
continue ;
}
if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000)) {
dest [count] = 0x8000 ;
continue ;
}
dest [count] = lrintf (scaled_value) ;
}
while (--count >= 0)
{ scaled_value = src [count] * normfact ;
if (CPU_CLIPS_POSITIVE == 0 && scaled_value >= (1.0 * 0x7FFF))
{ dest [count] = 0x7FFF ;
continue ;
} ;
if (CPU_CLIPS_NEGATIVE == 0 && scaled_value <= (-8.0 * 0x1000))
{ dest [count] = 0x8000 ;
continue ;
} ;
dest [count] = lrintf (scaled_value) ;
} ;
} /* f2flac16_clip_array */
static void
@@ -1170,7 +1218,7 @@ flac_write_d2flac (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
convert (ptr + total, buffer, writecount, psf->norm_double) ;
if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount/psf->sf.channels))
if (FLAC__stream_encoder_process_interleaved (pflac->fse, buffer, writecount / psf->sf.channels))
thiswrite = writecount ;
else
break ;
@@ -1288,13 +1336,24 @@ flac_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
pflac->frame = NULL ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
{ FLAC__uint64 position ;
if (FLAC__stream_decoder_seek_absolute (pflac->fsd, offset))
{ FLAC__stream_decoder_get_decode_position (pflac->fsd, &position) ;
return offset ;
} ;
if (offset == psf->sf.frames)
{ /*
** If we've been asked to seek to the very end of the file, libFLAC
** will return an error. However, we know the length of the file so
** instead of returning an error, we can return the offset.
*/
return offset ;
} ;
psf->error = SFE_BAD_SEEK ;
return ((sf_count_t) -1) ;
} ;
@@ -1304,6 +1363,16 @@ flac_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
return ((sf_count_t) -1) ;
} /* flac_seek */
static int
flac_byterate (SF_PRIVATE *psf)
{
if (psf->file.mode == SFM_READ)
return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ;
return -1 ;
} /* flac_byterate */
#else /* HAVE_EXTERNAL_LIBS */
int
+115 -99
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -92,7 +92,7 @@ float32_init (SF_PRIVATE *psf)
psf->blockwidth = sizeof (float) * psf->sf.channels ;
if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ switch (psf->endian + float_caps)
{ case (SF_ENDIAN_BIG + FLOAT_CAN_RW_BE) :
psf->data_endswap = SF_FALSE ;
@@ -163,7 +163,7 @@ float32_init (SF_PRIVATE *psf)
} ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ switch (psf->endian + float_caps)
{ case (SF_ENDIAN_LITTLE + FLOAT_CAN_RW_LE) :
psf->data_endswap = SF_FALSE ;
@@ -241,13 +241,13 @@ float32_init (SF_PRIVATE *psf)
else
psf->datalength = 0 ;
psf->sf.frames = psf->datalength / psf->blockwidth ;
psf->sf.frames = psf->blockwidth > 0 ? psf->datalength / psf->blockwidth : 0 ;
return 0 ;
} /* float32_init */
float
float32_be_read (unsigned char *cptr)
float32_be_read (const unsigned char *cptr)
{ int exponent, mantissa, negative ;
float fvalue ;
@@ -275,7 +275,7 @@ float32_be_read (unsigned char *cptr)
} /* float32_be_read */
float
float32_le_read (unsigned char *cptr)
float32_le_read (const unsigned char *cptr)
{ int exponent, mantissa, negative ;
float fvalue ;
@@ -444,7 +444,7 @@ f2s_clip_array (const float *src, int count, short *dest, float scale)
if (CPU_CLIPS_POSITIVE == 0 && tmp > 32767.0)
dest [count] = SHRT_MAX ;
else if (CPU_CLIPS_NEGATIVE == 0 && tmp < 32768.0)
else if (CPU_CLIPS_NEGATIVE == 0 && tmp < -32768.0)
dest [count] = SHRT_MIN ;
else
dest [count] = lrintf (tmp) ;
@@ -505,25 +505,26 @@ d2f_array (const double *src, float *dest, int count)
static sf_count_t
host_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ void (*convert) (const float *, int, short *, float) ;
{ BUF_UNION ubuf ;
void (*convert) (const float *, int, short *, float) ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
float scale ;
convert = (psf->add_clipping) ? f2s_clip_array : f2s_array ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
/* Fix me : Need lef2s_array */
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
f2s_array (psf->u.fbuf, readcount, ptr + total, scale) ;
convert (ubuf.fbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -535,24 +536,25 @@ host_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
static sf_count_t
host_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ void (*convert) (const float *, int, int *, float) ;
{ BUF_UNION ubuf ;
void (*convert) (const float *, int, int *, float) ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
float scale ;
convert = (psf->add_clipping) ? f2i_clip_array : f2i_array ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFFFFFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
convert (psf->u.fbuf, readcount, ptr + total, scale) ;
convert (ubuf.fbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -564,20 +566,21 @@ host_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
host_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
if (psf->data_endswap != SF_TRUE)
return psf_fread (ptr, sizeof (float), len, psf) ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
endswap_int_copy ((int*) (ptr + total), psf->u.ibuf, readcount) ;
endswap_int_copy ((int*) (ptr + total), ubuf.ibuf, readcount) ;
total += readcount ;
if (readcount < bufferlen)
@@ -590,21 +593,22 @@ host_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
host_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
/* Fix me : Need lef2d_array */
f2d_array (psf->u.fbuf, readcount, ptr + total) ;
f2d_array (ubuf.fbuf, readcount, ptr + total) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -616,26 +620,27 @@ host_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
static sf_count_t
host_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
float scale ;
/* Erik */
scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / 0x8000 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
s2f_array (ptr + total, psf->u.fbuf, bufferlen, scale) ;
s2f_array (ptr + total, ubuf.fbuf, bufferlen, scale) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -647,25 +652,26 @@ host_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
static sf_count_t
host_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
float scale ;
scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
i2f_array (ptr + total, psf->u.fbuf, bufferlen, scale) ;
i2f_array (ptr + total, ubuf.fbuf, bufferlen, scale) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float) , bufferlen, psf) ;
writecount = psf_fwrite (ubuf.fbuf, sizeof (float) , bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -677,7 +683,8 @@ host_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
host_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
if (psf->peak_info)
@@ -686,15 +693,15 @@ host_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
if (psf->data_endswap != SF_TRUE)
return psf_fwrite (ptr, sizeof (float), len, psf) ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
endswap_int_copy (psf->u.ibuf, (const int*) (ptr + total), bufferlen) ;
endswap_int_copy (ubuf.ibuf, (const int*) (ptr + total), bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -706,24 +713,25 @@ host_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
host_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
d2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
d2f_array (ptr + total, ubuf.fbuf, bufferlen) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -738,24 +746,25 @@ host_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
static sf_count_t
replace_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
float scale ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
bf2f_array (psf->u.fbuf, bufferlen) ;
bf2f_array (ubuf.fbuf, bufferlen) ;
f2s_array (psf->u.fbuf, readcount, ptr + total, scale) ;
f2s_array (ubuf.fbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -767,24 +776,25 @@ replace_read_f2s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
static sf_count_t
replace_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
float scale ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
scale = (psf->float_int_mult == 0) ? 1.0 : 0x7FFF / psf->float_max ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
bf2f_array (psf->u.fbuf, bufferlen) ;
bf2f_array (ubuf.fbuf, bufferlen) ;
f2i_array (psf->u.fbuf, readcount, ptr + total, scale) ;
f2i_array (ubuf.fbuf, readcount, ptr + total, scale) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -796,24 +806,25 @@ replace_read_f2i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
replace_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
/* FIX THIS */
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
bf2f_array (psf->u.fbuf, bufferlen) ;
bf2f_array (ubuf.fbuf, bufferlen) ;
memcpy (ptr + total, psf->u.fbuf, bufferlen * sizeof (float)) ;
memcpy (ptr + total, ubuf.fbuf, bufferlen * sizeof (float)) ;
total += readcount ;
if (readcount < bufferlen)
@@ -826,22 +837,23 @@ replace_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
replace_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ int bufferlen, readcount ;
{ BUF_UNION ubuf ;
int bufferlen, readcount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
readcount = psf_fread (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
readcount = psf_fread (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
bf2f_array (psf->u.fbuf, bufferlen) ;
bf2f_array (ubuf.fbuf, bufferlen) ;
f2d_array (psf->u.fbuf, readcount, ptr + total) ;
f2d_array (ubuf.fbuf, readcount, ptr + total) ;
total += readcount ;
if (readcount < bufferlen)
break ;
@@ -853,27 +865,28 @@ replace_read_f2d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
static sf_count_t
replace_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
float scale ;
scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / 0x8000 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
s2f_array (ptr + total, psf->u.fbuf, bufferlen, scale) ;
s2f_array (ptr + total, ubuf.fbuf, bufferlen, scale) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ;
f2bf_array (psf->u.fbuf, bufferlen) ;
f2bf_array (ubuf.fbuf, bufferlen) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -885,27 +898,28 @@ replace_write_s2f (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
static sf_count_t
replace_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
float scale ;
scale = (psf->scale_int_float == 0) ? 1.0 : 1.0 / (8.0 * 0x10000000) ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
i2f_array (ptr + total, psf->u.fbuf, bufferlen, scale) ;
i2f_array (ptr + total, ubuf.fbuf, bufferlen, scale) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ;
f2bf_array (psf->u.fbuf, bufferlen) ;
f2bf_array (ubuf.fbuf, bufferlen) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -917,27 +931,28 @@ replace_write_i2f (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
replace_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
/* FIX THIS */
if (psf->peak_info)
float32_peak_update (psf, ptr, len, 0) ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
memcpy (psf->u.fbuf, ptr + total, bufferlen * sizeof (float)) ;
memcpy (ubuf.fbuf, ptr + total, bufferlen * sizeof (float)) ;
f2bf_array (psf->u.fbuf, bufferlen) ;
f2bf_array (ubuf.fbuf, bufferlen) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float) , bufferlen, psf) ;
writecount = psf_fwrite (ubuf.fbuf, sizeof (float) , bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
@@ -949,25 +964,26 @@ replace_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
replace_write_d2f (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ int bufferlen, writecount ;
{ BUF_UNION ubuf ;
int bufferlen, writecount ;
sf_count_t total = 0 ;
bufferlen = ARRAY_LEN (psf->u.fbuf) ;
bufferlen = ARRAY_LEN (ubuf.fbuf) ;
while (len > 0)
{ if (len < bufferlen)
bufferlen = (int) len ;
d2f_array (ptr + total, psf->u.fbuf, bufferlen) ;
d2f_array (ptr + total, ubuf.fbuf, bufferlen) ;
if (psf->peak_info)
float32_peak_update (psf, psf->u.fbuf, bufferlen, total / psf->sf.channels) ;
float32_peak_update (psf, ubuf.fbuf, bufferlen, total / psf->sf.channels) ;
f2bf_array (psf->u.fbuf, bufferlen) ;
f2bf_array (ubuf.fbuf, bufferlen) ;
if (psf->data_endswap == SF_TRUE)
endswap_int_array (psf->u.ibuf, bufferlen) ;
endswap_int_array (ubuf.ibuf, bufferlen) ;
writecount = psf_fwrite (psf->u.fbuf, sizeof (float), bufferlen, psf) ;
writecount = psf_fwrite (ubuf.fbuf, sizeof (float), bufferlen, psf) ;
total += writecount ;
if (writecount < bufferlen)
break ;
+27 -23
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -112,8 +112,6 @@ g72x_init (SF_PRIVATE * psf)
default : return SFE_UNIMPLEMENTED ;
} ;
psf->blockwidth = psf->bytewidth = 1 ;
psf->filelength = psf_get_filelen (psf) ;
if (psf->filelength < psf->dataoffset)
psf->filelength = psf->dataoffset ;
@@ -122,7 +120,7 @@ g72x_init (SF_PRIVATE * psf)
if (psf->dataend > 0)
psf->datalength -= psf->filelength - psf->dataend ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
{ pg72x->private = g72x_reader_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
if (pg72x->private == NULL)
return SFE_MALLOC_FAILED ;
@@ -134,7 +132,7 @@ g72x_init (SF_PRIVATE * psf)
psf->read_float = g72x_read_f ;
psf->read_double = g72x_read_d ;
psf->seek = g72x_seek ;
psf->seek = g72x_seek ;
if (psf->datalength % pg72x->blocksize)
{ psf_log_printf (psf, "*** Odd psf->datalength (%D) should be a multiple of %d\n", psf->datalength, pg72x->blocksize) ;
@@ -147,7 +145,7 @@ g72x_init (SF_PRIVATE * psf)
psf_g72x_decode_block (psf, pg72x) ;
}
else if (psf->mode == SFM_WRITE)
else if (psf->file.mode == SFM_WRITE)
{ pg72x->private = g72x_writer_init (codec, &(pg72x->blocksize), &(pg72x->samplesperblock)) ;
if (pg72x->private == NULL)
return SFE_MALLOC_FAILED ;
@@ -253,7 +251,8 @@ g72x_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
static sf_count_t
g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
{ BUF_UNION ubuf ;
G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -262,7 +261,7 @@ g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
sptr = ubuf.sbuf ;
bufferlen = SF_BUFFER_LEN / sizeof (short) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
@@ -282,7 +281,8 @@ g72x_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
{ BUF_UNION ubuf ;
G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -294,7 +294,7 @@ g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
sptr = ubuf.sbuf ;
bufferlen = SF_BUFFER_LEN / sizeof (short) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
@@ -313,7 +313,8 @@ g72x_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
{ BUF_UNION ubuf ;
G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -325,7 +326,7 @@ g72x_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
sptr = ubuf.sbuf ;
bufferlen = SF_BUFFER_LEN / sizeof (short) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
@@ -401,7 +402,7 @@ g72x_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t UNUSED (offset))
** return PSF_SEEK_ERROR ;
** } ;
**
** if (psf->mode == SFM_READ)
** if (psf->file.mode == SFM_READ)
** { psf_fseek (psf, psf->dataoffset + newblock * pg72x->blocksize, SEEK_SET) ;
** pg72x->block_curr = newblock ;
** psf_g72x_decode_block (psf, pg72x) ;
@@ -491,7 +492,8 @@ g72x_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
static sf_count_t
g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
{ BUF_UNION ubuf ;
G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -500,8 +502,8 @@ g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
return 0 ;
pg72x = (G72x_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
sptr = ubuf.sbuf ;
bufferlen = SF_BUFFER_LEN / sizeof (short) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -518,7 +520,8 @@ g72x_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
{ BUF_UNION ubuf ;
G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -530,8 +533,8 @@ g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
sptr = ubuf.sbuf ;
bufferlen = SF_BUFFER_LEN / sizeof (short) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -549,7 +552,8 @@ g72x_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ G72x_PRIVATE *pg72x ;
{ BUF_UNION ubuf ;
G72x_PRIVATE *pg72x ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -561,8 +565,8 @@ g72x_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ((SF_BUFFER_LEN / psf->blockwidth) * psf->blockwidth) / sizeof (short) ;
sptr = ubuf.sbuf ;
bufferlen = SF_BUFFER_LEN / sizeof (short) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -584,7 +588,7 @@ g72x_close (SF_PRIVATE *psf)
pg72x = (G72x_PRIVATE*) psf->codec_data ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ /* If a block has been partially assembled, write it out
** as the final block.
*/
+30 -24
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -84,7 +84,7 @@ gsm610_init (SF_PRIVATE *psf)
return SFE_INTERNAL ;
} ;
if (psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
psf->sf.seekable = SF_FALSE ;
@@ -132,7 +132,7 @@ Need separate gsm_data structs for encode and decode.
break ;
} ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
{ if (psf->datalength % pgsm610->blocksize == 0)
pgsm610->blocks = psf->datalength / pgsm610->blocksize ;
else if (psf->datalength % pgsm610->blocksize == 1 && pgsm610->blocksize == GSM610_BLOCKSIZE)
@@ -162,7 +162,7 @@ Need separate gsm_data structs for encode and decode.
psf->read_double = gsm610_read_d ;
} ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ pgsm610->blockcount = 0 ;
pgsm610->samplecount = 0 ;
@@ -194,7 +194,7 @@ gsm610_wav_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
pgsm610->samplecount = 0 ;
if (pgsm610->blockcount > pgsm610->blocks)
{ memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
{ memset (pgsm610->samples, 0, sizeof (pgsm610->samples)) ;
return 1 ;
} ;
@@ -222,7 +222,7 @@ gsm610_decode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
pgsm610->samplecount = 0 ;
if (pgsm610->blockcount > pgsm610->blocks)
{ memset (pgsm610->samples, 0, GSM610_SAMPLES * sizeof (short)) ;
{ memset (pgsm610->samples, 0, sizeof (pgsm610->samples)) ;
return 1 ;
} ;
@@ -243,7 +243,7 @@ gsm610_read_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610, short *ptr, int len
while (indx < len)
{ if (pgsm610->blockcount >= pgsm610->blocks && pgsm610->samplecount >= pgsm610->samplesperblock)
{ memset (&(ptr [indx]), 0, (len - indx) * sizeof (short)) ;
{ memset (ptr + indx, 0, (len - indx) * sizeof (short)) ;
return total ;
} ;
@@ -290,6 +290,7 @@ gsm610_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
static sf_count_t
gsm610_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -298,8 +299,8 @@ gsm610_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
@@ -315,6 +316,7 @@ gsm610_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
gsm610_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -326,8 +328,8 @@ gsm610_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
@@ -343,6 +345,7 @@ gsm610_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
gsm610_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -354,8 +357,8 @@ gsm610_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = gsm610_read_block (psf, pgsm610, sptr, readcount) ;
@@ -406,7 +409,7 @@ gsm610_seek (SF_PRIVATE *psf, int UNUSED (mode), sf_count_t offset)
newblock = offset / pgsm610->samplesperblock ;
newsample = offset % pgsm610->samplesperblock ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
{ if (psf->read_current != newblock * pgsm610->samplesperblock + newsample)
{ psf_fseek (psf, psf->dataoffset + newblock * pgsm610->samplesperblock, SEEK_SET) ;
pgsm610->blockcount = newblock ;
@@ -441,7 +444,7 @@ gsm610_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
pgsm610->blockcount ++ ;
/* Set samples to zero for next block. */
memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
memset (pgsm610->samples, 0, sizeof (pgsm610->samples)) ;
return 1 ;
} /* gsm610_encode_block */
@@ -452,7 +455,7 @@ gsm610_wav_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
/* Encode the samples. */
gsm_encode (pgsm610->gsm_data, pgsm610->samples, pgsm610->block) ;
gsm_encode (pgsm610->gsm_data, pgsm610->samples+WAV_W64_GSM610_SAMPLES/2, pgsm610->block+WAV_W64_GSM610_BLOCKSIZE/2) ;
gsm_encode (pgsm610->gsm_data, pgsm610->samples+WAV_W64_GSM610_SAMPLES / 2, pgsm610->block+WAV_W64_GSM610_BLOCKSIZE / 2) ;
/* Write the block to disk. */
if ((k = psf_fwrite (pgsm610->block, 1, WAV_W64_GSM610_BLOCKSIZE, psf)) != WAV_W64_GSM610_BLOCKSIZE)
@@ -462,7 +465,7 @@ gsm610_wav_encode_block (SF_PRIVATE *psf, GSM610_PRIVATE *pgsm610)
pgsm610->blockcount ++ ;
/* Set samples to zero for next block. */
memset (pgsm610->samples, 0, WAV_W64_GSM610_SAMPLES * sizeof (short)) ;
memset (pgsm610->samples, 0, sizeof (pgsm610->samples)) ;
return 1 ;
} /* gsm610_wav_encode_block */
@@ -517,6 +520,7 @@ gsm610_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
static sf_count_t
gsm610_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -525,8 +529,8 @@ gsm610_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
return 0 ;
pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -542,6 +546,7 @@ gsm610_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
gsm610_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -553,8 +558,8 @@ gsm610_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -570,6 +575,7 @@ gsm610_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
gsm610_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ GSM610_PRIVATE *pgsm610 ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -581,8 +587,8 @@ gsm610_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -604,7 +610,7 @@ gsm610_close (SF_PRIVATE *psf)
pgsm610 = (GSM610_PRIVATE*) psf->codec_data ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ /* If a block has been partially assembled, write it out
** as the final block.
*/
+14 -7
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -55,14 +55,14 @@ htk_open (SF_PRIVATE *psf)
if (psf->is_pipe)
return SFE_HTK_NO_PIPE ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = htk_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_HTK)
return SFE_BAD_OPEN_FORMAT ;
@@ -95,7 +95,7 @@ htk_open (SF_PRIVATE *psf)
static int
htk_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
htk_write_header (psf, SF_TRUE) ;
return 0 ;
@@ -195,10 +195,17 @@ htk_read_header (SF_PRIVATE *psf)
return SFE_HTK_NOT_WAVEFORM ;
psf->sf.channels = 1 ;
psf->sf.samplerate = 10000000 / sample_period ;
psf_log_printf (psf, "HTK Waveform file\n Sample Count : %d\n Sample Period : %d => %d Hz\n",
sample_count, sample_period, psf->sf.samplerate) ;
if (sample_period > 0)
{ psf->sf.samplerate = 10000000 / sample_period ;
psf_log_printf (psf, "HTK Waveform file\n Sample Count : %d\n Sample Period : %d => %d Hz\n",
sample_count, sample_period, psf->sf.samplerate) ;
}
else
{ psf->sf.samplerate = 16000 ;
psf_log_printf (psf, "HTK Waveform file\n Sample Count : %d\n Sample Period : %d (should be > 0) => Guessed sample rate %d Hz\n",
sample_count, sample_period, psf->sf.samplerate) ;
} ;
psf->sf.format = SF_FORMAT_HTK | SF_FORMAT_PCM_16 ;
psf->bytewidth = 2 ;
+57
View File
@@ -0,0 +1,57 @@
/*
** Copyright (C) 2010-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
int
id3_skip (SF_PRIVATE * psf)
{ unsigned char buf [10] ;
memset (buf, 0, sizeof (buf)) ;
psf_binheader_readf (psf, "pb", 0, buf, 10) ;
if (buf [0] == 'I' && buf [1] == 'D' && buf [2] == '3')
{ int offset = buf [6] & 0x7f ;
offset = (offset << 7) | (buf [7] & 0x7f) ;
offset = (offset << 7) | (buf [8] & 0x7f) ;
offset = (offset << 7) | (buf [9] & 0x7f) ;
psf_log_printf (psf, "ID3 length : %d\n--------------------\n", offset) ;
/* Never want to jump backwards in a file. */
if (offset < 0)
return 0 ;
/* Calculate new file offset and position ourselves there. */
psf->fileoffset += offset + 10 ;
psf_binheader_readf (psf, "p", psf->fileoffset) ;
return 1 ;
} ;
return 0 ;
} /* id3_skip */
+54 -53
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -37,11 +37,7 @@ typedef struct IMA_ADPCM_PRIVATE_tag
int stepindx [2] ;
unsigned char *block ;
short *samples ;
#if HAVE_FLEXIBLE_ARRAY
short data [] ; /* ISO C99 struct flexible array. */
#else
short data [0] ; /* This is a hack and might not work. */
#endif
} IMA_ADPCM_PRIVATE ;
/*============================================================================================
@@ -50,9 +46,9 @@ typedef struct IMA_ADPCM_PRIVATE_tag
static int ima_indx_adjust [16] =
{ -1, -1, -1, -1, /* +0 - +3, decrease the step size */
2, 4, 6, 8, /* +4 - +7, increase the step size */
-1, -1, -1, -1, /* -0 - -3, decrease the step size */
2, 4, 6, 8, /* -4 - -7, increase the step size */
+2, +4, +6, +8, /* +4 - +7, increase the step size */
-1, -1, -1, -1, /* -0 - -3, decrease the step size */
+2, +4, +6, +8, /* -4 - -7, increase the step size */
} ;
static int ima_step_size [89] =
@@ -116,14 +112,14 @@ wav_w64_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
return SFE_INTERNAL ;
} ;
if (psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
return error ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
if ((error = ima_writer_init (psf, blockalign)))
return error ;
@@ -137,14 +133,14 @@ int
aiff_ima_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
{ int error ;
if (psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if (psf->mode == SFM_READ)
if (psf->file.mode == SFM_READ)
if ((error = ima_reader_init (psf, blockalign, samplesperblock)))
return error ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
if ((error = ima_writer_init (psf, blockalign)))
return error ;
@@ -159,7 +155,7 @@ ima_close (SF_PRIVATE *psf)
pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ /* If a block has been partially assembled, write it out
** as the final block.
*/
@@ -181,18 +177,16 @@ ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
{ IMA_ADPCM_PRIVATE *pima ;
int pimasize, count ;
if (psf->mode != SFM_READ)
if (psf->file.mode != SFM_READ)
return SFE_BAD_MODE_RW ;
pimasize = sizeof (IMA_ADPCM_PRIVATE) + blockalign * psf->sf.channels + 3 * psf->sf.channels * samplesperblock ;
if (! (pima = malloc (pimasize)))
if (! (pima = calloc (1, pimasize)))
return SFE_MALLOC_FAILED ;
psf->codec_data = (void*) pima ;
memset (pima, 0, pimasize) ;
pima->samples = pima->data ;
pima->block = (unsigned char*) (pima->data + samplesperblock * psf->sf.channels) ;
@@ -204,7 +198,7 @@ ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
psf->datalength = (psf->dataend) ? psf->dataend - psf->dataoffset :
psf->filelength - psf->dataoffset ;
if (pima->blocksize == 0)
if (pima->blocksize == 0)
{ psf_log_printf (psf, "*** Error : pima->blocksize should not be zero.\n") ;
return SFE_INTERNAL ;
} ;
@@ -238,7 +232,6 @@ ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
default :
psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
return SFE_INTERNAL ;
break ;
} ;
pima->decode_block (psf, pima) ; /* Read first block. */
@@ -254,8 +247,8 @@ ima_reader_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
static int
aiff_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
{ unsigned char *blockdata ;
int chan, k, diff, bytecode ;
short step, stepindx, predictor, *sampledata ;
int chan, k, diff, bytecode, predictor ;
short step, stepindx, *sampledata ;
static int count = 0 ;
count ++ ;
@@ -307,6 +300,11 @@ count ++ ;
if (bytecode & 8) diff = -diff ;
predictor += diff ;
if (predictor < -32768)
predictor = -32768 ;
else if (predictor > 32767)
predictor = 32767 ;
pima->samples [pima->channels * k + chan] = predictor ;
} ;
} ;
@@ -376,7 +374,7 @@ aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
{ blockindx = chan * pima->blocksize + 2 + indx / 2 ;
pima->block [blockindx] = pima->samples [indx] & 0x0F ;
pima->block [blockindx] |= (pima->samples [indx + pima->channels] << 4) & 0xF0 ;
pima->block [blockindx] |= (pima->samples [indx + chan] << 4) & 0xF0 ;
} ;
} ;
@@ -394,7 +392,7 @@ aiff_ima_encode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
static int
wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
{ int chan, k, current, blockindx, indx, indxstart, diff ;
{ int chan, k, predictor, blockindx, indx, indxstart, diff ;
short step, bytecode, stepindx [2] ;
pima->blockcount ++ ;
@@ -411,9 +409,9 @@ wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
/* Read and check the block header. */
for (chan = 0 ; chan < pima->channels ; chan++)
{ current = pima->block [chan*4] | (pima->block [chan*4+1] << 8) ;
if (current & 0x8000)
current -= 0x10000 ;
{ predictor = pima->block [chan*4] | (pima->block [chan*4+1] << 8) ;
if (predictor & 0x8000)
predictor -= 0x10000 ;
stepindx [chan] = pima->block [chan*4+2] ;
stepindx [chan] = clamp_ima_step_index (stepindx [chan]) ;
@@ -422,7 +420,7 @@ wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
if (pima->block [chan*4+3] != 0)
psf_log_printf (psf, "IMA ADPCM synchronisation error.\n") ;
pima->samples [chan] = current ;
pima->samples [chan] = predictor ;
} ;
/*
@@ -455,7 +453,7 @@ wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
bytecode = pima->samples [k] & 0xF ;
step = ima_step_size [stepindx [chan]] ;
current = pima->samples [k - pima->channels] ;
predictor = pima->samples [k - pima->channels] ;
diff = step >> 3 ;
if (bytecode & 1)
@@ -467,17 +465,17 @@ wav_w64_ima_decode_block (SF_PRIVATE *psf, IMA_ADPCM_PRIVATE *pima)
if (bytecode & 8)
diff = -diff ;
current += diff ;
predictor += diff ;
if (current > 32767)
current = 32767 ;
else if (current < -32768)
current = -32768 ;
if (predictor > 32767)
predictor = 32767 ;
else if (predictor < -32768)
predictor = -32768 ;
stepindx [chan] += ima_indx_adjust [bytecode] ;
stepindx [chan] = clamp_ima_step_index (stepindx [chan]) ;
pima->samples [k] = current ;
pima->samples [k] = predictor ;
} ;
return 1 ;
@@ -623,6 +621,7 @@ ima_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
static sf_count_t
ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
@@ -631,8 +630,8 @@ ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : (int) len ;
count = ima_read_block (psf, pima, sptr, readcount) ;
@@ -650,6 +649,7 @@ ima_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
@@ -661,8 +661,8 @@ ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : (int) len ;
count = ima_read_block (psf, pima, sptr, readcount) ;
@@ -680,6 +680,7 @@ ima_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
@@ -691,8 +692,8 @@ ima_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
normfact = (psf->norm_double == SF_TRUE) ? 1.0 / ((double) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : (int) len ;
count = ima_read_block (psf, pima, sptr, readcount) ;
@@ -724,9 +725,7 @@ ima_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
if (offset == 0)
{ psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
pima->blockcount = 0 ;
if (pima->decode_block) {
pima->decode_block (psf, pima) ;
}
pima->decode_block (psf, pima) ;
pima->samplecount = 0 ;
return 0 ;
} ;
@@ -764,7 +763,7 @@ ima_writer_init (SF_PRIVATE *psf, int blockalign)
int samplesperblock ;
unsigned int pimasize ;
if (psf->mode != SFM_WRITE)
if (psf->file.mode != SFM_WRITE)
return SFE_BAD_MODE_RW ;
samplesperblock = 2 * (blockalign - 4 * psf->sf.channels) / psf->sf.channels + 1 ;
@@ -798,7 +797,6 @@ ima_writer_init (SF_PRIVATE *psf, int blockalign)
default :
psf_log_printf (psf, "ima_reader_init: bad psf->sf.format\n") ;
return SFE_INTERNAL ;
break ;
} ;
psf->write_short = ima_write_s ;
@@ -861,6 +859,7 @@ ima_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
static sf_count_t
ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
@@ -869,8 +868,8 @@ ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
return 0 ;
pima = (IMA_ADPCM_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
for (k = 0 ; k < writecount ; k++)
@@ -888,6 +887,7 @@ ima_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
@@ -899,8 +899,8 @@ ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
for (k = 0 ; k < writecount ; k++)
@@ -918,6 +918,7 @@ ima_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ IMA_ADPCM_PRIVATE *pima ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
@@ -929,8 +930,8 @@ ima_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : (int) len ;
for (k = 0 ; k < writecount ; k++)
+5 -3
View File
@@ -1,6 +1,6 @@
/*
** Copyright (C) 2007-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (c) 2007 <robs@users.sourceforge.net>
** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the GNU Lesser General Public License as published by
@@ -19,6 +19,8 @@
/* ADPCM: IMA, OKI <==> 16-bit PCM. */
#include "sfconfig.h"
#include <string.h>
/* Set up for libsndfile environment: */
@@ -75,7 +77,7 @@ adpcm_decode (IMA_OKI_ADPCM * state, int code)
s = ((state->steps [state->step_index] * s) >> 3) & state->mask ;
if (code & 8)
s = -s ;
s = -s ;
s += state->last_output ;
if (s < MIN_SAMPLE || s > MAX_SAMPLE)
@@ -137,7 +139,7 @@ ima_oki_adpcm_encode_block (IMA_OKI_ADPCM * state)
/*
** The codec expects an even number of input samples.
**
**
** Samples should always be passed in even length blocks. If the last block to
** be encoded is odd length, extend that block by one zero valued sample.
*/
+1 -1
View File
@@ -1,6 +1,6 @@
/*
** Copyright (C) 2007-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (c) 2007 <robs@users.sourceforge.net>
** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the GNU Lesser General Public License as published by
+4 -5
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -53,7 +53,7 @@ int
interleave_init (SF_PRIVATE *psf)
{ INTERLEAVE_DATA *pdata ;
if (psf->mode != SFM_READ)
if (psf->file.mode != SFM_READ)
return SFE_INTERLEAVE_MODE ;
if (psf->interleave)
@@ -287,9 +287,8 @@ interleave_read_double (SF_PRIVATE *psf, double *ptr, sf_count_t len)
*/
static sf_count_t
interleave_seek (SF_PRIVATE *psf, int mode, sf_count_t samples_from_start)
{ psf = psf ; mode = mode ;
interleave_seek (SF_PRIVATE * UNUSED (psf), int UNUSED (mode), sf_count_t samples_from_start)
{
/*
** Do nothing here. This is a place holder to prevent the default
** seek function from being called.
+8 -7
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2001-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -80,14 +80,14 @@ ircam_open (SF_PRIVATE *psf)
{ int subformat ;
int error = SFE_NO_ERROR ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = ircam_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_IRCAM)
return SFE_BAD_OPEN_FORMAT ;
@@ -95,7 +95,7 @@ ircam_open (SF_PRIVATE *psf)
if (psf->endian == 0 || psf->endian == SF_ENDIAN_CPU)
psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;
psf->dataoffset = IRCAM_DATA_OFFSET ;
psf->dataoffset = IRCAM_DATA_OFFSET ;
if ((error = ircam_write_header (psf, SF_FALSE)))
return error ;
@@ -163,9 +163,10 @@ ircam_read_header (SF_PRIVATE *psf)
psf->sf.samplerate = (int) samplerate ;
psf_log_printf (psf, " Sample Rate : %d\n"
" Channels : %d\n"
" Encoding : %X => %s\n", psf->sf.samplerate, psf->sf.channels, encoding, get_encoding_str (encoding)) ;
psf_log_printf (psf, " Sample Rate : %d\n"
" Channels : %d\n"
" Encoding : %X => %s\n",
psf->sf.samplerate, psf->sf.channels, encoding, get_encoding_str (encoding)) ;
switch (encoding)
{ case IRCAM_PCM_16 :
+2
View File
@@ -33,7 +33,9 @@ sf_write_double @40
sf_strerror @50
sf_get_string @60
sf_set_string @61
sf_version_string @68
sf_open_fd @70
sf_wchar_open @71
sf_open_virtual @80
sf_write_sync @90
+3 -3
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2003-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -25,7 +25,7 @@
#include "sfendian.h"
#include "common.h"
#if (OS_IS_MACOSX == 1)
#if (OSX_DARWIN_VERSION >= 1)
int
macbinary3_open (SF_PRIVATE * UNUSED (psf))
@@ -41,5 +41,5 @@ macbinary3_open (SF_PRIVATE * UNUSED (psf))
return 0 ;
} /* macbinary3_open */
#endif /* OS_IS_MACOSX */
#endif /* OSX_DARWIN_VERSION */
+1 -1
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2003-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2003-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -0,0 +1,14 @@
#!/bin/bash -e
# This script takes a static library and removes all non-public symbols.
# Ie, it makes a static lib whose symbols are far less likely to clash with
# the symbols of another shared or static library.
grep sf_ Symbols.gnu-binutils | sed -e "s/[ ;]//g" > Symbols.static
ld -r --whole-archive .libs/libsndfile.a -o libsndfile_a.o
objcopy --keep-global-symbols=Symbols.static libsndfile_a.o libsndfile.o
rm -f libsndfile.a
ar cru libsndfile.a libsndfile.o
+9 -8
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -76,7 +76,7 @@ int
mat4_open (SF_PRIVATE *psf)
{ int subformat, error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = mat4_read_header (psf)))
return error ;
} ;
@@ -86,7 +86,7 @@ mat4_open (SF_PRIVATE *psf)
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
@@ -135,7 +135,7 @@ mat4_open (SF_PRIVATE *psf)
static int
mat4_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
mat4_write_header (psf, SF_TRUE) ;
return 0 ;
@@ -206,8 +206,9 @@ mat4_write_header (SF_PRIVATE *psf, int calc_length)
static int
mat4_read_header (SF_PRIVATE *psf)
{ int marker, rows, cols, imag ;
unsigned namesize ;
{ char buffer [256] ;
uint32_t marker, namesize ;
int rows, cols, imag ;
double value ;
const char *marker_str ;
char name [64] ;
@@ -244,8 +245,8 @@ mat4_read_header (SF_PRIVATE *psf)
psf_binheader_readf (psf, "d", &value) ;
snprintf (psf->u.cbuf, sizeof (psf->u.cbuf), " Value : %f\n", value) ;
psf_log_printf (psf, psf->u.cbuf) ;
snprintf (buffer, sizeof (buffer), " Value : %f\n", value) ;
psf_log_printf (psf, buffer) ;
if ((rows != 1) || (cols != 1))
return SFE_MAT4_NO_SAMPLERATE ;
+28 -20
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -86,7 +86,7 @@ int
mat5_open (SF_PRIVATE *psf)
{ int subformat, error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = mat5_read_header (psf)))
return error ;
} ;
@@ -96,7 +96,7 @@ mat5_open (SF_PRIVATE *psf)
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
@@ -143,7 +143,7 @@ mat5_open (SF_PRIVATE *psf)
static int
mat5_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
mat5_write_header (psf, SF_TRUE) ;
return 0 ;
@@ -157,6 +157,7 @@ mat5_write_header (SF_PRIVATE *psf, int calc_length)
{ static const char *filename = "MATLAB 5.0 MAT-file, written by " PACKAGE "-" VERSION ", " ;
static const char *sr_name = "samplerate\0\0\0\0\0\0\0\0\0\0\0" ;
static const char *wd_name = "wavedata\0" ;
char buffer [256] ;
sf_count_t current, datasize ;
int encoding ;
@@ -204,11 +205,11 @@ mat5_write_header (SF_PRIVATE *psf, int calc_length)
psf->headindex = 0 ;
psf_fseek (psf, 0, SEEK_SET) ;
psf_get_date_str (psf->u.cbuf, sizeof (psf->u.scbuf)) ;
psf_binheader_writef (psf, "bb", filename, strlen (filename), psf->u.cbuf, strlen (psf->u.cbuf) + 1) ;
psf_get_date_str (buffer, sizeof (buffer)) ;
psf_binheader_writef (psf, "bb", filename, strlen (filename), buffer, strlen (buffer) + 1) ;
memset (psf->u.scbuf, ' ', 124 - psf->headindex) ;
psf_binheader_writef (psf, "b", psf->u.scbuf, make_size_t (124 - psf->headindex)) ;
memset (buffer, ' ', 124 - psf->headindex) ;
psf_binheader_writef (psf, "b", buffer, make_size_t (124 - psf->headindex)) ;
psf->rwf_endian = psf->endian ;
@@ -257,38 +258,39 @@ mat5_write_header (SF_PRIVATE *psf, int calc_length)
static int
mat5_read_header (SF_PRIVATE *psf)
{ char name [32] ;
{ char buffer [256], name [32] ;
short version, endian ;
int type, flags1, flags2, rows, cols ;
unsigned size ;
int have_samplerate = 1 ;
psf_binheader_readf (psf, "pb", 0, psf->u.cbuf, 124) ;
psf_binheader_readf (psf, "pb", 0, buffer, 124) ;
psf->u.scbuf [125] = 0 ;
buffer [125] = 0 ;
if (strlen (psf->u.cbuf) >= 124)
if (strlen (buffer) >= 124)
return SFE_UNIMPLEMENTED ;
if (strstr (psf->u.cbuf, "MATLAB 5.0 MAT-file") == psf->u.cbuf)
psf_log_printf (psf, "%s\n", psf->u.scbuf) ;
if (strstr (buffer, "MATLAB 5.0 MAT-file") == buffer)
psf_log_printf (psf, "%s\n", buffer) ;
psf_binheader_readf (psf, "E22", &version, &endian) ;
if (endian == MI_MARKER)
{ psf->endian = psf->rwf_endian = SF_ENDIAN_BIG ;
if (CPU_IS_LITTLE_ENDIAN) version = ENDSWAP_SHORT (version) ;
if (CPU_IS_LITTLE_ENDIAN) version = ENDSWAP_16 (version) ;
}
else if (endian == IM_MARKER)
{ psf->endian = psf->rwf_endian = SF_ENDIAN_LITTLE ;
if (CPU_IS_BIG_ENDIAN) version = ENDSWAP_SHORT (version) ;
if (CPU_IS_BIG_ENDIAN) version = ENDSWAP_16 (version) ;
}
else
return SFE_MAT5_BAD_ENDIAN ;
if ((CPU_IS_LITTLE_ENDIAN && endian == IM_MARKER) ||
(CPU_IS_BIG_ENDIAN && endian == MI_MARKER))
version = ENDSWAP_SHORT (version) ;
version = ENDSWAP_16 (version) ;
psf_log_printf (psf, "Version : 0x%04X\n", version) ;
psf_log_printf (psf, "Endian : 0x%04X => %s\n", endian,
@@ -317,11 +319,13 @@ mat5_read_header (SF_PRIVATE *psf)
return SFE_MAT5_NO_BLOCK ;
psf_binheader_readf (psf, "44", &rows, &cols) ;
psf_log_printf (psf, " Rows : %X Cols : %d\n", rows, cols) ;
psf_log_printf (psf, " Rows : %d Cols : %d\n", rows, cols) ;
if (rows != 1 || cols != 1)
return SFE_MAT5_SAMPLE_RATE ;
{ if (psf->sf.samplerate == 0)
psf->sf.samplerate = 44100 ;
have_samplerate = 0 ;
}
psf_binheader_readf (psf, "4", &type) ;
if (type == MAT5_TYPE_SCHAR)
@@ -355,6 +359,9 @@ mat5_read_header (SF_PRIVATE *psf)
psf_binheader_readf (psf, "44", &type, &size) ;
if (!have_samplerate)
goto skip_samplerate ;
switch (type)
{ case MAT5_TYPE_DOUBLE :
{ double samplerate ;
@@ -445,6 +452,7 @@ mat5_read_header (SF_PRIVATE *psf)
psf_binheader_readf (psf, "44", &type, &size) ;
psf_log_printf (psf, " Type : %X Size : %d\n", type, size) ;
skip_samplerate :
/*++++++++++++++++++++++++++++++++++++++++++++++++++*/
if (rows == 0 && cols == 0)
+7 -10
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -38,7 +38,7 @@
** 1 byte: loopMode (0 no loop, 1 forward looping)
** 1 byte: number of beat in loop
** 1 uint16: sampleRate
**
**
** DATA
** Data are always non compressed 16 bits interleaved
*/
@@ -63,10 +63,9 @@ static int mpc2k_read_header (SF_PRIVATE *psf) ;
int
mpc2k_open (SF_PRIVATE *psf)
{ int subformat ;
int error = 0 ;
{ int error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = mpc2k_read_header (psf)))
return error ;
} ;
@@ -74,9 +73,7 @@ mpc2k_open (SF_PRIVATE *psf)
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_MPC2K)
return SFE_BAD_OPEN_FORMAT ;
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (mpc2k_write_header (psf, SF_FALSE))
return psf->error ;
@@ -98,7 +95,7 @@ mpc2k_open (SF_PRIVATE *psf)
static int
mpc2k_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
mpc2k_write_header (psf, SF_TRUE) ;
return 0 ;
@@ -134,7 +131,7 @@ mpc2k_write_header (SF_PRIVATE *psf, int calc_length)
if (psf->is_pipe == SF_FALSE)
psf_fseek (psf, 0, SEEK_SET) ;
snprintf (sample_name, sizeof (sample_name), "%s ", psf->filename) ;
snprintf (sample_name, sizeof (sample_name), "%s ", psf->file.name.c) ;
psf_binheader_writef (psf, "e11b", 1, 4, sample_name, make_size_t (HEADER_NAME_LEN)) ;
psf_binheader_writef (psf, "e111", 100, 0, (psf->sf.channels - 1) & 1) ;
+30 -29
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -44,11 +44,7 @@ typedef struct
sf_count_t samplecount ;
short *samples ;
unsigned char *block ;
#if HAVE_FLEXIBLE_ARRAY
short dummydata [] ; /* ISO C99 struct flexible array. */
#else
short dummydata [0] ; /* This is a hack an might not work. */
#endif
} MSADPCM_PRIVATE ;
/*============================================================================================
@@ -137,15 +133,14 @@ wav_w64_msadpcm_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
return SFE_INTERNAL ;
} ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
samplesperblock = 2 + 2 * (blockalign - 7 * psf->sf.channels) / psf->sf.channels ;
pmssize = sizeof (MSADPCM_PRIVATE) + blockalign + 3 * psf->sf.channels * samplesperblock ;
if (! (psf->codec_data = malloc (pmssize)))
if (! (psf->codec_data = calloc (1, pmssize)))
return SFE_MALLOC_FAILED ;
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
memset (pms, 0, pmssize) ;
pms->samples = pms->dummydata ;
pms->block = (unsigned char*) (pms->dummydata + psf->sf.channels * samplesperblock) ;
@@ -159,8 +154,8 @@ wav_w64_msadpcm_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
return SFE_INTERNAL ;
} ;
if (psf->mode == SFM_READ)
{ pms->dataremaining = psf->datalength ;
if (psf->file.mode == SFM_READ)
{ pms->dataremaining = psf->datalength ;
if (psf->datalength % pms->blocksize)
pms->blocks = psf->datalength / pms->blocksize + 1 ;
@@ -185,7 +180,7 @@ wav_w64_msadpcm_init (SF_PRIVATE *psf, int blockalign, int samplesperblock)
psf->read_double = msadpcm_read_d ;
} ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ pms->samples = pms->dummydata ;
pms->samplecount = 0 ;
@@ -207,9 +202,9 @@ msadpcm_decode_block (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
{ int chan, k, blockindx, sampleindx ;
short bytecode, bpred [2], chan_idelta [2] ;
int predict ;
int current ;
int idelta ;
int predict ;
int current ;
int idelta ;
pms->blockcount ++ ;
pms->samplecount = 0 ;
@@ -278,7 +273,7 @@ msadpcm_decode_block (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
sampleindx = 2 * pms->channels ;
while (blockindx < pms->blocksize)
{ bytecode = pms->block [blockindx++] ;
pms->samples [sampleindx++] = (bytecode >> 4) & 0x0F ;
pms->samples [sampleindx++] = (bytecode >> 4) & 0x0F ;
pms->samples [sampleindx++] = bytecode & 0x0F ;
} ;
@@ -297,7 +292,7 @@ msadpcm_decode_block (SF_PRIVATE *psf, MSADPCM_PRIVATE *pms)
if (bytecode & 0x8)
bytecode -= 0x10 ;
predict = ((pms->samples [k - pms->channels] * AdaptCoeff1 [bpred [chan]])
predict = ((pms->samples [k - pms->channels] * AdaptCoeff1 [bpred [chan]])
+ (pms->samples [k - 2 * pms->channels] * AdaptCoeff2 [bpred [chan]])) >> 8 ; /* => / 256 => FIXED_POINT_COEFF_BASE == 256 */
current = (bytecode * idelta) + predict ;
@@ -364,6 +359,7 @@ msadpcm_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
static sf_count_t
msadpcm_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
{ MSADPCM_PRIVATE *pms ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -372,8 +368,8 @@ msadpcm_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
return 0 ;
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = msadpcm_read_block (psf, pms, sptr, readcount) ;
@@ -390,6 +386,7 @@ msadpcm_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
msadpcm_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ MSADPCM_PRIVATE *pms ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -400,8 +397,8 @@ msadpcm_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
normfact = (psf->norm_float == SF_TRUE) ? 1.0 / ((float) 0x8000) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = msadpcm_read_block (psf, pms, sptr, readcount) ;
@@ -418,6 +415,7 @@ msadpcm_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
msadpcm_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ MSADPCM_PRIVATE *pms ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, readcount = 0, count ;
sf_count_t total = 0 ;
@@ -429,8 +427,8 @@ msadpcm_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
return 0 ;
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = msadpcm_read_block (psf, pms, sptr, readcount) ;
@@ -674,6 +672,7 @@ msadpcm_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
static sf_count_t
msadpcm_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
{ MSADPCM_PRIVATE *pms ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
@@ -682,8 +681,8 @@ msadpcm_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
return 0 ;
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -700,6 +699,7 @@ msadpcm_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
msadpcm_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ MSADPCM_PRIVATE *pms ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
@@ -711,8 +711,8 @@ msadpcm_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFF) : 1.0 ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -729,6 +729,7 @@ msadpcm_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
msadpcm_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ MSADPCM_PRIVATE *pms ;
BUF_UNION ubuf ;
short *sptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
@@ -740,8 +741,8 @@ msadpcm_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
return 0 ;
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
sptr = psf->u.sbuf ;
bufferlen = ARRAY_LEN (psf->u.sbuf) ;
sptr = ubuf.sbuf ;
bufferlen = ARRAY_LEN (ubuf.sbuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -764,7 +765,7 @@ msadpcm_close (SF_PRIVATE *psf)
pms = (MSADPCM_PRIVATE*) psf->codec_data ;
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ /* Now we know static int for certain the length of the file we can
** re-write the header.
*/
+116
View File
@@ -0,0 +1,116 @@
/*
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
#if (ENABLE_EXPERIMENTAL_CODE == 0)
int
new_open (SF_PRIVATE *psf)
{ if (psf)
return SFE_UNIMPLEMENTED ;
return (psf && 0) ;
} /* new_open */
#else
/*------------------------------------------------------------------------------
** Macros to handle big/little endian issues.
*/
/*------------------------------------------------------------------------------
** Typedefs.
*/
/*------------------------------------------------------------------------------
** Private static functions.
*/
static int new_read_header (SF_PRIVATE *psf) ;
/*------------------------------------------------------------------------------
** Public function.
*/
int
new_open (SF_PRIVATE *psf)
{ int subformat, error = 0 ;
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
return SFE_UNIMPLEMENTED ;
if ((error = new_read_header (psf)))
return error ;
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_WVE)
return SFE_BAD_OPEN_FORMAT ;
subformat = SF_CODEC (psf->sf.format) ;
return error ;
} /* new_open */
/*------------------------------------------------------------------------------
*/
static int
new_read_header (SF_PRIVATE *psf)
{ int marker ;
/* Set position to start of file to begin reading header. */
psf_binheader_readf (psf, "pm", 0, &marker) ;
if (marker != ALAW_MARKER)
return SFE_WVE_NOT_WVE ;
psf_binheader_readf (psf, "m", &marker) ;
if (marker != SOUN_MARKER)
return SFE_WVE_NOT_WVE ;
psf_binheader_readf (psf, "m", &marker) ;
if (marker != DFIL_MARKER)
return SFE_WVE_NOT_WVE ;
psf_log_printf (psf, "Read only : Psion Alaw\n"
" Sample Rate : 8000\n"
" Channels : 1\n"
" Encoding : A-law\n") ;
psf->dataoffset = 0x20 ;
psf->datalength = psf->filelength - psf->dataoffset ;
psf->sf.format = SF_FORMAT_WVE | SF_FORMAT_ALAW ;
psf->sf.samplerate = 8000 ;
psf->sf.frames = psf->datalength ;
psf->sf.channels = 1 ;
return alaw_init (psf) ;
} /* new_read_header */
/*------------------------------------------------------------------------------
*/
#endif
+31 -15
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -54,12 +54,12 @@ int
nist_open (SF_PRIVATE *psf)
{ int error ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = nist_read_header (psf)))
return error ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
@@ -118,15 +118,12 @@ static char bad_header [] =
static int
nist_read_header (SF_PRIVATE *psf)
{ char *psf_header ;
int bitwidth = 0, bytes = 0, count, encoding ;
{ char psf_header [NIST_HEADER_LENGTH + 2] ;
int bitwidth = 0, count, encoding ;
unsigned bytes = 0 ;
char str [64], *cptr ;
long samples ;
psf->sf.format = SF_FORMAT_NIST ;
psf_header = psf->u.cbuf ;
if (sizeof (psf->header) <= NIST_HEADER_LENGTH)
return SFE_INTERNAL ;
@@ -164,7 +161,9 @@ nist_read_header (SF_PRIVATE *psf)
{ sscanf (cptr, "sample_coding -s%d %63s", &count, str) ;
if (strcmp (str, "pcm") == 0)
{ /* Correct this later when we find out the bitwidth. */
encoding = SF_FORMAT_PCM_U8 ;
}
else if (strcmp (str, "alaw") == 0)
encoding = SF_FORMAT_ALAW ;
else if ((strcmp (str, "ulaw") == 0) || (strcmp (str, "mu-law") == 0))
@@ -193,19 +192,23 @@ nist_read_header (SF_PRIVATE *psf)
psf->endian = (CPU_IS_BIG_ENDIAN) ? SF_ENDIAN_BIG : SF_ENDIAN_LITTLE ;
/* This is where we figure out endian-ness. */
if ((cptr = strstr (psf_header, "sample_byte_format -s")))
{ sscanf (cptr, "sample_byte_format -s%d %8s", &bytes, str) ;
if ((cptr = strstr (psf_header, "sample_byte_format -s"))
&& sscanf (cptr, "sample_byte_format -s%u %8s", &bytes, str) == 2)
{
if (bytes != strlen (str))
psf_log_printf (psf, "Weird sample_byte_format : strlen '%s' != %d\n", str, bytes) ;
if (bytes > 1)
{ if (psf->bytewidth == 0)
psf->bytewidth = bytes ;
else if (psf->bytewidth != bytes)
else if (psf->bytewidth - bytes != 0)
{ psf_log_printf (psf, "psf->bytewidth (%d) != bytes (%d)\n", psf->bytewidth, bytes) ;
return SFE_NIST_BAD_ENCODING ;
} ;
if (strstr (str, "01") == str)
if (strcmp (str, "01") == 0)
psf->endian = SF_ENDIAN_LITTLE ;
else if (strstr (str, "10"))
else if (strcmp (str, "10") == 0)
psf->endian = SF_ENDIAN_BIG ;
else
{ psf_log_printf (psf, "Weird endian-ness : %s\n", str) ;
@@ -255,13 +258,26 @@ nist_read_header (SF_PRIVATE *psf)
else
return SFE_UNIMPLEMENTED ;
/* Sanitize psf->sf.format. */
switch (SF_CODEC (psf->sf.format))
{ case SF_FORMAT_ULAW :
case SF_FORMAT_ALAW :
case SF_FORMAT_PCM_U8 :
/* Blank out endian bits. */
psf->sf.format = SF_FORMAT_NIST | SF_CODEC (psf->sf.format) ;
break ;
default :
break ;
} ;
return 0 ;
} /* nist_read_header */
static int
nist_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
nist_write_header (psf, SF_TRUE) ;
return 0 ;
+132 -1037
View File
File diff suppressed because it is too large. Load diff
+52
View File
@@ -0,0 +1,52 @@
/*
** Copyright (C) 2008-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software ; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation ; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY ; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program ; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef SF_SRC_OGG_H
enum
{ OGG_ANNODEX = 300,
OGG_ANXDATA,
OGG_FLAC,
OGG_FLAC0,
OGG_PCM,
OGG_SPEEX,
OGG_VORBIS,
} ;
typedef struct
{ /* Sync and verify incoming physical bitstream */
ogg_sync_state osync ;
/* Take physical pages, weld into a logical stream of packets */
ogg_stream_state ostream ;
/* One Ogg bitstream page. Vorbis packets are inside */
ogg_page opage ;
/* One raw packet of data for decode */
ogg_packet opacket ;
int eos ;
int codec ;
} OGG_PRIVATE ;
#define readint(buf, base) (((buf [base + 3] << 24) & 0xff000000) | \
((buf [base + 2] <<16) & 0xff0000) | \
((buf [base + 1] << 8) & 0xff00) | \
(buf [base] & 0xff))
#endif /* SF_SRC_OGG_H */
+149
View File
@@ -0,0 +1,149 @@
/*
** Copyright (C) 2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software ; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation ; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY ; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program ; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
#if (ENABLE_EXPERIMENTAL_CODE && HAVE_EXTERNAL_LIBS)
#include <ogg/ogg.h>
#include "ogg.h"
typedef struct
{ int32_t serialno ;
void * state ;
} OPUS_PRIVATE ;
static int ogg_opus_read_header (SF_PRIVATE * psf) ;
static int ogg_opus_close (SF_PRIVATE *psf) ;
int
ogg_opus_open (SF_PRIVATE *psf)
{ OGG_PRIVATE* odata = psf->container_data ;
OPUS_PRIVATE* oopus = calloc (1, sizeof (OPUS_PRIVATE)) ;
int error = 0 ;
if (odata == NULL)
{ psf_log_printf (psf, "%s : odata is NULL???\n", __func__) ;
return SFE_INTERNAL ;
} ;
psf->codec_data = oopus ;
if (oopus == NULL)
return SFE_MALLOC_FAILED ;
if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if (psf->file.mode == SFM_READ)
{ /* Call this here so it only gets called once, so no memory is leaked. */
ogg_sync_init (&odata->osync) ;
if ((error = ogg_opus_read_header (psf)))
return error ;
#if 0
psf->read_short = ogg_opus_read_s ;
psf->read_int = ogg_opus_read_i ;
psf->read_float = ogg_opus_read_f ;
psf->read_double = ogg_opus_read_d ;
psf->sf.frames = ogg_opus_length (psf) ;
#endif
} ;
psf->codec_close = ogg_opus_close ;
if (psf->file.mode == SFM_WRITE)
{
#if 0
/* Set the default oopus quality here. */
vdata->quality = 0.4 ;
psf->write_header = ogg_opus_write_header ;
psf->write_short = ogg_opus_write_s ;
psf->write_int = ogg_opus_write_i ;
psf->write_float = ogg_opus_write_f ;
psf->write_double = ogg_opus_write_d ;
#endif
psf->sf.frames = SF_COUNT_MAX ; /* Unknown really */
psf->strings.flags = SF_STR_ALLOW_START ;
} ;
psf->bytewidth = 1 ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
#if 0
psf->seek = ogg_opus_seek ;
psf->command = ogg_opus_command ;
#endif
/* FIXME, FIXME, FIXME : Hack these here for now and correct later. */
psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_SPEEX ;
psf->sf.sections = 1 ;
psf->datalength = 1 ;
psf->dataoffset = 0 ;
/* End FIXME. */
return error ;
} /* ogg_opus_open */
static int
ogg_opus_read_header (SF_PRIVATE * UNUSED (psf))
{
return 0 ;
} /* ogg_opus_read_header */
static int
ogg_opus_close (SF_PRIVATE * UNUSED (psf))
{
return 0 ;
} /* ogg_opus_close */
#else /* ENABLE_EXPERIMENTAL_CODE && HAVE_EXTERNAL_LIBS */
int
ogg_opus_open (SF_PRIVATE *psf)
{
psf_log_printf (psf, "This version of libsndfile was compiled without Ogg/Opus support.\n") ;
return SFE_UNIMPLEMENTED ;
} /* ogg_opus_open */
#endif
+164
View File
@@ -0,0 +1,164 @@
/*
** Copyright (C) 2008-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software ; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation ; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY ; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program ; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
#if (ENABLE_EXPERIMENTAL_CODE && HAVE_EXTERNAL_LIBS)
#include <ogg/ogg.h>
#include "ogg.h"
typedef struct
{ int32_t serialno ;
void * state ;
} OPCM_PRIVATE ;
static int opcm_read_header (SF_PRIVATE * psf) ;
static int opcm_close (SF_PRIVATE *psf) ;
int
ogg_pcm_open (SF_PRIVATE *psf)
{ OGG_PRIVATE* odata = psf->container_data ;
OPCM_PRIVATE* opcm = calloc (1, sizeof (OPCM_PRIVATE)) ;
int error = 0 ;
if (odata == NULL)
{ psf_log_printf (psf, "%s : odata is NULL???\n", __func__) ;
return SFE_INTERNAL ;
} ;
psf->codec_data = opcm ;
if (opcm == NULL)
return SFE_MALLOC_FAILED ;
if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if (psf->file.mode == SFM_READ)
{ /* Call this here so it only gets called once, so no memory is leaked. */
ogg_sync_init (&odata->osync) ;
if ((error = opcm_read_header (psf)))
return error ;
#if 0
psf->read_short = opcm_read_s ;
psf->read_int = opcm_read_i ;
psf->read_float = opcm_read_f ;
psf->read_double = opcm_read_d ;
psf->sf.frames = opcm_length (psf) ;
#endif
} ;
psf->codec_close = opcm_close ;
if (psf->file.mode == SFM_WRITE)
{
#if 0
/* Set the default opcm quality here. */
vdata->quality = 0.4 ;
psf->write_header = opcm_write_header ;
psf->write_short = opcm_write_s ;
psf->write_int = opcm_write_i ;
psf->write_float = opcm_write_f ;
psf->write_double = opcm_write_d ;
#endif
psf->sf.frames = SF_COUNT_MAX ; /* Unknown really */
psf->strings.flags = SF_STR_ALLOW_START ;
} ;
psf->bytewidth = 1 ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
#if 0
psf->seek = opcm_seek ;
psf->command = opcm_command ;
#endif
/* FIXME, FIXME, FIXME : Hack these here for now and correct later. */
psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_SPEEX ;
psf->sf.sections = 1 ;
psf->datalength = 1 ;
psf->dataoffset = 0 ;
/* End FIXME. */
return error ;
} /* ogg_pcm_open */
static int
opcm_read_header (SF_PRIVATE * UNUSED (psf))
{
return 0 ;
} /* opcm_read_header */
static int
opcm_close (SF_PRIVATE * UNUSED (psf))
{
return 0 ;
} /* opcm_close */
/*
encoded_speex_frames = (frames_per_packet * Packets)
= 1 * 272
= 272
audio_samples = encoded_speex_frames * frame_size
= 272 * 640
= 174080
duration = audio_samples / rate
= 174080 / 44100
= 3.947
*/
#else /* ENABLE_EXPERIMENTAL_CODE && HAVE_EXTERNAL_LIBS */
int
ogg_pcm_open (SF_PRIVATE *psf)
{
psf_log_printf (psf, "This version of libsndfile was compiled without Ogg/Speex support.\n") ;
return SFE_UNIMPLEMENTED ;
} /* ogg_pcm_open */
#endif
+425
View File
@@ -0,0 +1,425 @@
/*
** Copyright (C) 2008-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software ; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation ; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY ; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program ; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "sndfile.h"
#include "sfendian.h"
#include "common.h"
#if (ENABLE_EXPERIMENTAL_CODE && HAVE_EXTERNAL_LIBS)
#include <ogg/ogg.h>
#include <speex/speex.h>
#include <speex/speex_stereo.h>
#include <speex/speex_header.h>
#include <speex/speex_callbacks.h>
#include "ogg.h"
#define OGG_SPX_READ_SIZE 200
typedef struct
{ SpeexBits bits ;
int32_t serialno ;
int frame_size, granule_frame_size, nframes ;
int force_mode ;
SpeexStereoState stereo ;
SpeexHeader header ;
void * state ;
} SPX_PRIVATE ;
static int spx_read_header (SF_PRIVATE * psf) ;
static int spx_close (SF_PRIVATE *psf) ;
static void *spx_header_read (SF_PRIVATE * psf, ogg_packet *op, spx_int32_t enh_enabled, int force_mode) ;
static void spx_print_comments (const char *comments, int length) ;
int
ogg_speex_open (SF_PRIVATE *psf)
{ OGG_PRIVATE* odata = psf->container_data ;
SPX_PRIVATE* spx = calloc (1, sizeof (SPX_PRIVATE)) ;
int error = 0 ;
if (odata == NULL)
{ psf_log_printf (psf, "%s : odata is NULL???\n", __func__) ;
return SFE_INTERNAL ;
} ;
psf->codec_data = spx ;
if (spx == NULL)
return SFE_MALLOC_FAILED ;
if (psf->file.mode == SFM_RDWR)
return SFE_BAD_MODE_RW ;
if (psf->file.mode == SFM_READ)
{ /* Call this here so it only gets called once, so no memory is leaked. */
ogg_sync_init (&odata->osync) ;
if ((error = spx_read_header (psf)))
return error ;
#if 0
psf->read_short = spx_read_s ;
psf->read_int = spx_read_i ;
psf->read_float = spx_read_f ;
psf->read_double = spx_read_d ;
psf->sf.frames = spx_length (psf) ;
#endif
} ;
psf->codec_close = spx_close ;
if (psf->file.mode == SFM_WRITE)
{
#if 0
/* Set the default spx quality here. */
vdata->quality = 0.4 ;
psf->write_header = spx_write_header ;
psf->write_short = spx_write_s ;
psf->write_int = spx_write_i ;
psf->write_float = spx_write_f ;
psf->write_double = spx_write_d ;
#endif
psf->sf.frames = SF_COUNT_MAX ; /* Unknown really */
psf->strings.flags = SF_STR_ALLOW_START ;
} ;
psf->bytewidth = 1 ;
psf->blockwidth = psf->bytewidth * psf->sf.channels ;
#if 0
psf->seek = spx_seek ;
psf->command = spx_command ;
#endif
/* FIXME, FIXME, FIXME : Hack these here for now and correct later. */
psf->sf.format = SF_FORMAT_OGG | SF_FORMAT_SPEEX ;
psf->sf.sections = 1 ;
psf->datalength = 1 ;
psf->dataoffset = 0 ;
/* End FIXME. */
return error ;
} /* ogg_speex_open */
#define le_short (x) (x)
static int
spx_read_header (SF_PRIVATE * psf)
{ static SpeexStereoState STEREO_INIT = SPEEX_STEREO_STATE_INIT ;
OGG_PRIVATE* odata = psf->container_data ;
SPX_PRIVATE* spx = psf->codec_data ;
ogg_int64_t page_granule = 0 ;
int stream_init = 0 ;
int page_nb_packets = 0 ;
int packet_count = 0 ;
int enh_enabled = 1 ;
int force_mode = -1 ;
char * data ;
int nb_read ;
int lookahead ;
printf ("%s %d\n", __func__, __LINE__) ;
psf_log_printf (psf, "Speex header\n") ;
odata->eos = 0 ;
/* Reset ogg stuff which has already been used in src/ogg.c. */
ogg_stream_reset (&odata->ostream) ;
ogg_sync_reset (&odata->osync) ;
/* Seek to start of stream. */
psf_fseek (psf, 0, SEEK_SET) ;
/* Initialize. */
ogg_sync_init (&odata->osync) ;
speex_bits_init (&spx->bits) ;
/* Set defaults. */
psf->sf.channels = -1 ;
psf->sf.samplerate = 0 ;
spx->stereo = STEREO_INIT ;
/* Get a pointer to the ogg buffer and read data into it. */
data = ogg_sync_buffer (&odata->osync, OGG_SPX_READ_SIZE) ;
nb_read = psf_fread (data, 1, OGG_SPX_READ_SIZE, psf) ;
ogg_sync_wrote (&odata->osync, nb_read) ;
/* Now we chew on Ogg packets. */
while (ogg_sync_pageout (&odata->osync, &odata->opage) == 1)
{ if (stream_init == 0)
{ ogg_stream_init (&odata->ostream, ogg_page_serialno (&odata->opage)) ;
stream_init = 1 ;
} ;
if (ogg_page_serialno (&odata->opage) != odata->ostream.serialno)
{ /* so all streams are read. */
ogg_stream_reset_serialno (&odata->ostream, ogg_page_serialno (&odata->opage)) ;
} ;
/*Add page to the bitstream*/
ogg_stream_pagein (&odata->ostream, &odata->opage) ;
page_granule = ogg_page_granulepos (&odata->opage) ;
page_nb_packets = ogg_page_packets (&odata->opage) ;
/*Extract all available packets*/
while (odata->eos == 0 && ogg_stream_packetout (&odata->ostream, &odata->opacket) == 1)
{ if (odata->opacket.bytes >= 8 && memcmp (odata->opacket.packet, "Speex ", 8) == 0)
{ spx->serialno = odata->ostream.serialno ;
} ;
if (spx->serialno == -1 || odata->ostream.serialno != spx->serialno)
break ;
if (packet_count == 0)
{ spx->state = spx_header_read (psf, &odata->opacket, enh_enabled, force_mode) ;
if (! spx->state)
break ;
speex_decoder_ctl (spx->state, SPEEX_GET_LOOKAHEAD, &lookahead) ;
if (spx->nframes == 0)
spx->nframes = 1 ;
}
else if (packet_count == 1)
{ spx_print_comments ((const char*) odata->opacket.packet, odata->opacket.bytes) ;
}
else if (packet_count < 2 + spx->header.extra_headers)
{ /* Ignore extra headers */
}
packet_count ++ ;
} ;
} ;
psf_log_printf (psf, "End\n") ;
psf_log_printf (psf, "packet_count %d\n", packet_count) ;
psf_log_printf (psf, "page_nb_packets %d\n", page_nb_packets) ;
psf_log_printf (psf, "page_granule %lld\n", page_granule) ;
return 0 ;
} /* spx_read_header */
static int
spx_close (SF_PRIVATE *psf)
{ SPX_PRIVATE* spx = psf->codec_data ;
if (spx->state)
speex_decoder_destroy (spx->state) ;
if (spx)
speex_bits_destroy (&spx->bits) ;
return 0 ;
} /* spx_close */
static void *
spx_header_read (SF_PRIVATE * psf, ogg_packet *op, spx_int32_t enh_enabled, int force_mode)
{ SPX_PRIVATE* spx = psf->codec_data ;
void *st ;
const SpeexMode *mode ;
SpeexHeader *tmp_header ;
int modeID ;
SpeexCallback callback ;
tmp_header = speex_packet_to_header ((char*) op->packet, op->bytes) ;
if (tmp_header == NULL)
{ psf_log_printf (psf, "Cannot read Speex header\n") ;
return NULL ;
} ;
memcpy (&spx->header, tmp_header, sizeof (spx->header)) ;
free (tmp_header) ;
tmp_header = NULL ;
if (spx->header.mode >= SPEEX_NB_MODES || spx->header.mode < 0)
{ psf_log_printf (psf, "Mode number %d does not (yet/any longer) exist in this version\n", spx->header.mode) ;
return NULL ;
} ;
modeID = spx->header.mode ;
if (force_mode != -1)
modeID = force_mode ;
mode = speex_lib_get_mode (modeID) ;
if (spx->header.speex_version_id > 1)
{ psf_log_printf (psf, "This file was encoded with Speex bit-stream version %d, which I don't know how to decode\n", spx->header.speex_version_id) ;
return NULL ;
} ;
if (mode->bitstream_version < spx->header.mode_bitstream_version)
{ psf_log_printf (psf, "The file was encoded with a newer version of Speex. You need to upgrade in order to play it.\n") ;
return NULL ;
} ;
if (mode->bitstream_version > spx->header.mode_bitstream_version)
{ psf_log_printf (psf, "The file was encoded with an older version of Speex. You would need to downgrade the version in order to play it.\n") ;
return NULL ;
} ;
st = speex_decoder_init (mode) ;
if (!st)
{ psf_log_printf (psf, "Decoder initialization failed.\n") ;
return NULL ;
} ;
speex_decoder_ctl (st, SPEEX_SET_ENH, &enh_enabled) ;
speex_decoder_ctl (st, SPEEX_GET_FRAME_SIZE, &spx->frame_size) ;
spx->granule_frame_size = spx->frame_size ;
if (!psf->sf.samplerate)
psf->sf.samplerate = spx->header.rate ;
/* Adjust rate if --force-* options are used */
if (force_mode != -1)
{ if (spx->header.mode < force_mode)
{ psf->sf.samplerate <<= (force_mode - spx->header.mode) ;
spx->granule_frame_size >>= (force_mode - spx->header.mode) ;
} ;
if (spx->header.mode > force_mode)
{ psf->sf.samplerate >>= (spx->header.mode - force_mode) ;
spx->granule_frame_size <<= (spx->header.mode - force_mode) ;
} ;
} ;
speex_decoder_ctl (st, SPEEX_SET_SAMPLING_RATE, &psf->sf.samplerate) ;
spx->nframes = spx->header.frames_per_packet ;
if (psf->sf.channels == -1)
psf->sf.channels = spx->header.nb_channels ;
if (! (psf->sf.channels == 1))
{ psf->sf.channels = 2 ;
callback.callback_id = SPEEX_INBAND_STEREO ;
callback.func = speex_std_stereo_request_handler ;
callback.data = &spx->stereo ;
speex_decoder_ctl (st, SPEEX_SET_HANDLER, &callback) ;
} ;
spx->header.speex_version [sizeof (spx->header.speex_version) - 1] = 0 ;
psf_log_printf (psf, " Encoder ver : %s\n Frames/packet : %d\n",
spx->header.speex_version, spx->header.frames_per_packet) ;
if (spx->header.bitrate > 0)
psf_log_printf (psf, " Bit rate : %d\n", spx->header.bitrate) ;
psf_log_printf (psf, " Sample rate : %d\n Mode : %s\n VBR : %s\n Channels : %d\n",
psf->sf.samplerate, mode->modeName, (spx->header.vbr ? "yes" : "no"), psf->sf.channels) ;
psf_log_printf (psf, " Extra headers : %d\n", spx->header.extra_headers) ;
return st ;
} /* spx_header_read */
static void
spx_print_comments (const char *c, int length)
{
const char *end ;
int len, i, nb_fields ;
printf ("%s %d\n", __func__, __LINE__) ;
if (length < 8)
{ fprintf (stderr, "Invalid/corrupted comments\n") ;
return ;
}
end = c + length ;
len = readint (c, 0) ;
c += 4 ;
if (len < 0 || c + len > end)
{ fprintf (stderr, "Invalid/corrupted comments\n") ;
return ;
}
(void) fwrite (c, 1, len, stderr) ;
c += len ;
fprintf (stderr, "\n") ;
if (c + 4 > end)
{ fprintf (stderr, "Invalid/corrupted comments\n") ;
return ;
}
nb_fields = readint (c, 0) ;
c += 4 ;
for (i = 0 ; i < nb_fields ; i++)
{ if (c + 4 > end)
{ fprintf (stderr, "Invalid/corrupted comments\n") ;
return ;
} ;
len = readint (c, 0) ;
c += 4 ;
if (len < 0 || c + len > end)
{ fprintf (stderr, "Invalid/corrupted comments\n") ;
return ;
}
(void) fwrite (c, 1, len, stderr) ;
c += len ;
fprintf (stderr, "\n") ;
} ;
return ;
} /* spx_print_comments */
/*
encoded_speex_frames = (frames_per_packet * Packets)
= 1 * 272
= 272
audio_samples = encoded_speex_frames * frame_size
= 272 * 640
= 174080
duration = audio_samples / rate
= 174080 / 44100
= 3.947
*/
#else /* ENABLE_EXPERIMENTAL_CODE && HAVE_EXTERNAL_LIBS */
int
ogg_speex_open (SF_PRIVATE *psf)
{
psf_log_printf (psf, "This version of libsndfile was compiled without Ogg/Speex support.\n") ;
return SFE_UNIMPLEMENTED ;
} /* ogg_speex_open */
#endif
File diff suppressed because it is too large. Load diff
+63 -74
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -52,23 +52,19 @@
typedef struct
{ int version ;
int endianness ;
int samplerate ;
int format ;
int samplerate ;
int format ;
int channels ;
int source ;
} PAF_FMT ;
typedef struct
{ int max_blocks, channels, samplesperblock, blocksize ;
{ int max_blocks, channels, blocksize ;
int read_block, write_block, read_count, write_count ;
sf_count_t sample_count ;
int *samples ;
unsigned char *block ;
#if HAVE_FLEXIBLE_ARRAY
int data [] ; /* ISO C99 struct flexible array. */
#else
int data [1] ; /* This is a hack and may not work. */
#endif
} PAF24_PRIVATE ;
/*------------------------------------------------------------------------------
@@ -108,14 +104,14 @@ paf_open (SF_PRIVATE *psf)
psf->dataoffset = PAF_HEADER_LENGTH ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = paf_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_PAF)
return SFE_BAD_OPEN_FORMAT ;
@@ -163,6 +159,9 @@ paf_read_header (SF_PRIVATE *psf)
{ PAF_FMT paf_fmt ;
int marker ;
if (psf->filelength < PAF_HEADER_LENGTH)
return SFE_PAF_SHORT_HEADER ;
memset (&paf_fmt, 0, sizeof (paf_fmt)) ;
psf_binheader_readf (psf, "pm", 0, &marker) ;
@@ -199,8 +198,8 @@ paf_read_header (SF_PRIVATE *psf)
psf->endian = SF_ENDIAN_BIG ;
} ;
if (psf->filelength < PAF_HEADER_LENGTH)
return SFE_PAF_SHORT_HEADER ;
if (paf_fmt.channels < 1 || paf_fmt.channels > SF_MAX_CHANNELS)
return SFE_PAF_BAD_CHANNELS ;
psf->datalength = psf->filelength - psf->dataoffset ;
@@ -356,20 +355,18 @@ paf24_init (SF_PRIVATE *psf)
*/
psf->last_op = 0 ;
if (! (psf->codec_data = malloc (paf24size)))
if (! (psf->codec_data = calloc (1, paf24size)))
return SFE_MALLOC_FAILED ;
ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
memset (ppaf24, 0, paf24size) ;
ppaf24->channels = psf->sf.channels ;
ppaf24->samples = ppaf24->data ;
ppaf24->block = (unsigned char*) (ppaf24->data + PAF24_SAMPLES_PER_BLOCK * ppaf24->channels) ;
ppaf24->blocksize = PAF24_BLOCK_SIZE * ppaf24->channels ;
ppaf24->samplesperblock = PAF24_SAMPLES_PER_BLOCK ;
if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ paf24_read_block (psf, ppaf24) ; /* Read first block. */
psf->read_short = paf24_read_s ;
@@ -378,7 +375,7 @@ paf24_init (SF_PRIVATE *psf)
psf->read_double = paf24_read_d ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->write_short = paf24_write_s ;
psf->write_int = paf24_write_i ;
psf->write_float = paf24_write_f ;
@@ -392,7 +389,7 @@ paf24_init (SF_PRIVATE *psf)
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->datalength % PAF24_BLOCK_SIZE)
{ if (psf->mode == SFM_READ)
{ if (psf->file.mode == SFM_READ)
psf_log_printf (psf, "*** Warning : file seems to be truncated.\n") ;
ppaf24->max_blocks = psf->datalength / ppaf24->blocksize + 1 ;
}
@@ -400,12 +397,12 @@ paf24_init (SF_PRIVATE *psf)
ppaf24->max_blocks = psf->datalength / ppaf24->blocksize ;
ppaf24->read_block = 0 ;
if (psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_RDWR)
ppaf24->write_block = ppaf24->max_blocks ;
else
ppaf24->write_block = 0 ;
psf->sf.frames = ppaf24->samplesperblock * ppaf24->max_blocks ;
psf->sf.frames = PAF24_SAMPLES_PER_BLOCK * ppaf24->max_blocks ;
ppaf24->sample_count = psf->sf.frames ;
return 0 ;
@@ -426,8 +423,8 @@ paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
if (mode == SFM_READ && ppaf24->write_count > 0)
paf24_write_block (psf, ppaf24) ;
newblock = offset / ppaf24->samplesperblock ;
newsample = offset % ppaf24->samplesperblock ;
newblock = offset / PAF24_SAMPLES_PER_BLOCK ;
newsample = offset % PAF24_SAMPLES_PER_BLOCK ;
switch (mode)
{ case SFM_READ :
@@ -460,7 +457,7 @@ paf24_seek (SF_PRIVATE *psf, int mode, sf_count_t offset)
return PSF_SEEK_ERROR ;
} ;
return newblock * ppaf24->samplesperblock + newsample ;
return newblock * PAF24_SAMPLES_PER_BLOCK + newsample ;
} /* paf24_seek */
static int
@@ -472,7 +469,7 @@ paf24_close (SF_PRIVATE *psf)
ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (ppaf24->write_count > 0)
paf24_write_block (psf, ppaf24) ;
} ;
@@ -490,8 +487,8 @@ paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
ppaf24->read_block ++ ;
ppaf24->read_count = 0 ;
if (ppaf24->read_block * ppaf24->samplesperblock > ppaf24->sample_count)
{ memset (ppaf24->samples, 0, ppaf24->samplesperblock * ppaf24->channels) ;
if (ppaf24->read_block * PAF24_SAMPLES_PER_BLOCK > ppaf24->sample_count)
{ memset (ppaf24->samples, 0, PAF24_SAMPLES_PER_BLOCK * ppaf24->channels) ;
return 1 ;
} ;
@@ -500,29 +497,15 @@ paf24_read_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
psf_log_printf (psf, "*** Warning : short read (%d != %d).\n", k, ppaf24->blocksize) ;
if (CPU_IS_LITTLE_ENDIAN)
{ /* Do endian swapping if necessary. */
if (psf->endian == SF_ENDIAN_BIG)
endswap_int_array (ppaf24->data, 8 * ppaf24->channels) ;
/* Do endian swapping if necessary. */
if (psf->endian == SF_ENDIAN_BIG)
endswap_int_array (ppaf24->data, 8 * ppaf24->channels) ;
/* Unpack block. */
for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
{ channel = k % ppaf24->channels ;
cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
ppaf24->samples [k] = (cptr [0] << 8) | (cptr [1] << 16) | (cptr [2] << 24) ;
} ;
}
else
{ /* Do endian swapping if necessary. */
if (psf->endian == SF_ENDIAN_BIG)
endswap_int_array (ppaf24->data, 8 * ppaf24->channels) ;
/* Unpack block. */
for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
{ channel = k % ppaf24->channels ;
cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
ppaf24->samples [k] = (cptr [0] << 8) | (cptr [1] << 16) | (cptr [2] << 24) ;
} ;
/* Unpack block. */
for (k = 0 ; k < PAF24_SAMPLES_PER_BLOCK * ppaf24->channels ; k++)
{ channel = k % ppaf24->channels ;
cptr = ppaf24->block + PAF24_BLOCK_SIZE * channel + 3 * (k / ppaf24->channels) ;
ppaf24->samples [k] = (cptr [0] << 8) | (cptr [1] << 16) | (cptr [2] << 24) ;
} ;
return 1 ;
@@ -533,15 +516,15 @@ paf24_read (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, int *ptr, int len)
{ int count, total = 0 ;
while (total < len)
{ if (ppaf24->read_block * ppaf24->samplesperblock >= ppaf24->sample_count)
{ if (ppaf24->read_block * PAF24_SAMPLES_PER_BLOCK >= ppaf24->sample_count)
{ memset (&(ptr [total]), 0, (len - total) * sizeof (int)) ;
return total ;
} ;
if (ppaf24->read_count >= ppaf24->samplesperblock)
if (ppaf24->read_count >= PAF24_SAMPLES_PER_BLOCK)
paf24_read_block (psf, ppaf24) ;
count = (ppaf24->samplesperblock - ppaf24->read_count) * ppaf24->channels ;
count = (PAF24_SAMPLES_PER_BLOCK - ppaf24->read_count) * ppaf24->channels ;
count = (len - total > count) ? count : len - total ;
memcpy (&(ptr [total]), &(ppaf24->samples [ppaf24->read_count * ppaf24->channels]), count * sizeof (int)) ;
@@ -554,7 +537,8 @@ paf24_read (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, int *ptr, int len)
static sf_count_t
paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ PAF24_PRIVATE *ppaf24 ;
{ BUF_UNION ubuf ;
PAF24_PRIVATE *ppaf24 ;
int *iptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
@@ -563,8 +547,8 @@ paf24_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
return 0 ;
ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = paf24_read (psf, ppaf24, iptr, readcount) ;
@@ -592,7 +576,8 @@ paf24_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ PAF24_PRIVATE *ppaf24 ;
{ BUF_UNION ubuf ;
PAF24_PRIVATE *ppaf24 ;
int *iptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
@@ -604,8 +589,8 @@ paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = paf24_read (psf, ppaf24, iptr, readcount) ;
@@ -619,7 +604,8 @@ paf24_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ PAF24_PRIVATE *ppaf24 ;
{ BUF_UNION ubuf ;
PAF24_PRIVATE *ppaf24 ;
int *iptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
@@ -631,8 +617,8 @@ paf24_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
normfact = (psf->norm_double == SF_TRUE) ? (1.0 / 0x80000000) : (1.0 / 0x100) ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = paf24_read (psf, ppaf24, iptr, readcount) ;
@@ -686,10 +672,10 @@ paf24_write_block (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24)
if ((k = psf_fwrite (ppaf24->block, 1, ppaf24->blocksize, psf)) != ppaf24->blocksize)
psf_log_printf (psf, "*** Warning : short write (%d != %d).\n", k, ppaf24->blocksize) ;
if (ppaf24->sample_count < ppaf24->write_block * ppaf24->samplesperblock + ppaf24->write_count)
ppaf24->sample_count = ppaf24->write_block * ppaf24->samplesperblock + ppaf24->write_count ;
if (ppaf24->sample_count < ppaf24->write_block * PAF24_SAMPLES_PER_BLOCK + ppaf24->write_count)
ppaf24->sample_count = ppaf24->write_block * PAF24_SAMPLES_PER_BLOCK + ppaf24->write_count ;
if (ppaf24->write_count == ppaf24->samplesperblock)
if (ppaf24->write_count == PAF24_SAMPLES_PER_BLOCK)
{ ppaf24->write_block ++ ;
ppaf24->write_count = 0 ;
} ;
@@ -702,7 +688,7 @@ paf24_write (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, const int *ptr, int len)
{ int count, total = 0 ;
while (total < len)
{ count = (ppaf24->samplesperblock - ppaf24->write_count) * ppaf24->channels ;
{ count = (PAF24_SAMPLES_PER_BLOCK - ppaf24->write_count) * ppaf24->channels ;
if (count > len - total)
count = len - total ;
@@ -711,7 +697,7 @@ paf24_write (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, const int *ptr, int len)
total += count ;
ppaf24->write_count += count / ppaf24->channels ;
if (ppaf24->write_count >= ppaf24->samplesperblock)
if (ppaf24->write_count >= PAF24_SAMPLES_PER_BLOCK)
paf24_write_block (psf, ppaf24) ;
} ;
@@ -720,7 +706,8 @@ paf24_write (SF_PRIVATE *psf, PAF24_PRIVATE *ppaf24, const int *ptr, int len)
static sf_count_t
paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ PAF24_PRIVATE *ppaf24 ;
{ BUF_UNION ubuf ;
PAF24_PRIVATE *ppaf24 ;
int *iptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -729,8 +716,8 @@ paf24_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
return 0 ;
ppaf24 = (PAF24_PRIVATE*) psf->codec_data ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -770,7 +757,8 @@ paf24_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ PAF24_PRIVATE *ppaf24 ;
{ BUF_UNION ubuf ;
PAF24_PRIVATE *ppaf24 ;
int *iptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -782,8 +770,8 @@ paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
normfact = (psf->norm_float == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -800,7 +788,8 @@ paf24_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ PAF24_PRIVATE *ppaf24 ;
{ BUF_UNION ubuf ;
PAF24_PRIVATE *ppaf24 ;
int *iptr ;
int k, bufferlen, writecount = 0, count ;
sf_count_t total = 0 ;
@@ -812,8 +801,8 @@ paf24_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
normfact = (psf->norm_double == SF_TRUE) ? (1.0 * 0x7FFFFFFF) : (1.0 / 0x100) ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
+323 -263
View File
File diff suppressed because it is too large. Load diff
+3 -3
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -51,14 +51,14 @@ pvf_open (SF_PRIVATE *psf)
{ int subformat ;
int error = 0 ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = pvf_read_header (psf)))
return error ;
} ;
subformat = SF_CODEC (psf->sf.format) ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_PVF)
return SFE_BAD_OPEN_FORMAT ;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
+286 -56
View File
@@ -1,5 +1,6 @@
/*
** Copyright (C) 2008-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2008-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2009 Uli Franke <cls@nebadje.org>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -19,6 +20,9 @@
/*
** This format documented at:
** http://www.sr.se/utveckling/tu/bwf/prog/RF_64v1_4.pdf
**
** But this may be a better reference:
** http://www.ebu.ch/CMSimages/en/tec_doc_t3306-2007_tcm6-42570.pdf
*/
#include "sfconfig.h"
@@ -44,6 +48,11 @@
#define fact_MARKER MAKE_MARKER ('f', 'a', 'c', 't')
#define data_MARKER MAKE_MARKER ('d', 'a', 't', 'a')
#define bext_MARKER MAKE_MARKER ('b', 'e', 'x', 't')
#define cart_MARKER MAKE_MARKER ('c', 'a', 'r', 't')
#define OggS_MARKER MAKE_MARKER ('O', 'g', 'g', 'S')
#define wvpk_MARKER MAKE_MARKER ('w', 'v', 'p', 'k')
/*------------------------------------------------------------------------------
** Typedefs.
*/
@@ -52,9 +61,10 @@
** Private static functions.
*/
static int rf64_read_header (SF_PRIVATE *psf) ;
static int rf64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock) ;
static int rf64_write_header (SF_PRIVATE *psf, int calc_length) ;
static int rf64_close (SF_PRIVATE *psf) ;
static int rf64_command (SF_PRIVATE *psf, int command, void * UNUSED (data), int datasize) ;
/*------------------------------------------------------------------------------
** Public function.
@@ -64,17 +74,19 @@ int
rf64_open (SF_PRIVATE *psf)
{ WAV_PRIVATE *wpriv ;
int subformat, error = 0 ;
int blockalign, framesperblock ;
if ((wpriv = calloc (1, sizeof (WAV_PRIVATE))) == NULL)
return SFE_MALLOC_FAILED ;
psf->container_data = wpriv ;
wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
/* All RF64 files are little endian. */
psf->endian = SF_ENDIAN_LITTLE ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = rf64_read_header (psf)) != 0)
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = rf64_read_header (psf, &blockalign, &framesperblock)) != 0)
return error ;
} ;
@@ -83,7 +95,7 @@ rf64_open (SF_PRIVATE *psf)
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
@@ -96,6 +108,7 @@ rf64_open (SF_PRIVATE *psf)
} ;
psf->container_close = rf64_close ;
psf->command = rf64_command ;
switch (subformat)
{ case SF_FORMAT_PCM_U8 :
@@ -132,68 +145,162 @@ rf64_open (SF_PRIVATE *psf)
/*------------------------------------------------------------------------------
*/
enum
{ HAVE_ds64 = 0x01,
HAVE_fmt = 0x02,
HAVE_bext = 0x04,
HAVE_data = 0x08,
HAVE_cart = 0x10
} ;
#define HAVE_CHUNK(CHUNK) ((parsestage & CHUNK) != 0)
static int
rf64_read_header (SF_PRIVATE *psf)
{ WAV_PRIVATE *wpriv ;
sf_count_t riff_size, data_size ;
unsigned int size32 ;
int marker, marks [2], error, done = 0 ;
rf64_read_header (SF_PRIVATE *psf, int *blockalign, int *framesperblock)
{ WAV_PRIVATE *wpriv ;
WAV_FMT *wav_fmt ;
sf_count_t riff_size = 0, frame_count = 0, ds64_datalength = 0 ;
uint32_t marks [2], size32, parsestage = 0 ;
int marker, error, done = 0, format = 0 ;
if ((wpriv = psf->container_data) == NULL)
return SFE_INTERNAL ;
wav_fmt = &wpriv->wav_fmt ;
/* Set position to start of file to begin reading header. */
psf_binheader_readf (psf, "pmmm", 0, &marker, marks, marks + 1) ;
if (marker != RF64_MARKER || marks [0] != FFFF_MARKER || marks [1] != WAVE_MARKER)
if (marker != RF64_MARKER || marks [1] != WAVE_MARKER)
return SFE_RF64_NOT_RF64 ;
psf_log_printf (psf, "%M\n %M\n", RF64_MARKER, WAVE_MARKER) ;
if (marks [0] == FFFF_MARKER)
psf_log_printf (psf, "%M\n %M\n", RF64_MARKER, WAVE_MARKER) ;
else
psf_log_printf (psf, "%M : 0x%x (should be 0xFFFFFFFF)\n %M\n", RF64_MARKER, WAVE_MARKER) ;
while (! done)
while (NOT (done))
{ psf_binheader_readf (psf, "em4", &marker, &size32) ;
switch (marker)
{ case ds64_MARKER :
{ unsigned int table_len, bytesread ;
/* Read ds64 sizes (3 8-byte words). */
bytesread = psf_binheader_readf (psf, "888", &riff_size, &ds64_datalength, &frame_count) ;
/* Read table length. */
bytesread += psf_binheader_readf (psf, "4", &table_len) ;
/* Skip table for now. (this was "table_len + 4", why?) */
bytesread += psf_binheader_readf (psf, "j", table_len) ;
if (size32 == bytesread)
psf_log_printf (psf, "%M : %u\n", marker, size32) ;
else if (size32 >= bytesread + 4)
{ unsigned int next ;
psf_binheader_readf (psf, "m", &next) ;
if (next == fmt_MARKER)
{ psf_log_printf (psf, "%M : %u (should be %u)\n", marker, size32, bytesread) ;
psf_binheader_readf (psf, "j", -4) ;
}
else
{ psf_log_printf (psf, "%M : %u\n", marker, size32) ;
psf_binheader_readf (psf, "j", size32 - bytesread - 4) ;
} ;
} ;
if (psf->filelength != riff_size + 8)
psf_log_printf (psf, " Riff size : %D (should be %D)\n", riff_size, psf->filelength - 8) ;
else
psf_log_printf (psf, " Riff size : %D\n", riff_size) ;
psf_log_printf (psf, " Data size : %D\n", ds64_datalength) ;
psf_log_printf (psf, " Frames : %D\n", frame_count) ;
psf_log_printf (psf, " Table length : %u\n", table_len) ;
} ;
parsestage |= HAVE_ds64 ;
break ;
case fmt_MARKER:
psf_log_printf (psf, "%M : %u\n", marker, size32) ;
psf_binheader_readf (psf, "888", &riff_size, &data_size, &psf->sf.frames) ;
psf_log_printf (psf, " Riff size : %D\n Data size : %D\n Frames : %D\n",
riff_size, data_size, psf->sf.frames) ;
psf_binheader_readf (psf, "4", &size32) ;
psf_log_printf (psf, " Table len : %u\n", size32) ;
psf_binheader_readf (psf, "jm4", size32 + 4, &marker, &size32) ;
psf_log_printf (psf, "%M : %u\n", marker, size32) ;
if ((error = wav_w64_read_fmt_chunk (psf, size32)) != 0)
return error ;
psf->sf.format = SF_FORMAT_RF64 | (psf->sf.format & SF_FORMAT_SUBMASK) ;
format = wav_fmt->format ;
parsestage |= HAVE_fmt ;
break ;
case bext_MARKER :
if ((error = wav_read_bext_chunk (psf, size32)) != 0)
return error ;
parsestage |= HAVE_bext ;
break ;
case cart_MARKER :
if ((error = wav_read_cart_chunk (psf, size32)) != 0)
return error ;
parsestage |= HAVE_cart ;
break ;
case data_MARKER :
psf_log_printf (psf, "%M : %x\n", marker, size32) ;
psf->dataoffset = psf->headindex ;
done = SF_TRUE ;
break ;
/* see wav for more sophisticated parsing -> implement state machine with parsestage */
if (HAVE_CHUNK (HAVE_ds64))
{ if (size32 == 0xffffffff)
psf_log_printf (psf, "%M : 0x%x\n", marker, size32) ;
else
psf_log_printf (psf, "%M : 0x%x (should be 0xffffffff\n", marker, size32) ;
psf->datalength = ds64_datalength ;
}
else
{ if (size32 == 0xffffffff)
{ psf_log_printf (psf, "%M : 0x%x\n", marker, size32) ;
psf_log_printf (psf, " *** Data length not specified no 'ds64' chunk.\n") ;
}
else
{ psf_log_printf (psf, "%M : 0x%x\n**** Weird, RF64 file without a 'ds64' chunk and no valid 'data' size.\n", marker, size32) ;
psf->datalength = size32 ;
} ;
} ;
psf->dataoffset = psf_ftell (psf) ;
if (psf->dataoffset > 0)
{ if (size32 == 0 && riff_size == 8 && psf->filelength > 44)
{ psf_log_printf (psf, " *** Looks like a WAV file which wasn't closed properly. Fixing it.\n") ;
psf->datalength = psf->filelength - psf->dataoffset ;
} ;
/* Only set dataend if there really is data at the end. */
if (psf->datalength + psf->dataoffset < psf->filelength)
psf->dataend = psf->datalength + psf->dataoffset ;
if (NOT (psf->sf.seekable) || psf->dataoffset < 0)
break ;
/* Seek past data and continue reading header. */
psf_fseek (psf, psf->datalength, SEEK_CUR) ;
if (psf_ftell (psf) != psf->datalength + psf->dataoffset)
psf_log_printf (psf, " *** psf_fseek past end error ***\n") ;
break ;
} ;
break ;
default :
if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
&& isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
{ psf_binheader_readf (psf, "4", &size32) ;
psf_log_printf (psf, "*** %M : %d (unknown marker)\n", marker, size32) ;
{ psf_log_printf (psf, "*** %M : %d (unknown marker)\n", marker, size32) ;
if (size32 < 8)
done = SF_TRUE ;
psf_binheader_readf (psf, "j", size32) ;
break ;
} ;
if (psf_ftell (psf) & 0x03)
{ psf_log_printf (psf, " Unknown chunk marker at position %d. Resynching.\n", size32 - 4) ;
{ psf_log_printf (psf, " Unknown chunk marker at position 0x%x. Resynching.\n", size32 - 4) ;
psf_binheader_readf (psf, "j", -3) ;
break ;
} ;
psf_log_printf (psf, "*** Unknown chunk marker (%X) at position %D. Exiting parser.\n", marker, psf_ftell (psf) - 4) ;
psf_log_printf (psf, "*** Unknown chunk marker (0x%X) at position 0x%X. Exiting parser.\n", marker, psf_ftell (psf) - 4) ;
done = SF_TRUE ;
break ;
} ; /* switch (marker) */
@@ -204,6 +311,99 @@ rf64_read_header (SF_PRIVATE *psf)
} ;
} ;
if (psf->dataoffset <= 0)
return SFE_WAV_NO_DATA ;
/* WAVs can be little or big endian */
psf->endian = psf->rwf_endian ;
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
if (psf->is_pipe == 0)
{ /*
** Check for 'wvpk' at the start of the DATA section. Not able to
** handle this.
*/
psf_binheader_readf (psf, "4", &marker) ;
if (marker == wvpk_MARKER || marker == OggS_MARKER)
return SFE_WAV_WVPK_DATA ;
} ;
/* Seek to start of DATA section. */
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
if (psf->blockwidth)
{ if (psf->filelength - psf->dataoffset < psf->datalength)
psf->sf.frames = (psf->filelength - psf->dataoffset) / psf->blockwidth ;
else
psf->sf.frames = psf->datalength / psf->blockwidth ;
} ;
if (frame_count != psf->sf.frames)
psf_log_printf (psf, "*** Calculated frame count %d does not match value from 'ds64' chunk of %d.\n", psf->sf.frames, frame_count) ;
switch (format)
{
case WAVE_FORMAT_EXTENSIBLE :
/* with WAVE_FORMAT_EXTENSIBLE the psf->sf.format field is already set. We just have to set the major to rf64 */
psf->sf.format = (psf->sf.format & ~SF_FORMAT_TYPEMASK) | SF_FORMAT_RF64 ;
if (psf->sf.format == (SF_FORMAT_WAVEX | SF_FORMAT_MS_ADPCM))
{ *blockalign = wav_fmt->msadpcm.blockalign ;
*framesperblock = wav_fmt->msadpcm.samplesperblock ;
} ;
break ;
case WAVE_FORMAT_PCM :
psf->sf.format = SF_FORMAT_RF64 | u_bitwidth_to_subformat (psf->bytewidth * 8) ;
break ;
case WAVE_FORMAT_MULAW :
case IBM_FORMAT_MULAW :
psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_ULAW) ;
break ;
case WAVE_FORMAT_ALAW :
case IBM_FORMAT_ALAW :
psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_ALAW) ;
break ;
case WAVE_FORMAT_MS_ADPCM :
psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_MS_ADPCM) ;
*blockalign = wav_fmt->msadpcm.blockalign ;
*framesperblock = wav_fmt->msadpcm.samplesperblock ;
break ;
case WAVE_FORMAT_IMA_ADPCM :
psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_IMA_ADPCM) ;
*blockalign = wav_fmt->ima.blockalign ;
*framesperblock = wav_fmt->ima.samplesperblock ;
break ;
case WAVE_FORMAT_GSM610 :
psf->sf.format = (SF_FORMAT_RF64 | SF_FORMAT_GSM610) ;
break ;
case WAVE_FORMAT_IEEE_FLOAT :
psf->sf.format = SF_FORMAT_RF64 ;
psf->sf.format |= (psf->bytewidth == 8) ? SF_FORMAT_DOUBLE : SF_FORMAT_FLOAT ;
break ;
case WAVE_FORMAT_G721_ADPCM :
psf->sf.format = SF_FORMAT_RF64 | SF_FORMAT_G721_32 ;
break ;
default : return SFE_UNIMPLEMENTED ;
} ;
if (wpriv->fmt_is_broken)
wav_w64_analyze (psf) ;
/* Only set the format endian-ness if its non-standard big-endian. */
if (psf->endian == SF_ENDIAN_BIG)
psf->sf.format |= SF_ENDIAN_BIG ;
return 0 ;
} /* rf64_read_header */
@@ -242,9 +442,9 @@ static const EXT_SUBFORMAT MSGUID_SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT =
static int
wavex_write_fmt_chunk (SF_PRIVATE *psf)
rf64_write_fmt_chunk (SF_PRIVATE *psf)
{ WAV_PRIVATE *wpriv ;
int subformat, fmt_size, add_fact_chunk = 0 ;
int subformat, fmt_size ;
if ((wpriv = psf->container_data) == NULL)
return SFE_INTERNAL ;
@@ -281,6 +481,8 @@ wavex_write_fmt_chunk (SF_PRIVATE *psf)
*/
if (wpriv->wavex_ambisonic != SF_AMBISONIC_NONE)
psf_binheader_writef (psf, "4", 0) ;
else if (wpriv->wavex_channelmask != 0)
psf_binheader_writef (psf, "4", wpriv->wavex_channelmask) ;
else
{ /*
** Ok some liberty is taken here to use the most commonly used channel masks
@@ -345,22 +547,11 @@ wavex_write_fmt_chunk (SF_PRIVATE *psf)
wavex_write_guid (psf, &MSGUID_SUBTYPE_ALAW) ;
break ;
#if 0
/* This is dead code due to return in previous switch statement. */
case SF_FORMAT_MS_ADPCM : /* todo, GUID exists */
wavex_write_guid (psf, &MSGUID_SUBTYPE_MS_ADPCM) ;
break ;
return SFE_UNIMPLEMENTED ;
#endif
default : return SFE_UNIMPLEMENTED ;
} ;
if (add_fact_chunk)
psf_binheader_writef (psf, "tm48", fact_MARKER, 4, psf->sf.frames) ;
return 0 ;
} /* wavex_write_fmt_chunk */
} /* rf64_write_fmt_chunk */
static int
@@ -375,7 +566,6 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
if (calc_length)
{ psf->filelength = psf_get_filelen (psf) ;
psf->datalength = psf->filelength - psf->dataoffset ;
if (psf->dataend)
@@ -392,7 +582,8 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
psf_binheader_writef (psf, "em4m", RF64_MARKER, 0xffffffff, WAVE_MARKER) ;
psf_binheader_writef (psf, "m488844", ds64_MARKER, 32, psf->filelength, psf->datalength, psf->sf.frames, 0, 0x005c0064) ;
/* Currently no table. */
psf_binheader_writef (psf, "m48884", ds64_MARKER, 28, psf->filelength - 8, psf->datalength, psf->sf.frames, 0) ;
/* WAVE and 'fmt ' markers. */
psf_binheader_writef (psf, "m", fmt_MARKER) ;
@@ -406,7 +597,7 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
case SF_FORMAT_WAVEX :
case SF_FORMAT_RF64 :
if ((error = wavex_write_fmt_chunk (psf)) != 0)
if ((error = rf64_write_fmt_chunk (psf)) != 0)
return error ;
break ;
@@ -414,9 +605,14 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
return SFE_UNIMPLEMENTED ;
} ;
if (psf->broadcast_16k != NULL)
wav_write_bext_chunk (psf) ;
if (psf->cart_16k != NULL)
wav_write_cart_chunk (psf) ;
#if 0
/* The LIST/INFO chunk. */
if (psf->str_flags & SF_STR_LOCATE_START)
if (psf->strings.flags & SF_STR_LOCATE_START)
wav_write_strings (psf, SF_STR_LOCATE_START) ;
if (psf->peak_info != NULL && psf->peak_info->peak_loc == SF_PEAK_START)
@@ -426,8 +622,8 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
psf_binheader_writef (psf, "ft8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
} ;
if (psf->broadcast_info != NULL)
wav_write_bext_chunk (psf) ;
// if (psf->broadcast_info != NULL)
// wav_write_bext_chunk (psf) ;
if (psf->instrument != NULL)
{ int tmp ;
@@ -446,7 +642,7 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
{ int type ;
type = psf->instrument->loops [tmp].mode ;
type = (type == SF_LOOP_FORWARD ? 0 : type==SF_LOOP_BACKWARD ? 2 : type == SF_LOOP_ALTERNATING ? 1 : 32) ;
type = (type == SF_LOOP_FORWARD ? 0 : type == SF_LOOP_BACKWARD ? 2 : type == SF_LOOP_ALTERNATING ? 1 : 32) ;
psf_binheader_writef (psf, "44", tmp, type) ;
psf_binheader_writef (psf, "44", psf->instrument->loops [tmp].start, psf->instrument->loops [tmp].end) ;
@@ -475,7 +671,7 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
psf->dataoffset = psf->headindex ;
if (! has_data)
if (NOT (has_data))
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
else if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
@@ -486,7 +682,7 @@ rf64_write_header (SF_PRIVATE *psf, int calc_length)
static int
rf64_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ // rf64_write_tailer (psf) ;
psf->write_header (psf, SF_TRUE) ;
@@ -494,3 +690,37 @@ rf64_close (SF_PRIVATE *psf)
return 0 ;
} /* rf64_close */
static int
rf64_command (SF_PRIVATE *psf, int command, void * UNUSED (data), int datasize)
{ WAV_PRIVATE *wpriv ;
if ((wpriv = psf->container_data) == NULL)
return SFE_INTERNAL ;
switch (command)
{ case SFC_WAVEX_SET_AMBISONIC :
if ((SF_CONTAINER (psf->sf.format)) == SF_FORMAT_WAVEX)
{ if (datasize == SF_AMBISONIC_NONE)
wpriv->wavex_ambisonic = SF_AMBISONIC_NONE ;
else if (datasize == SF_AMBISONIC_B_FORMAT)
wpriv->wavex_ambisonic = SF_AMBISONIC_B_FORMAT ;
else
return 0 ;
} ;
return wpriv->wavex_ambisonic ;
case SFC_WAVEX_GET_AMBISONIC :
return wpriv->wavex_ambisonic ;
case SFC_SET_CHANNEL_MAP_INFO :
wpriv->wavex_channelmask = wavex_gen_channel_mask (psf->channel_map, psf->sf.channels) ;
return (wpriv->wavex_channelmask != 0) ;
default :
break ;
} ;
return 0 ;
} /* rf64_command */
+9 -10
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2001-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -80,10 +80,9 @@ rx2_open (SF_PRIVATE *psf)
"Additional/PencilTool", "Disabled"
} ;
BUF_UNION ubuf ;
int error, marker, length, glob_offset, slce_count, frames ;
int sdat_length = 0, slce_total = 0 ;
int n_channels ;
@@ -119,14 +118,14 @@ rx2_open (SF_PRIVATE *psf)
/* Get name length */
length = 0 ;
psf_binheader_readf (psf, "1", &length) ;
if (length >= SIGNED_SIZEOF (psf->u.cbuf))
if (length >= SIGNED_SIZEOF (ubuf.cbuf))
{ psf_log_printf (psf, " Text : %d *** Error : Too sf_count_t!\n") ;
return -1001 ;
}
memset (psf->u.cbuf, 0, sizeof (psf->u.cbuf)) ;
psf_binheader_readf (psf, "b", psf->u.cbuf, length) ;
psf_log_printf (psf, " Text : \"%s\"\n", psf->u.cbuf) ;
memset (ubuf.cbuf, 0, sizeof (ubuf.cbuf)) ;
psf_binheader_readf (psf, "b", ubuf.cbuf, length) ;
psf_log_printf (psf, " Text : \"%s\"\n", ubuf.cbuf) ;
/* Jump to GLOB offset position. */
if (glob_offset & 1)
@@ -253,7 +252,7 @@ rx2_open (SF_PRIVATE *psf)
break ;
} ;
puts (psf->logbuffer) ;
puts (psf->parselog.buf) ;
puts ("-----------------------------------") ;
printf ("SDAT length : %d\n", sdat_length) ;
@@ -270,7 +269,7 @@ rx2_open (SF_PRIVATE *psf)
puts (" ") ;
psf->logbuffer [0] = 0 ;
psf->parselog.buf [0] = 0 ;
/* OK, have the header although not too sure what it all means. */
@@ -306,7 +305,7 @@ rx2_open (SF_PRIVATE *psf)
static int
rx2_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ /* Now we know for certain the length of the file we can re-write
** correct values for the FORM, 8SVX and BODY chunks.
*/
+70 -47
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2001-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2004 Paavo Jumppanen
**
** This program is free software; you can redistribute it and/or modify
@@ -104,12 +104,12 @@ sd2_open (SF_PRIVATE *psf)
/* SD2 is always big endian. */
psf->endian = SF_ENDIAN_BIG ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->rsrclength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->rsrclength > 0))
{ psf_use_rsrc (psf, SF_TRUE) ;
valid = psf_file_valid (psf) ;
psf_use_rsrc (psf, SF_FALSE) ;
if (! valid)
{ psf_log_printf (psf, "sd2_open : psf->rsrcdes < 0\n") ;
{ psf_log_printf (psf, "sd2_open : psf->rsrc.filedes < 0\n") ;
return SFE_SD2_BAD_RSRC ;
} ;
@@ -128,8 +128,9 @@ sd2_open (SF_PRIVATE *psf)
psf->dataoffset = 0 ;
/* Only open and write the resource in RDWR mode is its current length is zero. */
if (psf->mode == SFM_WRITE || (psf->mode == SFM_RDWR && psf->rsrclength == 0))
{ psf_open_rsrc (psf, psf->mode) ;
if (psf->file.mode == SFM_WRITE || (psf->file.mode == SFM_RDWR && psf->rsrclength == 0))
{ psf->rsrc.mode = psf->file.mode ;
psf_open_rsrc (psf) ;
error = sd2_write_rsrc_fork (psf, SF_FALSE) ;
@@ -148,6 +149,7 @@ sd2_open (SF_PRIVATE *psf)
{ case SF_FORMAT_PCM_S8 : /* 8-bit linear PCM. */
case SF_FORMAT_PCM_16 : /* 16-bit linear PCM. */
case SF_FORMAT_PCM_24 : /* 24-bit linear PCM */
case SF_FORMAT_PCM_32 : /* 32-bit linear PCM */
error = pcm_init (psf) ;
break ;
@@ -172,7 +174,7 @@ error_cleanup:
static int
sd2_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE)
if (psf->file.mode == SFM_WRITE)
{ /* Now we know for certain the audio_length of the file we can re-write
** correct values for the FORM, 8SVX and BODY chunks.
*/
@@ -222,7 +224,7 @@ write_marker (unsigned char * data, int offset, int value)
} /* write_marker */
static void
write_str (unsigned char * data, int offset, char * buffer, int buffer_len)
write_str (unsigned char * data, int offset, const char * buffer, int buffer_len)
{ memcpy (data + offset, buffer, buffer_len) ;
} /* write_str */
@@ -281,8 +283,8 @@ sd2_write_rsrc_fork (SF_PRIVATE *psf, int UNUSED (calc_length))
write_int (rsrc.rsrc_data, 4, rsrc.map_offset) ;
write_int (rsrc.rsrc_data, 8, rsrc.data_length) ;
write_char (rsrc.rsrc_data, 0x30, strlen (psf->filename)) ;
write_str (rsrc.rsrc_data, 0x31, psf->filename, strlen (psf->filename)) ;
write_char (rsrc.rsrc_data, 0x30, strlen (psf->file.name.c)) ;
write_str (rsrc.rsrc_data, 0x31, psf->file.name.c, strlen (psf->file.name.c)) ;
write_short (rsrc.rsrc_data, 0x50, 0) ;
write_marker (rsrc.rsrc_data, 0x52, Sd2f_MARKER) ;
@@ -369,44 +371,61 @@ sd2_write_rsrc_fork (SF_PRIVATE *psf, int UNUSED (calc_length))
*/
static inline int
read_char (const unsigned char * data, int offset)
{ return data [offset] ;
} /* read_char */
read_rsrc_char (const SD2_RSRC *prsrc, int offset)
{ const unsigned char * data = prsrc->rsrc_data ;
if (offset < 0 || offset >= prsrc->rsrc_len)
return 0 ;
return data [offset] ;
} /* read_rsrc_char */
static inline int
read_short (const unsigned char * data, int offset)
{ return (data [offset] << 8) + data [offset + 1] ;
} /* read_short */
read_rsrc_short (const SD2_RSRC *prsrc, int offset)
{ const unsigned char * data = prsrc->rsrc_data ;
if (offset < 0 || offset + 1 >= prsrc->rsrc_len)
return 0 ;
return (data [offset] << 8) + data [offset + 1] ;
} /* read_rsrc_short */
static inline int
read_int (const unsigned char * data, int offset)
{ return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
} /* read_int */
read_rsrc_int (const SD2_RSRC *prsrc, int offset)
{ const unsigned char * data = prsrc->rsrc_data ;
if (offset < 0 || offset + 3 >= prsrc->rsrc_len)
return 0 ;
return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
} /* read_rsrc_int */
static inline int
read_marker (const unsigned char * data, int offset)
{
read_rsrc_marker (const SD2_RSRC *prsrc, int offset)
{ const unsigned char * data = prsrc->rsrc_data ;
if (offset < 0 || offset + 3 >= prsrc->rsrc_len)
return 0 ;
if (CPU_IS_BIG_ENDIAN)
return (data [offset] << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
else if (CPU_IS_LITTLE_ENDIAN)
if (CPU_IS_LITTLE_ENDIAN)
return data [offset] + (data [offset + 1] << 8) + (data [offset + 2] << 16) + (data [offset + 3] << 24) ;
else
return 0x666 ;
} /* read_marker */
return 0 ;
} /* read_rsrc_marker */
static void
read_str (const unsigned char * data, int offset, char * buffer, int buffer_len)
{ int k ;
read_rsrc_str (const SD2_RSRC *prsrc, int offset, char * buffer, int buffer_len)
{ const unsigned char * data = prsrc->rsrc_data ;
int k ;
memset (buffer, 0, buffer_len) ;
if (offset < 0 || offset + buffer_len >= prsrc->rsrc_len)
return ;
for (k = 0 ; k < buffer_len - 1 ; k++)
{ if (isprint (data [offset + k]) == 0)
{ if (psf_isprint (data [offset + k]) == 0)
return ;
buffer [k] = data [offset + k] ;
} ;
return ;
} /* read_str */
} /* read_rsrc_str */
static int
sd2_parse_rsrc_fork (SF_PRIVATE *psf)
@@ -433,17 +452,17 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf)
/* Reset the header storage because we have changed to the rsrcdes. */
psf->headindex = psf->headend = rsrc.rsrc_len ;
rsrc.data_offset = read_int (rsrc.rsrc_data, 0) ;
rsrc.map_offset = read_int (rsrc.rsrc_data, 4) ;
rsrc.data_length = read_int (rsrc.rsrc_data, 8) ;
rsrc.map_length = read_int (rsrc.rsrc_data, 12) ;
rsrc.data_offset = read_rsrc_int (&rsrc, 0) ;
rsrc.map_offset = read_rsrc_int (&rsrc, 4) ;
rsrc.data_length = read_rsrc_int (&rsrc, 8) ;
rsrc.map_length = read_rsrc_int (&rsrc, 12) ;
if (rsrc.data_offset == 0x51607 && rsrc.map_offset == 0x20000)
{ psf_log_printf (psf, "Trying offset of 0x52 bytes.\n") ;
rsrc.data_offset = read_int (rsrc.rsrc_data, 0x52 + 0) + 0x52 ;
rsrc.map_offset = read_int (rsrc.rsrc_data, 0x52 + 4) + 0x52 ;
rsrc.data_length = read_int (rsrc.rsrc_data, 0x52 + 8) ;
rsrc.map_length = read_int (rsrc.rsrc_data, 0x52 + 12) ;
rsrc.data_offset = read_rsrc_int (&rsrc, 0x52 + 0) + 0x52 ;
rsrc.map_offset = read_rsrc_int (&rsrc, 0x52 + 4) + 0x52 ;
rsrc.data_length = read_rsrc_int (&rsrc, 0x52 + 8) ;
rsrc.map_length = read_rsrc_int (&rsrc, 0x52 + 12) ;
} ;
psf_log_printf (psf, " data offset : 0x%04X\n map offset : 0x%04X\n"
@@ -486,7 +505,7 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf)
goto parse_rsrc_fork_cleanup ;
} ;
rsrc.string_offset = rsrc.map_offset + read_short (rsrc.rsrc_data, rsrc.map_offset + 26) ;
rsrc.string_offset = rsrc.map_offset + read_rsrc_short (&rsrc, rsrc.map_offset + 26) ;
if (rsrc.string_offset > rsrc.rsrc_len)
{ psf_log_printf (psf, "Bad string offset (%d).\n", rsrc.string_offset) ;
error = SFE_SD2_BAD_RSRC ;
@@ -495,7 +514,7 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf)
rsrc.type_offset = rsrc.map_offset + 30 ;
rsrc.type_count = read_short (rsrc.rsrc_data, rsrc.map_offset + 28) + 1 ;
rsrc.type_count = read_rsrc_short (&rsrc, rsrc.map_offset + 28) + 1 ;
if (rsrc.type_count < 1)
{ psf_log_printf (psf, "Bad type count.\n") ;
error = SFE_SD2_BAD_RSRC ;
@@ -511,11 +530,11 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf)
rsrc.str_index = -1 ;
for (k = 0 ; k < rsrc.type_count ; k ++)
{ marker = read_marker (rsrc.rsrc_data, rsrc.type_offset + k * 8) ;
{ marker = read_rsrc_marker (&rsrc, rsrc.type_offset + k * 8) ;
if (marker == STR_MARKER)
{ rsrc.str_index = k ;
rsrc.str_count = read_short (rsrc.rsrc_data, rsrc.type_offset + k * 8 + 4) + 1 ;
rsrc.str_count = read_rsrc_short (&rsrc, rsrc.type_offset + k * 8 + 4) + 1 ;
error = parse_str_rsrc (psf, &rsrc) ;
goto parse_rsrc_fork_cleanup ;
} ;
@@ -547,26 +566,26 @@ parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc)
for (k = 0 ; data_offset + data_len < rsrc->rsrc_len ; k++)
{ int slen ;
slen = read_char (rsrc->rsrc_data, str_offset) ;
read_str (rsrc->rsrc_data, str_offset + 1, name, SF_MIN (SIGNED_SIZEOF (name), slen + 1)) ;
slen = read_rsrc_char (rsrc, str_offset) ;
read_rsrc_str (rsrc, str_offset + 1, name, SF_MIN (SIGNED_SIZEOF (name), slen + 1)) ;
str_offset += slen + 1 ;
rsrc_id = read_short (rsrc->rsrc_data, rsrc->item_offset + k * 12) ;
rsrc_id = read_rsrc_short (rsrc, rsrc->item_offset + k * 12) ;
data_offset = rsrc->data_offset + read_int (rsrc->rsrc_data, rsrc->item_offset + k * 12 + 4) ;
data_offset = rsrc->data_offset + read_rsrc_int (rsrc, rsrc->item_offset + k * 12 + 4) ;
if (data_offset < 0 || data_offset > rsrc->rsrc_len)
{ psf_log_printf (psf, "Exiting parser on data offset of %d.\n", data_offset) ;
break ;
} ;
data_len = read_int (rsrc->rsrc_data, data_offset) ;
data_len = read_rsrc_int (rsrc, data_offset) ;
if (data_len < 0 || data_len > rsrc->rsrc_len)
{ psf_log_printf (psf, "Exiting parser on data length of %d.\n", data_len) ;
break ;
} ;
slen = read_char (rsrc->rsrc_data, data_offset + 4) ;
read_str (rsrc->rsrc_data, data_offset + 5, value, SF_MIN (SIGNED_SIZEOF (value), slen + 1)) ;
slen = read_rsrc_char (rsrc, data_offset + 4) ;
read_rsrc_str (rsrc, data_offset + 5, value, SF_MIN (SIGNED_SIZEOF (value), slen + 1)) ;
psf_log_printf (psf, " 0x%04x %4d %4d %3d '%s'\n", data_offset, rsrc_id, data_len, slen, value) ;
@@ -619,6 +638,10 @@ parse_str_rsrc (SF_PRIVATE *psf, SD2_RSRC * rsrc)
psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_24 ;
break ;
case 4 :
psf->sf.format = SF_FORMAT_SD2 | SF_FORMAT_PCM_32 ;
break ;
default :
psf_log_printf (psf, "Bad sample size (%d)\n", rsrc->sample_size) ;
return SFE_SD2_BAD_SAMPLE_SIZE ;
+91 -55
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -56,6 +56,7 @@ typedef struct tag_SDS_PRIVATE
int read_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */
int write_block, write_count ;
int total_written ;
unsigned char write_data [SDS_BLOCK_SIZE] ;
int write_samples [SDS_BLOCK_SIZE / 2] ; /* Maximum samples per block */
} SDS_PRIVATE ;
@@ -82,6 +83,7 @@ static sf_count_t sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len
static sf_count_t sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len) ;
static sf_count_t sds_seek (SF_PRIVATE *psf, int mode, sf_count_t offset) ;
static int sds_byterate (SF_PRIVATE * psf) ;
static int sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
static int sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds) ;
@@ -111,7 +113,7 @@ sds_open (SF_PRIVATE *psf)
return SFE_MALLOC_FAILED ;
psf->codec_data = psds ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = sds_read_header (psf, psds)))
return error ;
} ;
@@ -119,7 +121,7 @@ sds_open (SF_PRIVATE *psf)
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_SDS)
return SFE_BAD_OPEN_FORMAT ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (sds_write_header (psf, SF_FALSE))
return psf->error ;
@@ -131,8 +133,9 @@ sds_open (SF_PRIVATE *psf)
if ((error = sds_init (psf, psds)) != 0)
return error ;
psf->seek = sds_seek ;
psf->container_close = sds_close ;
psf->seek = sds_seek ;
psf->byterate = sds_byterate ;
psf->blockwidth = 0 ;
@@ -145,7 +148,7 @@ sds_open (SF_PRIVATE *psf)
static int
sds_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ SDS_PRIVATE *psds ;
if ((psds = (SDS_PRIVATE *) psf->codec_data) == NULL)
@@ -186,7 +189,7 @@ sds_init (SF_PRIVATE *psf, SDS_PRIVATE *psds)
psds->samplesperblock = SDS_AUDIO_BYTES_PER_BLOCK / 4 ;
} ;
if (psf->mode == SFM_READ || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_READ || psf->file.mode == SFM_RDWR)
{ psf->read_short = sds_read_s ;
psf->read_int = sds_read_i ;
psf->read_float = sds_read_f ;
@@ -196,7 +199,7 @@ sds_init (SF_PRIVATE *psf, SDS_PRIVATE *psds)
psds->reader (psf, psds) ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ psf->write_short = sds_write_s ;
psf->write_int = sds_write_i ;
psf->write_float = sds_write_f ;
@@ -219,26 +222,47 @@ sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds)
if (marker != 0xF07E || byte != 0x01)
return SFE_SDS_NOT_SDS ;
psf_log_printf (psf, "Midi Sample Dump Standard (.sds)\nF07E\n Midi Channel : %d\n", channel) ;
bytesread += psf_binheader_readf (psf, "e213", &sample_no, &bitwidth, &samp_period) ;
bytesread += psf_binheader_readf (psf, "e2", &sample_no) ;
sample_no = SDS_3BYTE_TO_INT_DECODE (sample_no) ;
psf_log_printf (psf, "Midi Sample Dump Standard (.sds)\nF07E\n"
" Midi Channel : %d\n Sample Number : %d\n",
channel, sample_no) ;
bytesread += psf_binheader_readf (psf, "e13", &bitwidth, &samp_period) ;
samp_period = SDS_3BYTE_TO_INT_DECODE (samp_period) ;
psds->bitwidth = bitwidth ;
psf->sf.samplerate = 1000000000 / samp_period ;
if (psds->bitwidth > 1)
psf_log_printf (psf, " Bit Width : %d\n", psds->bitwidth) ;
else
{ psf_log_printf (psf, " Bit Width : %d (should be > 1)\n", psds->bitwidth) ;
return SFE_SDS_BAD_BIT_WIDTH ;
} ;
psf_log_printf (psf, " Sample Number : %d\n"
" Bit Width : %d\n"
if (samp_period > 0)
{ psf->sf.samplerate = 1000000000 / samp_period ;
psf_log_printf (psf, " Sample Period : %d\n"
" Sample Rate : %d\n",
sample_no, psds->bitwidth, psf->sf.samplerate) ;
samp_period, psf->sf.samplerate) ;
}
else
{ psf->sf.samplerate = 16000 ;
psf_log_printf (psf, " Sample Period : %d (should be > 0)\n"
" Sample Rate : %d (guessed)\n",
samp_period, psf->sf.samplerate) ;
} ;
bytesread += psf_binheader_readf (psf, "e3331", &data_length, &sustain_loop_start, &sustain_loop_end, &loop_type) ;
data_length = SDS_3BYTE_TO_INT_DECODE (data_length) ;
psf->sf.frames = psds->frames = data_length ;
sustain_loop_start = SDS_3BYTE_TO_INT_DECODE (sustain_loop_start) ;
sustain_loop_end = SDS_3BYTE_TO_INT_DECODE (sustain_loop_end) ;
@@ -251,13 +275,6 @@ sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds)
psf->dataoffset = SDS_DATA_OFFSET ;
psf->datalength = psf->filelength - psf->dataoffset ;
if (data_length != psf->filelength - psf->dataoffset)
{ psf_log_printf (psf, " Datalength : %d (truncated data??? %d)\n", data_length, psf->filelength - psf->dataoffset) ;
data_length = psf->filelength - psf->dataoffset ;
}
else
psf_log_printf (psf, " Datalength : %d\n", data_length) ;
bytesread += psf_binheader_readf (psf, "1", &byte) ;
if (byte != 0xF7)
psf_log_printf (psf, "bad end : %X\n", byte & 0xFF) ;
@@ -281,9 +298,6 @@ sds_read_header (SF_PRIVATE *psf, SDS_PRIVATE *psds)
psf_log_printf (psf, "Frames : %d\n", blockcount * psds->samplesperblock) ;
psf->sf.frames = blockcount * psds->samplesperblock ;
psds->frames = blockcount * psds->samplesperblock ;
/* Always Mono */
psf->sf.channels = 1 ;
psf->sf.sections = 1 ;
@@ -337,7 +351,7 @@ sds_write_header (SF_PRIVATE *psf, int calc_length)
current = psf_ftell (psf) ;
if (calc_length)
psf->sf.frames = psds->total_blocks * psds->samplesperblock + psds->write_count ;
psf->sf.frames = psds->total_written ;
if (psds->write_count > 0)
{ int current_count = psds->write_count ;
@@ -378,9 +392,9 @@ sds_write_header (SF_PRIVATE *psf, int calc_length)
psf_binheader_writef (psf, "e213", 0, psds->bitwidth, samp_period) ;
data_length = SDS_INT_TO_3BYTE_ENCODE (psds->total_blocks * SDS_BLOCK_SIZE) ;
data_length = SDS_INT_TO_3BYTE_ENCODE (psds->total_written) ;
sustain_loop_start = SDS_INT_TO_3BYTE_ENCODE (0) ;
sustain_loop_end = SDS_INT_TO_3BYTE_ENCODE (psf->sf.frames) ;
sustain_loop_end = SDS_INT_TO_3BYTE_ENCODE (0) ;
psf_binheader_writef (psf, "e33311", data_length, sustain_loop_start, sustain_loop_end, loop_type, 0xF7) ;
@@ -429,7 +443,7 @@ sds_2byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
{ printf ("Error 1 : %02X\n", checksum & 0xFF) ;
}
for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->read_data [k] ;
checksum &= 0x7F ;
@@ -473,7 +487,7 @@ sds_3byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
{ printf ("Error 1 : %02X\n", checksum & 0xFF) ;
}
for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->read_data [k] ;
checksum &= 0x7F ;
@@ -517,7 +531,7 @@ sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
{ printf ("Error 1 : %02X\n", checksum & 0xFF) ;
}
for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->read_data [k] ;
checksum &= 0x7F ;
@@ -538,7 +552,8 @@ sds_4byte_read (SF_PRIVATE *psf, SDS_PRIVATE *psds)
static sf_count_t
sds_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
{ SDS_PRIVATE *psds ;
{ BUF_UNION ubuf ;
SDS_PRIVATE *psds ;
int *iptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
@@ -547,8 +562,8 @@ sds_read_s (SF_PRIVATE *psf, short *ptr, sf_count_t len)
return 0 ;
psds = (SDS_PRIVATE*) psf->codec_data ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = sds_read (psf, psds, iptr, readcount) ;
@@ -577,7 +592,8 @@ sds_read_i (SF_PRIVATE *psf, int *ptr, sf_count_t len)
static sf_count_t
sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
{ SDS_PRIVATE *psds ;
{ BUF_UNION ubuf ;
SDS_PRIVATE *psds ;
int *iptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
@@ -592,8 +608,8 @@ sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
else
normfact = 1.0 / (1 << psds->bitwidth) ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = sds_read (psf, psds, iptr, readcount) ;
@@ -608,7 +624,8 @@ sds_read_f (SF_PRIVATE *psf, float *ptr, sf_count_t len)
static sf_count_t
sds_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
{ SDS_PRIVATE *psds ;
{ BUF_UNION ubuf ;
SDS_PRIVATE *psds ;
int *iptr ;
int k, bufferlen, readcount, count ;
sf_count_t total = 0 ;
@@ -623,8 +640,8 @@ sds_read_d (SF_PRIVATE *psf, double *ptr, sf_count_t len)
else
normfact = 1.0 / (1 << psds->bitwidth) ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ readcount = (len >= bufferlen) ? bufferlen : len ;
count = sds_read (psf, psds, iptr, readcount) ;
@@ -737,6 +754,15 @@ sds_seek (SF_PRIVATE *psf, int mode, sf_count_t seek_from_start)
return seek_from_start ;
} /* sds_seek */
static int
sds_byterate (SF_PRIVATE * psf)
{
if (psf->file.mode == SFM_READ)
return (psf->datalength * psf->sf.samplerate) / psf->sf.frames ;
return -1 ;
} /* sds_byterate */
/*==============================================================================
*/
@@ -749,7 +775,8 @@ sds_2byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
psds->write_data [0] = 0xF0 ;
psds->write_data [1] = 0x7E ;
psds->write_data [2] = 0 ; /* Channel number */
psds->write_data [3] = psds->write_block & 0x7F ; /* Packet number */
psds->write_data [3] = 2 ;
psds->write_data [4] = psds->write_block & 0x7F ; /* Packet number */
ucptr = psds->write_data + 5 ;
for (k = 0 ; k < 120 ; k += 2)
@@ -760,7 +787,7 @@ sds_2byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
} ;
checksum = psds->write_data [1] ;
for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->write_data [k] ;
checksum &= 0x7F ;
@@ -789,7 +816,8 @@ sds_3byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
psds->write_data [0] = 0xF0 ;
psds->write_data [1] = 0x7E ;
psds->write_data [2] = 0 ; /* Channel number */
psds->write_data [3] = psds->write_block & 0x7F ; /* Packet number */
psds->write_data [3] = 2 ;
psds->write_data [4] = psds->write_block & 0x7F ; /* Packet number */
ucptr = psds->write_data + 5 ;
for (k = 0 ; k < 120 ; k += 3)
@@ -801,7 +829,7 @@ sds_3byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
} ;
checksum = psds->write_data [1] ;
for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->write_data [k] ;
checksum &= 0x7F ;
@@ -830,7 +858,8 @@ sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
psds->write_data [0] = 0xF0 ;
psds->write_data [1] = 0x7E ;
psds->write_data [2] = 0 ; /* Channel number */
psds->write_data [3] = psds->write_block & 0x7F ; /* Packet number */
psds->write_data [3] = 2 ;
psds->write_data [4] = psds->write_block & 0x7F ; /* Packet number */
ucptr = psds->write_data + 5 ;
for (k = 0 ; k < 120 ; k += 4)
@@ -843,7 +872,7 @@ sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
} ;
checksum = psds->write_data [1] ;
for (k = 2 ; k < SDS_BLOCK_SIZE - 3 ; k ++)
for (k = 2 ; k <= SDS_BLOCK_SIZE - 3 ; k ++)
checksum ^= psds->write_data [k] ;
checksum &= 0x7F ;
@@ -865,7 +894,8 @@ sds_4byte_write (SF_PRIVATE *psf, SDS_PRIVATE *psds)
static sf_count_t
sds_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
{ SDS_PRIVATE *psds ;
{ BUF_UNION ubuf ;
SDS_PRIVATE *psds ;
int *iptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
@@ -873,9 +903,10 @@ sds_write_s (SF_PRIVATE *psf, const short *ptr, sf_count_t len)
if (psf->codec_data == NULL)
return 0 ;
psds = (SDS_PRIVATE*) psf->codec_data ;
psds->total_written += len ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -896,6 +927,7 @@ sds_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
if (psf->codec_data == NULL)
return 0 ;
psds = (SDS_PRIVATE*) psf->codec_data ;
psds->total_written += len ;
total = sds_write (psf, psds, ptr, len) ;
@@ -904,7 +936,8 @@ sds_write_i (SF_PRIVATE *psf, const int *ptr, sf_count_t len)
static sf_count_t
sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
{ SDS_PRIVATE *psds ;
{ BUF_UNION ubuf ;
SDS_PRIVATE *psds ;
int *iptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
@@ -913,14 +946,15 @@ sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
if (psf->codec_data == NULL)
return 0 ;
psds = (SDS_PRIVATE*) psf->codec_data ;
psds->total_written += len ;
if (psf->norm_float == SF_TRUE)
normfact = 1.0 * 0x80000000 ;
else
normfact = 1.0 * (1 << psds->bitwidth) ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
@@ -935,7 +969,8 @@ sds_write_f (SF_PRIVATE *psf, const float *ptr, sf_count_t len)
static sf_count_t
sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
{ SDS_PRIVATE *psds ;
{ BUF_UNION ubuf ;
SDS_PRIVATE *psds ;
int *iptr ;
int k, bufferlen, writecount, count ;
sf_count_t total = 0 ;
@@ -944,14 +979,15 @@ sds_write_d (SF_PRIVATE *psf, const double *ptr, sf_count_t len)
if (psf->codec_data == NULL)
return 0 ;
psds = (SDS_PRIVATE*) psf->codec_data ;
psds->total_written += len ;
if (psf->norm_double == SF_TRUE)
normfact = 1.0 * 0x80000000 ;
else
normfact = 1.0 * (1 << psds->bitwidth) ;
iptr = psf->u.ibuf ;
bufferlen = ARRAY_LEN (psf->u.ibuf) ;
iptr = ubuf.ibuf ;
bufferlen = ARRAY_LEN (ubuf.ibuf) ;
while (len > 0)
{ writecount = (len >= bufferlen) ? bufferlen : len ;
for (k = 0 ; k < writecount ; k++)
+11 -9
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -34,15 +34,17 @@
#define S_IXUSR 0000100 /* execute/search permission, owner */
#endif
#define S_IRWXG 0000070 /* rwx, group */
#define S_IRGRP 0000040 /* read permission, group */
#define S_IWGRP 0000020 /* write permission, grougroup */
#define S_IXGRP 0000010 /* execute/search permission, group */
/* Windows doesn't have group permissions so set all these to zero. */
#define S_IRWXG 0 /* rwx, group */
#define S_IRGRP 0 /* read permission, group */
#define S_IWGRP 0 /* write permission, grougroup */
#define S_IXGRP 0 /* execute/search permission, group */
#define S_IRWXO 0000007 /* rwx, other */
#define S_IROTH 0000004 /* read permission, other */
#define S_IWOTH 0000002 /* write permission, other */
#define S_IXOTH 0000001 /* execute/search permission, other */
/* Windows doesn't have others permissions so set all these to zero. */
#define S_IRWXO 0 /* rwx, other */
#define S_IROTH 0 /* read permission, other */
#define S_IWOTH 0 /* write permission, other */
#define S_IXOTH 0 /* execute/search permission, other */
#ifndef S_ISFIFO
#define S_ISFIFO(mode) (((mode) & _S_IFMT) == _S_IFIFO)
+23 -9
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2005-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2005-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -53,6 +53,10 @@
#define HAVE_ENDIAN_H 0
#endif
#ifndef HAVE_FSTAT64
#define HAVE_FSTAT64 0
#endif
#ifndef HAVE_FSYNC
#define HAVE_FSYNC 0
#endif
@@ -73,14 +77,6 @@
#define HAVE_MMAP 0
#endif
#ifndef HAVE_PREAD
#define HAVE_PREAD 0
#endif
#ifndef HAVE_PWRITE
#define HAVE_PWRITE 0
#endif
#ifndef HAVE_SETLOCALE
#define HAVE_SETLOCALE 0
#endif
@@ -93,9 +89,27 @@
#define HAVE_STDINT_H 0
#endif
#ifndef HAVE_SYS_WAIT_H
#define HAVE_SYS_WAIT_H 0
#endif
#ifndef HAVE_UNISTD_H
#define HAVE_UNISTD_H 0
#endif
#ifndef HAVE_PIPE
#define HAVE_PIPE 0
#endif
#ifndef HAVE_WAITPID
#define HAVE_WAITPID 0
#endif
#ifndef HAVE_X86INTRIN_H
#define HAVE_X86INTRIN_H 0
#endif
#define CPU_IS_X86 (defined __i486__ || defined __i586__ || defined __i686__ || defined __x86_64__)
#define CPU_IS_X86_64 (defined __x86_64__)
#endif
+147 -105
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -21,38 +21,72 @@
#include "sfconfig.h"
#if HAVE_STDINT_H
#include <stdint.h>
#elif HAVE_INTTYPES_H
#ifndef WIN32
#include <inttypes.h>
#endif
#if (defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
/* Good, we have int64_t. */
#elif (defined (SIZEOF_LONG_LONG) && (SIZEOF_LONG_LONG == 8))
typedef long long int64_t ;
#elif (defined (SIZEOF_LONG) && (SIZEOF_LONG == 8))
typedef long int64_t ;
#elif (defined (WIN32) || defined (_WIN32))
typedef __int64 int64_t ;
#else
#error "No 64 bit integer type."
#if COMPILER_IS_GCC && CPU_IS_X86
static inline int16_t
ENDSWAP_16 (int16_t x)
{ int16_t y ;
__asm__ ("rorw $8, %w0" : "=r" (y) : "0" (x) : "cc") ;
return y ;
} /* ENDSWAP_16 */
static inline int32_t
ENDSWAP_32 (int32_t x)
{ int32_t y ;
__asm__ ("bswap %0" : "=r" (y) : "0" (x)) ;
return y ;
} /* ENDSWAP_32 */
#if CPU_IS_X86_64
static inline int64_t
ENDSWAP_64X (int64_t x)
{ int64_t y ;
__asm__ ("bswap %q0" : "=r" (y) : "0" (x)) ;
return y ;
} /* ENDSWAP_64X */
#define ENDSWAP_64 ENDSWAP_64X
#endif
#if HAVE_BYTESWAP_H
#elif HAVE_BYTESWAP_H /* Linux, any CPU */
#include <byteswap.h>
#define ENDSWAP_SHORT(x) ((short) bswap_16 (x))
#define ENDSWAP_INT(x) ((int) bswap_32 (x))
#define ENDSWAP_16(x) (bswap_16 (x))
#define ENDSWAP_32(x) (bswap_32 (x))
#define ENDSWAP_64(x) (bswap_64 (x))
#else
#define ENDSWAP_SHORT(x) ((((x) >> 8) & 0xFF) + (((x) & 0xFF) << 8))
#define ENDSWAP_INT(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + (((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24))
#define ENDSWAP_16(x) ((((x) >> 8) & 0xFF) + (((x) & 0xFF) << 8))
#define ENDSWAP_32(x) ((((x) >> 24) & 0xFF) + (((x) >> 8) & 0xFF00) + (((x) & 0xFF00) << 8) + (((x) & 0xFF) << 24))
#endif
#ifndef ENDSWAP_64
static inline uint64_t
ENDSWAP_64 (uint64_t x)
{ union
{ uint32_t parts [2] ;
uint64_t whole ;
} u ;
uint32_t temp ;
u.whole = x ;
temp = u.parts [0] ;
u.parts [0] = ENDSWAP_32 (u.parts [1]) ;
u.parts [1] = ENDSWAP_32 (temp) ;
return u.whole ;
}
#endif
/*
** Many file types (ie WAV, AIFF) use sets of four consecutive bytes as a
** marker indicating different sections of the file.
@@ -61,9 +95,9 @@ typedef __int64 int64_t ;
*/
#if (CPU_IS_LITTLE_ENDIAN == 1)
#define MAKE_MARKER(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
#define MAKE_MARKER(a, b, c, d) ((uint32_t) ((a) | ((b) << 8) | ((c) << 16) | (((uint32_t) (d)) << 24)))
#elif (CPU_IS_BIG_ENDIAN == 1)
#define MAKE_MARKER(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
#define MAKE_MARKER(a, b, c, d) ((uint32_t) ((((uint32_t) (a)) << 24) | ((b) << 16) | ((c) << 8) | (d)))
#else
#error "Target CPU endian-ness unknown. May need to hand edit src/sfconfig.h"
#endif
@@ -76,34 +110,102 @@ typedef __int64 int64_t ;
*/
#if (CPU_IS_LITTLE_ENDIAN == 1)
#define LES2H_SHORT(x) (x)
#define LEI2H_INT(x) (x)
#define LE2H_16(x) (x)
#define LE2H_32(x) (x)
#define BES2H_SHORT(x) ENDSWAP_SHORT (x)
#define BEI2H_INT(x) ENDSWAP_INT (x)
#define BE2H_16(x) ENDSWAP_16 (x)
#define BE2H_32(x) ENDSWAP_32 (x)
#define BE2H_64(x) ENDSWAP_64 (x)
#define H2BE_SHORT(x) ENDSWAP_SHORT (x)
#define H2BE_INT(x) ENDSWAP_INT (x)
#define H2BE_16(x) ENDSWAP_16 (x)
#define H2BE_32(x) ENDSWAP_32 (x)
#elif (CPU_IS_BIG_ENDIAN == 1)
#define LES2H_SHORT(x) ENDSWAP_SHORT (x)
#define LEI2H_INT(x) ENDSWAP_INT (x)
#define LE2H_16(x) ENDSWAP_16 (x)
#define LE2H_32(x) ENDSWAP_32 (x)
#define BES2H_SHORT(x) (x)
#define BEI2H_INT(x) (x)
#define BE2H_16(x) (x)
#define BE2H_32(x) (x)
#define BE2H_64(x) (x)
#define H2LE_SHORT(x) ENDSWAP_SHORT (x)
#define H2LE_INT(x) ENDSWAP_INT (x)
#define H2BE_16(x) (x)
#define H2BE_32(x) (x)
#define H2LE_16(x) ENDSWAP_16 (x)
#define H2LE_32(x) ENDSWAP_32 (x)
#else
#error "Target CPU endian-ness unknown. May need to hand edit src/sfconfig.h"
#endif
#define LET2H_SHORT_PTR(x) ((x) [1] + ((x) [2] << 8))
#define LET2H_INT_PTR(x) (((x) [0] << 8) + ((x) [1] << 16) + ((x) [2] << 24))
#define LET2H_16_PTR(x) ((x) [1] + ((x) [2] << 8))
#define LET2H_32_PTR(x) (((x) [0] << 8) + ((x) [1] << 16) + ((x) [2] << 24))
#define BET2H_SHORT_PTR(x) (((x) [0] << 8) + (x) [1])
#define BET2H_INT_PTR(x) (((x) [0] << 24) + ((x) [1] << 16) + ((x) [2] << 8))
#define BET2H_16_PTR(x) (((x) [0] << 8) + (x) [1])
#define BET2H_32_PTR(x) (((x) [0] << 24) + ((x) [1] << 16) + ((x) [2] << 8))
static inline void
psf_put_be64 (uint8_t *ptr, int offset, int64_t value)
{
ptr [offset] = value >> 56 ;
ptr [offset + 1] = value >> 48 ;
ptr [offset + 2] = value >> 40 ;
ptr [offset + 3] = value >> 32 ;
ptr [offset + 4] = value >> 24 ;
ptr [offset + 5] = value >> 16 ;
ptr [offset + 6] = value >> 8 ;
ptr [offset + 7] = value ;
} /* psf_put_be64 */
static inline void
psf_put_be32 (uint8_t *ptr, int offset, int32_t value)
{
ptr [offset] = value >> 24 ;
ptr [offset + 1] = value >> 16 ;
ptr [offset + 2] = value >> 8 ;
ptr [offset + 3] = value ;
} /* psf_put_be32 */
static inline void
psf_put_be16 (uint8_t *ptr, int offset, int16_t value)
{
ptr [offset] = value >> 8 ;
ptr [offset + 1] = value ;
} /* psf_put_be16 */
static inline int64_t
psf_get_be64 (uint8_t *ptr, int offset)
{ int64_t value ;
value = ptr [offset] << 24 ;
value += ptr [offset + 1] << 16 ;
value += ptr [offset + 2] << 8 ;
value += ptr [offset + 3] ;
value <<= 32 ;
value += ptr [offset + 4] << 24 ;
value += ptr [offset + 5] << 16 ;
value += ptr [offset + 6] << 8 ;
value += ptr [offset + 7] ;
return value ;
} /* psf_get_be64 */
static inline int32_t
psf_get_be32 (uint8_t *ptr, int offset)
{ int32_t value ;
value = ptr [offset] << 24 ;
value += ptr [offset + 1] << 16 ;
value += ptr [offset + 2] << 8 ;
value += ptr [offset + 3] ;
return value ;
} /* psf_get_be32 */
static inline int16_t
psf_get_be16 (uint8_t *ptr, int offset)
{ return (ptr [offset] << 8) + ptr [offset + 1] ;
} /* psf_get_be16 */
/*-----------------------------------------------------------------------------------------------
** Generic functions for performing endian swapping on integer arrays.
@@ -115,7 +217,7 @@ endswap_short_array (short *ptr, int len)
while (--len >= 0)
{ temp = ptr [len] ;
ptr [len] = ENDSWAP_SHORT (temp) ;
ptr [len] = ENDSWAP_16 (temp) ;
} ;
} /* endswap_short_array */
@@ -123,7 +225,7 @@ static inline void
endswap_short_copy (short *dest, const short *src, int len)
{
while (--len >= 0)
{ dest [len] = ENDSWAP_SHORT (src [len]) ;
{ dest [len] = ENDSWAP_16 (src [len]) ;
} ;
} /* endswap_short_copy */
@@ -133,7 +235,7 @@ endswap_int_array (int *ptr, int len)
while (--len >= 0)
{ temp = ptr [len] ;
ptr [len] = ENDSWAP_INT (temp) ;
ptr [len] = ENDSWAP_32 (temp) ;
} ;
} /* endswap_int_array */
@@ -141,22 +243,20 @@ static inline void
endswap_int_copy (int *dest, const int *src, int len)
{
while (--len >= 0)
{ dest [len] = ENDSWAP_INT (src [len]) ;
{ dest [len] = ENDSWAP_32 (src [len]) ;
} ;
} /* endswap_int_copy */
/*========================================================================================
*/
#if (HAVE_BYTESWAP_H && defined (SIZEOF_INT64_T) && (SIZEOF_INT64_T == 8))
static inline void
endswap_int64_t_array (int64_t *ptr, int len)
{ int64_t value ;
while (--len >= 0)
{ value = ptr [len] ;
ptr [len] = bswap_64 (value) ;
ptr [len] = ENDSWAP_64 (value) ;
} ;
} /* endswap_int64_t_array */
@@ -166,78 +266,20 @@ endswap_int64_t_copy (int64_t *dest, const int64_t *src, int len)
while (--len >= 0)
{ value = src [len] ;
dest [len] = bswap_64 (value) ;
dest [len] = ENDSWAP_64 (value) ;
} ;
} /* endswap_int64_t_copy */
#else
static inline void
endswap_int64_t_array (int64_t *ptr, int len)
{ unsigned char *ucptr, temp ;
ucptr = (unsigned char *) ptr ;
ucptr += 8 * len ;
while (--len >= 0)
{ ucptr -= 8 ;
temp = ucptr [0] ;
ucptr [0] = ucptr [7] ;
ucptr [7] = temp ;
temp = ucptr [1] ;
ucptr [1] = ucptr [6] ;
ucptr [6] = temp ;
temp = ucptr [2] ;
ucptr [2] = ucptr [5] ;
ucptr [5] = temp ;
temp = ucptr [3] ;
ucptr [3] = ucptr [4] ;
ucptr [4] = temp ;
} ;
} /* endswap_int64_t_array */
static inline void
endswap_int64_t_copy (int64_t *dest, const int64_t *src, int len)
{ const unsigned char *psrc ;
unsigned char *pdest ;
if (dest == src)
{ endswap_int64_t_array (dest, len) ;
return ;
} ;
psrc = ((const unsigned char *) src) + 8 * len ;
pdest = ((unsigned char *) dest) + 8 * len ;
while (--len >= 0)
{ psrc -= 8 ;
pdest -= 8 ;
pdest [0] = psrc [7] ;
pdest [2] = psrc [5] ;
pdest [4] = psrc [3] ;
pdest [6] = psrc [1] ;
pdest [7] = psrc [0] ;
pdest [1] = psrc [6] ;
pdest [3] = psrc [4] ;
pdest [5] = psrc [2] ;
} ;
} /* endswap_int64_t_copy */
#endif
/* A couple of wrapper functions. */
static inline void
endswap_float_array (float *ptr, int len)
{ endswap_int_array ((void *) ptr, len) ;
{ endswap_int_array ((int *) ptr, len) ;
} /* endswap_float_array */
static inline void
endswap_double_array (double *ptr, int len)
{ endswap_int64_t_array ((void *) ptr, len) ;
{ endswap_int64_t_array ((int64_t *) ptr, len) ;
} /* endswap_double_array */
static inline void
File diff suppressed because it is too large. Load diff
+254 -47
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -30,6 +30,7 @@
#define SNDFILE_1
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#ifdef __cplusplus
@@ -105,6 +106,11 @@ enum
SF_FORMAT_VORBIS = 0x0060, /* Xiph Vorbis encoding. */
SF_FORMAT_ALAC_16 = 0x0070, /* Apple Lossless Audio Codec (16 bit). */
SF_FORMAT_ALAC_20 = 0x0071, /* Apple Lossless Audio Codec (20 bit). */
SF_FORMAT_ALAC_24 = 0x0072, /* Apple Lossless Audio Codec (24 bit). */
SF_FORMAT_ALAC_32 = 0x0073, /* Apple Lossless Audio Codec (32 bit). */
/* Endian-ness options. */
SF_ENDIAN_FILE = 0x00000000, /* Default file endian-ness. */
@@ -192,6 +198,11 @@ enum
SFC_WAVEX_GET_AMBISONIC = 0x1201,
SFC_SET_VBR_ENCODING_QUALITY = 0x1300,
SFC_SET_COMPRESSION_LEVEL = 0x1301,
/* Cart Chunk support */
SFC_SET_CART_INFO = 0x1400,
SFC_GET_CART_INFO = 0x1401,
/* Following commands for testing only. */
SFC_TEST_IEEE_FLOAT_REPLACE = 0x6001,
@@ -199,7 +210,7 @@ enum
/*
** SFC_SET_ADD_* values are deprecated and will disappear at some
** time in the future. They are guaranteed to be here up to and
** including version 1.0.8 to avoid breakage of existng software.
** including version 1.0.8 to avoid breakage of existing software.
** They currently do nothing and will continue to do nothing.
*/
SFC_SET_ADD_DITHER_ON_WRITE = 0x1070,
@@ -221,7 +232,9 @@ enum
SF_STR_COMMENT = 0x05,
SF_STR_DATE = 0x06,
SF_STR_ALBUM = 0x07,
SF_STR_LICENSE = 0x08
SF_STR_LICENSE = 0x08,
SF_STR_TRACKNUMBER = 0x09,
SF_STR_GENRE = 0x10
} ;
/*
@@ -230,7 +243,7 @@ enum
*/
#define SF_STR_FIRST SF_STR_TITLE
#define SF_STR_LAST SF_STR_LICENSE
#define SF_STR_LAST SF_STR_GENRE
enum
{ /* True and false */
@@ -267,27 +280,34 @@ enum
enum
{ SF_CHANNEL_MAP_INVALID = 0,
SF_CHANNEL_MAP_MONO = 1,
SF_CHANNEL_MAP_LEFT,
SF_CHANNEL_MAP_RIGHT,
SF_CHANNEL_MAP_CENTER,
SF_CHANNEL_MAP_LEFT, /* Apple calls this 'Left' */
SF_CHANNEL_MAP_RIGHT, /* Apple calls this 'Right' */
SF_CHANNEL_MAP_CENTER, /* Apple calls this 'Center' */
SF_CHANNEL_MAP_FRONT_LEFT,
SF_CHANNEL_MAP_FRONT_RIGHT,
SF_CHANNEL_MAP_FRONT_CENTER,
SF_CHANNEL_MAP_REAR_CENTER,
SF_CHANNEL_MAP_REAR_LEFT,
SF_CHANNEL_MAP_REAR_RIGHT,
SF_CHANNEL_MAP_LFE,
SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER,
SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER,
SF_CHANNEL_MAP_SIDE_LEFT,
SF_CHANNEL_MAP_SIDE_RIGHT,
SF_CHANNEL_MAP_TOP_CENTER,
SF_CHANNEL_MAP_TOP_FRONT_LEFT,
SF_CHANNEL_MAP_TOP_FRONT_RIGHT,
SF_CHANNEL_MAP_TOP_FRONT_CENTER,
SF_CHANNEL_MAP_TOP_REAR_LEFT,
SF_CHANNEL_MAP_TOP_REAR_RIGHT,
SF_CHANNEL_MAP_TOP_REAR_CENTER
SF_CHANNEL_MAP_REAR_CENTER, /* Apple calls this 'Center Surround', Msft calls this 'Back Center' */
SF_CHANNEL_MAP_REAR_LEFT, /* Apple calls this 'Left Surround', Msft calls this 'Back Left' */
SF_CHANNEL_MAP_REAR_RIGHT, /* Apple calls this 'Right Surround', Msft calls this 'Back Right' */
SF_CHANNEL_MAP_LFE, /* Apple calls this 'LFEScreen', Msft calls this 'Low Frequency' */
SF_CHANNEL_MAP_FRONT_LEFT_OF_CENTER, /* Apple calls this 'Left Center' */
SF_CHANNEL_MAP_FRONT_RIGHT_OF_CENTER, /* Apple calls this 'Right Center */
SF_CHANNEL_MAP_SIDE_LEFT, /* Apple calls this 'Left Surround Direct' */
SF_CHANNEL_MAP_SIDE_RIGHT, /* Apple calls this 'Right Surround Direct' */
SF_CHANNEL_MAP_TOP_CENTER, /* Apple calls this 'Top Center Surround' */
SF_CHANNEL_MAP_TOP_FRONT_LEFT, /* Apple calls this 'Vertical Height Left' */
SF_CHANNEL_MAP_TOP_FRONT_RIGHT, /* Apple calls this 'Vertical Height Right' */
SF_CHANNEL_MAP_TOP_FRONT_CENTER, /* Apple calls this 'Vertical Height Center' */
SF_CHANNEL_MAP_TOP_REAR_LEFT, /* Apple and MS call this 'Top Back Left' */
SF_CHANNEL_MAP_TOP_REAR_RIGHT, /* Apple and MS call this 'Top Back Right' */
SF_CHANNEL_MAP_TOP_REAR_CENTER, /* Apple and MS call this 'Top Back Center' */
SF_CHANNEL_MAP_AMBISONIC_B_W,
SF_CHANNEL_MAP_AMBISONIC_B_X,
SF_CHANNEL_MAP_AMBISONIC_B_Y,
SF_CHANNEL_MAP_AMBISONIC_B_Z,
SF_CHANNEL_MAP_MAX
} ;
@@ -296,13 +316,14 @@ enum
typedef struct SNDFILE_tag SNDFILE ;
/* The following typedef is system specific and is defined when libsndfile is
** compiled. sf_count_t can be one of loff_t (Linux), off_t (*BSD), off64_t
** (Solaris), __int64_t (Win32) etc. On windows, we need to allow the same
** header file to be compiler by both GCC and the microsoft compiler.
** compiled. sf_count_t will be a 64 bit value when the underlying OS allows
** 64 bit file offsets.
** On windows, we need to allow the same header file to be compiler by both GCC
** and the Microsoft compiler.
*/
#ifdef _MSCVER
typedef __int64_t sf_count_t ;
#if (defined (_MSCVER) || defined (_MSC_VER))
typedef __int64 sf_count_t ;
#define SF_COUNT_MAX 0x7fffffffffffffffi64
#else
typedef @TYPEOF_SF_COUNT_T@ sf_count_t ;
@@ -310,9 +331,9 @@ typedef @TYPEOF_SF_COUNT_T@ sf_count_t ;
#endif
/* A pointer to a SF_INFO structure is passed to sf_open_read () and filled in.
/* A pointer to a SF_INFO structure is passed to sf_open () and filled in.
** On write, the SF_INFO structure is filled in by the user and passed into
** sf_open_write ().
** sf_open ().
*/
struct SF_INFO
@@ -396,9 +417,9 @@ typedef struct
struct
{ int mode ;
unsigned int start ;
unsigned int end ;
unsigned int count ;
uint32_t start ;
uint32_t end ;
uint32_t count ;
} loops [16] ; /* make variable in a sensible way */
} SF_INSTRUMENT ;
@@ -416,7 +437,7 @@ typedef struct
/* a full bar of 7/8 is 7 beats */
float bpm ; /* suggestion, as it can be calculated using other fields:*/
/* file's lenght, file's sampleRate and our time_sig_den*/
/* file's length, file's sampleRate and our time_sig_den*/
/* -> bpms are always the amount of _quarter notes_ per minute */
int root_key ; /* MIDI note, or -1 for None */
@@ -429,23 +450,56 @@ typedef struct
*/
#define SF_BROADCAST_INFO_VAR(coding_hist_size) \
struct \
{ char description [256] ; \
char originator [32] ; \
char originator_reference [32] ; \
char origination_date [10] ; \
char origination_time [8] ; \
unsigned int time_reference_low ; \
unsigned int time_reference_high ; \
short version ; \
char umid [64] ; \
char reserved [190] ; \
unsigned int coding_history_size ; \
char coding_history [coding_hist_size] ; \
{ char description [256] ; \
char originator [32] ; \
char originator_reference [32] ; \
char origination_date [10] ; \
char origination_time [8] ; \
uint32_t time_reference_low ; \
uint32_t time_reference_high ; \
short version ; \
char umid [64] ; \
char reserved [190] ; \
uint32_t coding_history_size ; \
char coding_history [coding_hist_size] ; \
}
/* SF_BROADCAST_INFO is the above struct with coding_history field of 256 bytes. */
typedef SF_BROADCAST_INFO_VAR (256) SF_BROADCAST_INFO ;
struct SF_CART_TIMER
{ char usage[4] ;
int32_t value ;
} ;
typedef struct SF_CART_TIMER SF_CART_TIMER ;
#define SF_CART_INFO_VAR(p_tag_text_size) \
struct \
{ char version [4] ; \
char title [64] ; \
char artist [64] ; \
char cut_id [64] ; \
char client_id [64] ; \
char category [64] ; \
char classification [64] ; \
char out_cue [64] ; \
char start_date [10] ; \
char start_time [8] ; \
char end_date [10] ; \
char end_time [8] ; \
char producer_app_id [64] ; \
char producer_app_version [64] ; \
char user_def [64] ; \
int32_t level_reference ; \
SF_CART_TIMER post_timers [8] ; \
char reserved [276] ; \
char url [1024] ; \
uint32_t tag_text_size ; \
char tag_text[p_tag_text_size] ; \
}
typedef SF_CART_INFO_VAR (256) SF_CART_INFO ;
/* Virtual I/O functionality. */
@@ -465,6 +519,7 @@ struct SF_VIRTUAL_IO
typedef struct SF_VIRTUAL_IO SF_VIRTUAL_IO ;
/* Open the specified file for read, write or both. On error, this will
** return a NULL pointer. To find the error number, pass a NULL SNDFILE
** to sf_strerror ().
@@ -473,9 +528,10 @@ typedef struct SF_VIRTUAL_IO SF_VIRTUAL_IO ;
SNDFILE* sf_open (const char *path, int mode, SF_INFO *sfinfo) ;
/* Use the existing file descriptor to create a SNDFILE object. If close_desc
** is TRUE, the file descriptor will be closed when sf_close() is called. If
** it is FALSE, the descritor will not be closed.
** it is FALSE, the descriptor will not be closed.
** When passed a descriptor like this, the library will assume that the start
** of file header is at the current file offset. This allows sound files within
** larger container files to be read and/or written.
@@ -489,18 +545,21 @@ SNDFILE* sf_open_fd (int fd, int mode, SF_INFO *sfinfo, int close_desc) ;
SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) ;
/* sf_error () returns a error number which can be translated to a text
** string using sf_error_number().
*/
int sf_error (SNDFILE *sndfile) ;
/* sf_strerror () returns to the caller a pointer to the current error message for
** the given SNDFILE.
*/
const char* sf_strerror (SNDFILE *sndfile) ;
/* sf_error_number () allows the retrieval of the error string for each internal
** error number.
**
@@ -508,8 +567,9 @@ const char* sf_strerror (SNDFILE *sndfile) ;
const char* sf_error_number (int errnum) ;
/* The following two error functions are deprecated but they will remain in the
** library for the forseeable future. The function sf_strerror() should be used
** library for the foreseeable future. The function sf_strerror() should be used
** in their place.
*/
@@ -521,10 +581,12 @@ int sf_error_str (SNDFILE *sndfile, char* str, size_t len) ;
int sf_command (SNDFILE *sndfile, int command, void *data, int datasize) ;
/* Return TRUE if fields of the SF_INFO struct are a valid combination of values. */
int sf_format_check (const SF_INFO *info) ;
/* Seek within the waveform data chunk of the SNDFILE. sf_seek () uses
** the same values for whence (SEEK_SET, SEEK_CUR and SEEK_END) as
** stdio.h function fseek ().
@@ -537,8 +599,15 @@ int sf_format_check (const SF_INFO *info) ;
** On error all of these functions return -1.
*/
enum
{ SF_SEEK_SET = SEEK_SET,
SF_SEEK_CUR = SEEK_CUR,
SF_SEEK_END = SEEK_END
} ;
sf_count_t sf_seek (SNDFILE *sndfile, sf_count_t frames, int whence) ;
/* Functions for retrieving and setting string data within sound files.
** Not all file types support this features; AIFF and WAV do. For both
** functions, the str_type parameter must be one of the SF_STR_* values
@@ -551,12 +620,31 @@ int sf_set_string (SNDFILE *sndfile, int str_type, const char* str) ;
const char* sf_get_string (SNDFILE *sndfile, int str_type) ;
/* Return the library version string. */
const char * sf_version_string (void) ;
/* Return the current byterate at this point in the file. The byte rate in this
** case is the number of bytes per second of audio data. For instance, for a
** stereo, 18 bit PCM encoded file with an 16kHz sample rate, the byte rate
** would be 2 (stereo) * 2 (two bytes per sample) * 16000 => 64000 bytes/sec.
** For some file formats the returned value will be accurate and exact, for some
** it will be a close approximation, for some it will be the average bitrate for
** the whole file and for some it will be a time varying value that was accurate
** when the file was most recently read or written.
** To get the bitrate, multiple this value by 8.
** Returns -1 for unknown.
*/
int sf_current_byterate (SNDFILE *sndfile) ;
/* Functions for reading/writing the waveform data of a sound file.
*/
sf_count_t sf_read_raw (SNDFILE *sndfile, void *ptr, sf_count_t bytes) ;
sf_count_t sf_write_raw (SNDFILE *sndfile, const void *ptr, sf_count_t bytes) ;
/* Functions for reading and writing the data chunk in terms of frames.
** The number of items actually read/written = frames * number of channels.
** sf_xxxx_raw read/writes the raw data bytes from/to the file
@@ -579,6 +667,7 @@ sf_count_t sf_writef_float (SNDFILE *sndfile, const float *ptr, sf_count_t frame
sf_count_t sf_readf_double (SNDFILE *sndfile, double *ptr, sf_count_t frames) ;
sf_count_t sf_writef_double (SNDFILE *sndfile, const double *ptr, sf_count_t frames) ;
/* Functions for reading and writing the data chunk in terms of items.
** Otherwise similar to above.
** All of these read/write function return number of items read/written.
@@ -596,6 +685,7 @@ sf_count_t sf_write_float (SNDFILE *sndfile, const float *ptr, sf_count_t items)
sf_count_t sf_read_double (SNDFILE *sndfile, double *ptr, sf_count_t items) ;
sf_count_t sf_write_double (SNDFILE *sndfile, const double *ptr, sf_count_t items) ;
/* Close the SNDFILE and clean up all memory allocations associated with this
** file.
** Returns 0 on success, or an error number.
@@ -603,6 +693,7 @@ sf_count_t sf_write_double (SNDFILE *sndfile, const double *ptr, sf_count_t item
int sf_close (SNDFILE *sndfile) ;
/* If the file is opened SFM_WRITE or SFM_RDWR, call fsync() on the file
** to force the writing of data to disk. If the file is opened SFM_READ
** no action is taken.
@@ -610,8 +701,124 @@ int sf_close (SNDFILE *sndfile) ;
void sf_write_sync (SNDFILE *sndfile) ;
/* The function sf_wchar_open() is Windows Only!
** Open a file passing in a Windows Unicode filename. Otherwise, this is
** the same as sf_open().
**
** In order for this to work, you need to do the following:
**
** #include <windows.h>
** #define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
** #including <sndfile.h>
*/
#if (defined (ENABLE_SNDFILE_WINDOWS_PROTOTYPES) && ENABLE_SNDFILE_WINDOWS_PROTOTYPES)
SNDFILE* sf_wchar_open (LPCWSTR wpath, int mode, SF_INFO *sfinfo) ;
#endif
/* Getting and setting of chunks from within a sound file.
**
** These functions allow the getting and setting of chunks within a sound file
** (for those formats which allow it).
**
** These functions fail safely. Specifically, they will not allow you to overwrite
** existing chunks or add extra versions of format specific reserved chunks but
** should allow you to retrieve any and all chunks (may not be implemented for
** all chunks or all file formats).
*/
struct SF_CHUNK_INFO
{ char id [64] ; /* The chunk identifier. */
unsigned id_size ; /* The size of the chunk identifier. */
unsigned datalen ; /* The size of that data. */
void *data ; /* Pointer to the data. */
} ;
typedef struct SF_CHUNK_INFO SF_CHUNK_INFO ;
/* Set the specified chunk info (must be done before any audio data is written
** to the file). This will fail for format specific reserved chunks.
** The chunk_info->data pointer must be valid until the file is closed.
** Returns SF_ERR_NO_ERROR on success or non-zero on failure.
*/
int sf_set_chunk (SNDFILE * sndfile, const SF_CHUNK_INFO * chunk_info) ;
/*
** An opaque structure to an iterator over the all chunks of a given id
*/
typedef struct SF_CHUNK_ITERATOR SF_CHUNK_ITERATOR ;
/* Get an iterator for all chunks matching chunk_info.
** The iterator will point to the first chunk matching chunk_info.
** Chunks are matching, if (chunk_info->id) matches the first
** (chunk_info->id_size) bytes of a chunk found in the SNDFILE* handle.
** If chunk_info is NULL, an iterator to all chunks in the SNDFILE* handle
** is returned.
** The values of chunk_info->datalen and chunk_info->data are ignored.
** If no matching chunks are found in the sndfile, NULL is returned.
** The returned iterator will stay valid until one of the following occurs:
** a) The sndfile is closed.
** b) A new chunk is added using sf_set_chunk().
** c) Another chunk iterator function is called on the same SNDFILE* handle
** that causes the iterator to be modified.
** The memory for the iterator belongs to the SNDFILE* handle and is freed when
** sf_close() is called.
*/
SF_CHUNK_ITERATOR *
sf_get_chunk_iterator (SNDFILE * sndfile, const SF_CHUNK_INFO * chunk_info) ;
/* Iterate through chunks by incrementing the iterator.
** Increments the iterator and returns a handle to the new one.
** After this call, iterator will no longer be valid, and you must use the
** newly returned handle from now on.
** The returned handle can be used to access the next chunk matching
** the criteria as defined in sf_get_chunk_iterator().
** If iterator points to the last chunk, this will free all resources
** associated with iterator and return NULL.
** The returned iterator will stay valid until sf_get_chunk_iterator_next
** is called again, the sndfile is closed or a new chunk us added.
*/
SF_CHUNK_ITERATOR *
sf_next_chunk_iterator (SF_CHUNK_ITERATOR * iterator) ;
/* Get the size of the specified chunk.
** If the specified chunk exists, the size will be returned in the
** datalen field of the SF_CHUNK_INFO struct.
** Additionally, the id of the chunk will be copied to the id
** field of the SF_CHUNK_INFO struct and it's id_size field will
** be updated accordingly.
** If the chunk doesn't exist chunk_info->datalen will be zero, and the
** id and id_size fields will be undefined.
** The function will return SF_ERR_NO_ERROR on success or non-zero on
** failure.
*/
int
sf_get_chunk_size (const SF_CHUNK_ITERATOR * it, SF_CHUNK_INFO * chunk_info) ;
/* Get the specified chunk data.
** If the specified chunk exists, up to chunk_info->datalen bytes of
** the chunk data will be copied into the chunk_info->data buffer
** (allocated by the caller) and the chunk_info->datalen field
** updated to reflect the size of the data. The id and id_size
** field will be updated according to the retrieved chunk
** If the chunk doesn't exist chunk_info->datalen will be zero, and the
** id and id_size fields will be undefined.
** The function will return SF_ERR_NO_ERROR on success or non-zero on
** failure.
*/
int
sf_get_chunk_data (const SF_CHUNK_ITERATOR * it, SF_CHUNK_INFO * chunk_info) ;
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* SNDFILE_H */
+106 -2
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2005-2007 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2005-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
@@ -77,6 +77,16 @@ class SndfileHandle
int format = 0, int channels = 0, int samplerate = 0) ;
SndfileHandle (std::string const & path, int mode = SFM_READ,
int format = 0, int channels = 0, int samplerate = 0) ;
SndfileHandle (int fd, bool close_desc, int mode = SFM_READ,
int format = 0, int channels = 0, int samplerate = 0) ;
SndfileHandle (SF_VIRTUAL_IO &sfvirtual, void *user_data, int mode = SFM_READ,
int format = 0, int channels = 0, int samplerate = 0) ;
#ifdef ENABLE_SNDFILE_WINDOWS_PROTOTYPES
SndfileHandle (LPCWSTR wpath, int mode = SFM_READ,
int format = 0, int channels = 0, int samplerate = 0) ;
#endif
~SndfileHandle (void) ;
SndfileHandle (const SndfileHandle &orig) ;
@@ -132,6 +142,11 @@ class SndfileHandle
sf_count_t readRaw (void *ptr, sf_count_t bytes) ;
sf_count_t writeRaw (const void *ptr, sf_count_t bytes) ;
/**< Raw access to the handle. SndfileHandle keeps ownership. */
SNDFILE * rawHandle (void) ;
/**< Take ownership of handle, if reference count is 1. */
SNDFILE * takeOwnership (void) ;
} ;
/*==============================================================================
@@ -191,6 +206,53 @@ SndfileHandle::SndfileHandle (std::string const & path, int mode, int fmt, int c
return ;
} /* SndfileHandle std::string constructor */
inline
SndfileHandle::SndfileHandle (int fd, bool close_desc, int mode, int fmt, int chans, int srate)
: p (NULL)
{
if (fd < 0)
return ;
p = new (std::nothrow) SNDFILE_ref () ;
if (p != NULL)
{ p->ref = 1 ;
p->sfinfo.frames = 0 ;
p->sfinfo.channels = chans ;
p->sfinfo.format = fmt ;
p->sfinfo.samplerate = srate ;
p->sfinfo.sections = 0 ;
p->sfinfo.seekable = 0 ;
p->sf = sf_open_fd (fd, mode, &p->sfinfo, close_desc) ;
} ;
return ;
} /* SndfileHandle fd constructor */
inline
SndfileHandle::SndfileHandle (SF_VIRTUAL_IO &sfvirtual, void *user_data, int mode, int fmt, int chans, int srate)
: p (NULL)
{
p = new (std::nothrow) SNDFILE_ref () ;
if (p != NULL)
{ p->ref = 1 ;
p->sfinfo.frames = 0 ;
p->sfinfo.channels = chans ;
p->sfinfo.format = fmt ;
p->sfinfo.samplerate = srate ;
p->sfinfo.sections = 0 ;
p->sfinfo.seekable = 0 ;
p->sf = sf_open_virtual (&sfvirtual, mode, &p->sfinfo, user_data) ;
} ;
return ;
} /* SndfileHandle std::string constructor */
inline
SndfileHandle::~SndfileHandle (void)
{ if (p != NULL && --p->ref == 0)
@@ -249,7 +311,7 @@ SndfileHandle::getString (int str_type) const
{ return sf_get_string (p->sf, str_type) ; }
inline int
SndfileHandle::formatCheck(int fmt, int chans, int srate)
SndfileHandle::formatCheck (int fmt, int chans, int srate)
{
SF_INFO sfinfo ;
@@ -337,6 +399,48 @@ inline sf_count_t
SndfileHandle::writeRaw (const void *ptr, sf_count_t bytes)
{ return sf_write_raw (p->sf, ptr, bytes) ; }
inline SNDFILE *
SndfileHandle::rawHandle (void)
{ return (p ? p->sf : NULL) ; }
inline SNDFILE *
SndfileHandle::takeOwnership (void)
{
if (p == NULL || (p->ref != 1))
return NULL ;
SNDFILE * sf = p->sf ;
p->sf = NULL ;
delete p ;
p = NULL ;
return sf ;
}
#ifdef ENABLE_SNDFILE_WINDOWS_PROTOTYPES
inline
SndfileHandle::SndfileHandle (LPCWSTR wpath, int mode, int fmt, int chans, int srate)
: p (NULL)
{
p = new (std::nothrow) SNDFILE_ref () ;
if (p != NULL)
{ p->ref = 1 ;
p->sfinfo.frames = 0 ;
p->sfinfo.channels = chans ;
p->sfinfo.format = fmt ;
p->sfinfo.samplerate = srate ;
p->sfinfo.sections = 0 ;
p->sfinfo.seekable = 0 ;
p->sf = sf_wchar_open (wpath, mode, &p->sfinfo) ;
} ;
return ;
} /* SndfileHandle const wchar_t * constructor */
#endif
#endif /* SNDFILE_HH */
+68 -64
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2001-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2001-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -32,9 +32,9 @@ static void hexdump (void *data, int len) ;
int
psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
{ static char lsf_name [] = PACKAGE "-" VERSION ;
static char bracket_name [] = " (" PACKAGE "-" VERSION ")" ;
int k, str_len, len_remaining, str_flags, str_type_replace = 0 ;
{ char new_str [128] ;
size_t str_len ;
int k, str_flags ;
if (str == NULL)
return SFE_STR_BAD_STRING ;
@@ -42,10 +42,10 @@ psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
str_len = strlen (str) ;
/* A few extra checks for write mode. */
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ if ((psf->str_flags & SF_STR_ALLOW_START) == 0)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if ((psf->strings.flags & SF_STR_ALLOW_START) == 0)
return SFE_STR_NO_SUPPORT ;
if (psf->have_written && (psf->str_flags & SF_STR_ALLOW_END) == 0)
if (psf->have_written && (psf->strings.flags & SF_STR_ALLOW_END) == 0)
return SFE_STR_NO_SUPPORT ;
/* Only allow zero length strings for software. */
if (str_type != SF_STR_SOFTWARE && str_len == 0)
@@ -55,17 +55,17 @@ psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
/* Find the next free slot in table. */
for (k = 0 ; k < SF_MAX_STRINGS ; k++)
{ /* If we find a matching entry clear it. */
if (psf->strings [k].type == str_type)
psf->strings [k].type = -1 ;
if (psf->strings.data [k].type == str_type)
psf->strings.data [k].type = -1 ;
if (psf->strings [k].type == 0)
if (psf->strings.data [k].type == 0)
break ;
} ;
/* Determine flags */
str_flags = SF_STR_LOCATE_START ;
if (psf->mode == SFM_RDWR || psf->have_written || str_type_replace)
{ if ((psf->str_flags & SF_STR_ALLOW_END) == 0)
if (psf->file.mode == SFM_RDWR || psf->have_written)
{ if ((psf->strings.flags & SF_STR_ALLOW_END) == 0)
return SFE_STR_NO_ADD_END ;
str_flags = SF_STR_LOCATE_END ;
} ;
@@ -74,54 +74,40 @@ psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
if (k >= SF_MAX_STRINGS)
return SFE_STR_MAX_COUNT ;
if (k == 0 && psf->str_end != NULL)
{ psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->str_end != NULL\n") ;
if (k == 0 && psf->strings.storage_used != 0)
{ psf_log_printf (psf, "SFE_STR_WEIRD : k == 0 && psf->strings.storage_used != 0\n") ;
return SFE_STR_WEIRD ;
} ;
if (k != 0 && psf->str_end == NULL)
{ psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->str_end == NULL\n") ;
if (k != 0 && psf->strings.storage_used == 0)
{ psf_log_printf (psf, "SFE_STR_WEIRD : k != 0 && psf->strings.storage_used == 0\n") ;
return SFE_STR_WEIRD ;
} ;
/* Special case for the first string. */
if (k == 0)
psf->str_end = psf->str_storage ;
len_remaining = SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage) ;
if (len_remaining < str_len + 2)
return SFE_STR_MAX_DATA ;
psf->strings.storage_used = 0 ;
switch (str_type)
{ case SF_STR_SOFTWARE :
/* In write mode, want to append libsndfile-version to string. */
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ psf->strings [k].type = str_type ;
psf->strings [k].str = psf->str_end ;
psf->strings [k].flags = str_flags ;
memcpy (psf->str_end, str, str_len + 1) ;
psf->str_end += str_len ;
/*
** If the supplied string does not already contain a
** libsndfile-X.Y.Z component, then add it.
*/
if (strstr (str, PACKAGE) == NULL && len_remaining > (int) (strlen (bracket_name) + str_len + 2))
{ if (strlen (str) == 0)
strncat (psf->str_end, lsf_name, len_remaining) ;
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (strstr (str, PACKAGE) == NULL)
{ /*
** If the supplied string does not already contain a
** libsndfile-X.Y.Z component, then add it.
*/
if (strlen (str) == 0)
snprintf (new_str, sizeof (new_str), "%s-%s", PACKAGE, VERSION) ;
else
strncat (psf->str_end, bracket_name, len_remaining) ;
psf->str_end += strlen (psf->str_end) ;
} ;
snprintf (new_str, sizeof (new_str), "%s (%s-%s)", str, PACKAGE, VERSION) ;
}
else
snprintf (new_str, sizeof (new_str), "%s", str) ;
/* Plus one to catch string terminator. */
psf->str_end += 1 ;
break ;
str = new_str ;
} ;
/* Fall though if not write mode. */
break ;
case SF_STR_TITLE :
case SF_STR_COPYRIGHT :
@@ -130,13 +116,8 @@ psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
case SF_STR_DATE :
case SF_STR_ALBUM :
case SF_STR_LICENSE :
psf->strings [k].type = str_type ;
psf->strings [k].str = psf->str_end ;
psf->strings [k].flags = str_flags ;
/* Plus one to catch string terminator. */
memcpy (psf->str_end, str, str_len + 1) ;
psf->str_end += str_len + 1 ;
case SF_STR_TRACKNUMBER :
case SF_STR_GENRE :
break ;
default :
@@ -144,16 +125,39 @@ psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
return SFE_STR_BAD_TYPE ;
} ;
psf->str_flags |= str_flags ;
/* Plus one to catch string terminator. */
str_len = strlen (str) + 1 ;
if (psf->strings.storage_used + str_len + 1 > psf->strings.storage_len)
{ char * temp = psf->strings.storage ;
size_t newlen = 2 * psf->strings.storage_len + str_len + 1 ;
newlen = newlen < 256 ? 256 : newlen ;
if ((psf->strings.storage = realloc (temp, newlen)) == NULL)
{ psf->strings.storage = temp ;
return SFE_MALLOC_FAILED ;
} ;
psf->strings.storage_len = newlen ;
} ;
psf->strings.data [k].type = str_type ;
psf->strings.data [k].offset = psf->strings.storage_used ;
psf->strings.data [k].flags = str_flags ;
memcpy (psf->strings.storage + psf->strings.storage_used, str, str_len) ;
psf->strings.storage_used += str_len ;
psf->strings.flags |= str_flags ;
#if STRINGS_DEBUG
psf_log_printf (psf, "str_storage : %X\n", (int) psf->str_storage) ;
psf_log_printf (psf, "str_end : %X\n", (int) psf->str_end) ;
psf_log_printf (psf, "sizeof (str_storage) : %d\n", SIGNED_SIZEOF (psf->str_storage)) ;
psf_log_printf (psf, "used : %d\n", (int ) (psf->str_end - psf->str_storage)) ;
psf_log_printf (psf, "remaining : %d\n", SIGNED_SIZEOF (psf->str_storage) - (psf->str_end - psf->str_storage)) ;
psf_log_printf (psf, "str_storage : %p\n", psf->strings.storage) ;
psf_log_printf (psf, "storage_used : %u\n", psf->strings.storage_used) ;
psf_log_printf (psf, "used : %d\n", psf->strings.storage_used) ;
psf_log_printf (psf, "remaining : %d\n", psf->strings.storage_len - psf->strings.storage_used ;
hexdump (psf->str_storage, 300) ;
hexdump (psf->strings.storage, 300) ;
#endif
return 0 ;
@@ -161,7 +165,7 @@ psf_store_string (SF_PRIVATE *psf, int str_type, const char *str)
int
psf_set_string (SF_PRIVATE *psf, int str_type, const char *str)
{ if (psf->mode == SFM_READ)
{ if (psf->file.mode == SFM_READ)
return SFE_STR_NOT_WRITE ;
return psf_store_string (psf, str_type, str) ;
@@ -172,8 +176,8 @@ psf_get_string (SF_PRIVATE *psf, int str_type)
{ int k ;
for (k = 0 ; k < SF_MAX_STRINGS ; k++)
if (str_type == psf->strings [k].type)
return psf->strings [k].str ;
if (str_type == psf->strings.data [k].type)
return psf->strings.storage + psf->strings.data [k].offset ;
return NULL ;
} /* psf_get_string */
@@ -183,7 +187,7 @@ psf_location_string_count (const SF_PRIVATE * psf, int location)
{ int k, count = 0 ;
for (k = 0 ; k < SF_MAX_STRINGS ; k++)
if (psf->strings [k].type > 0 && psf->strings [k].flags & location)
if (psf->strings.data [k].type > 0 && psf->strings.data [k].flags & location)
count ++ ;
return count ;
@@ -208,7 +212,7 @@ hexdump (void *data, int len)
printf ("%02X ", ptr [k] & 0xFF) ;
printf (" ") ;
for (k = 0 ; k < 16 ; k++)
printf ("%c", isprint (ptr [k]) ? ptr [k] : '.') ;
printf ("%c", psf_isprint (ptr [k]) ? ptr [k] : '.') ;
puts ("") ;
ptr += 16 ;
len -= 16 ;
+23 -14
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -82,7 +82,7 @@ int
svx_open (SF_PRIVATE *psf)
{ int error ;
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = svx_read_header (psf)))
return error ;
@@ -95,7 +95,7 @@ svx_open (SF_PRIVATE *psf)
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
@@ -140,7 +140,7 @@ svx_read_header (SF_PRIVATE *psf)
memset (&vhdr, 0, sizeof (vhdr)) ;
psf_binheader_readf (psf, "p", 0) ;
/* Set default number of channels. Currently can't handle stereo SVX files. */
/* Set default number of channels. Modify later if necessary */
psf->sf.channels = 1 ;
psf->sf.format = SF_FORMAT_SVX ;
@@ -252,12 +252,12 @@ svx_read_header (SF_PRIVATE *psf)
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
if (strlen (psf->filename) != dword)
{ if (dword > sizeof (psf->filename) - 1)
if (strlen (psf->file.name.c) != dword)
{ if (dword > sizeof (psf->file.name.c) - 1)
return SFE_SVX_BAD_NAME_LENGTH ;
psf_binheader_readf (psf, "b", psf->filename, dword) ;
psf->filename [dword] = 0 ;
psf_binheader_readf (psf, "b", psf->file.name.c, dword) ;
psf->file.name.c [dword] = 0 ;
}
else
psf_binheader_readf (psf, "j", dword) ;
@@ -283,9 +283,15 @@ svx_read_header (SF_PRIVATE *psf)
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
bytecount += psf_binheader_readf (psf, "E4", &channels) ;
psf->sf.channels = channels ;
psf_log_printf (psf, " Channels : %d\n", channels) ;
if (channels == 2 || channels == 4)
psf_log_printf (psf, " Channels : %d => mono\n", channels) ;
else if (channels == 6)
{ psf->sf.channels = 2 ;
psf_log_printf (psf, " Channels : %d => stereo\n", channels) ;
}
else
psf_log_printf (psf, " Channels : %d *** assuming mono\n", channels) ;
psf_binheader_readf (psf, "j", dword - bytecount) ;
break ;
@@ -304,8 +310,8 @@ svx_read_header (SF_PRIVATE *psf)
break ;
default :
if (isprint ((marker >> 24) & 0xFF) && isprint ((marker >> 16) & 0xFF)
&& isprint ((marker >> 8) & 0xFF) && isprint (marker & 0xFF))
if (psf_isprint ((marker >> 24) & 0xFF) && psf_isprint ((marker >> 16) & 0xFF)
&& psf_isprint ((marker >> 8) & 0xFF) && psf_isprint (marker & 0xFF))
{ psf_binheader_readf (psf, "E4", &dword) ;
psf_log_printf (psf, "%M : %d (unknown marker)\n", marker, dword) ;
@@ -342,7 +348,7 @@ svx_read_header (SF_PRIVATE *psf)
static int
svx_close (SF_PRIVATE *psf)
{
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
if (psf->file.mode == SFM_WRITE || psf->file.mode == SFM_RDWR)
svx_write_header (psf, SF_TRUE) ;
return 0 ;
@@ -385,8 +391,11 @@ svx_write_header (SF_PRIVATE *psf, int calc_length)
/* VHDR : volume */
psf_binheader_writef (psf, "E4", (psf->bytewidth == 1) ? 0xFF : 0xFFFF) ;
if (psf->sf.channels == 2)
psf_binheader_writef (psf, "Em44", CHAN_MARKER, 4, 6) ;
/* Filename and annotation strings. */
psf_binheader_writef (psf, "Emsms", NAME_MARKER, psf->filename, ANNO_MARKER, annotation) ;
psf_binheader_writef (psf, "Emsms", NAME_MARKER, psf->file.name.c, ANNO_MARKER, annotation) ;
/* BODY marker and size. */
psf_binheader_writef (psf, "Etm8", BODY_MARKER, (psf->datalength < 0) ?
+2 -3
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2007-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -88,8 +88,7 @@ test_audio_detect (void)
ad.endianness = SF_ENDIAN_LITTLE ;
ad.channels = 1 ;
if (audio_detect (&psf, &ad, float_le_mono, sizeof (float_le_mono)) != SF_FORMAT_FLOAT)
{ if (errors == 0) puts ("\nFailed tests :\n") ;
puts (" float_le_mono") ;
{ puts (" float_le_mono") ;
errors ++ ;
} ;
+119
View File
@@ -0,0 +1,119 @@
/*
** Copyright (C) 2010-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "test_main.h"
#define BCAST_MAX 512
typedef SF_BROADCAST_INFO_VAR (BCAST_MAX) SF_BROADCAST_INFO_512 ;
static void
fill_coding_history (SF_BROADCAST_INFO_512 * bi)
{ static const char *lines [] =
{ "Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit.",
"Donec dignissim erat\nvehicula libero condimentum\ndictum porta augue faucibus.",
"Maecenas nec turpis\nsit amet quam\nfaucibus adipiscing.",
"Mauris aliquam,\nlectus interdum\ntincidunt luctus.",
"\n\n\n\n\n\n\n\n\n\n\n\n",
"In auctor lorem\nvel est euismod\ncondimentum.",
"\n\n\n\n\n\n\n\n\n\n\n\n",
"Ut vitae magna\nid dui placerat vehicula\nin id lectus.",
"\n\n\n\n\n\n\n\n\n\n\n\n",
"Sed lacus leo,\nmolestie et luctus ac,\ntincidunt sit amet nisi.",
"\n\n\n\n\n\n\n\n\n\n\n\n",
"Sed ligula neque,\ngravida semper vulputate laoreet,\ngravida eu tellus.",
"Donec dolor dolor,\nscelerisque in consequat ornare,\ntempor nec nisl."
} ;
int k ;
bi->coding_history [0] = 0 ;
for (k = 0 ; strlen (bi->coding_history) < bi->coding_history_size - 1 ; k ++)
append_snprintf (bi->coding_history, bi->coding_history_size, "%s\n", lines [k % ARRAY_LEN (lines)]) ;
return ;
} /* fill_coding_listory */
static void
test_broadcast_var_set (void)
{ SF_PRIVATE sf_private, *psf ;
int k ;
psf = &sf_private ;
memset (psf, 0, sizeof (sf_private)) ;
print_test_name ("Testing broadcast_var_set ") ;
for (k = 64 ; k < BCAST_MAX ; k++)
{
SF_BROADCAST_INFO_512 bi ;
memset (&bi, 0, sizeof (bi)) ;
bi.coding_history_size = k ;
fill_coding_history (&bi) ;
bi.coding_history_size -- ;
broadcast_var_set (psf, (SF_BROADCAST_INFO*) &bi, sizeof (bi)) ;
} ;
if (psf->broadcast_16k != NULL)
free (psf->broadcast_16k) ;
puts ("ok") ;
} /* test_broadcast_var_set */
static void
test_broadcast_var_zero (void)
{ SF_PRIVATE sf_private, *psf ;
SF_BROADCAST_INFO_VAR (0) bi ;
psf = &sf_private ;
memset (psf, 0, sizeof (sf_private)) ;
psf->file.mode = SFM_RDWR ;
print_test_name ("Testing broadcast_var_zero ") ;
memset (&bi, 0, sizeof (bi)) ;
broadcast_var_set (psf, (SF_BROADCAST_INFO*) &bi, sizeof (bi)) ;
if (psf->broadcast_16k->coding_history_size != 0)
{ printf ("\n\nLine %d: coding_history_size %d should be zero.\n\n", __LINE__, psf->broadcast_16k->coding_history_size) ;
exit (1) ;
} ;
if (psf->broadcast_16k != NULL)
free (psf->broadcast_16k) ;
puts ("ok") ;
} /* test_broadcast_var_zero */
void
test_broadcast_var (void)
{ test_broadcast_var_set () ;
test_broadcast_var_zero () ;
} /* test_broadcast_var */
+91
View File
@@ -0,0 +1,91 @@
/*
** Copyright (C) 2010-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
** the Free Software Foundation; either version 2.1 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Lesser General Public License for more details.
**
** You should have received a copy of the GNU Lesser General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#include "test_main.h"
#define CART_MAX 512
typedef SF_CART_INFO_VAR (CART_MAX) SF_CART_INFO_512 ;
static void
fill_tag_text (SF_CART_INFO_512 * ci)
{ static const char *lines [] =
{ "Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit.",
"Donec dignissim erat\nvehicula libero condimentum\ndictum porta augue faucibus.",
"Maecenas nec turpis\nsit amet quam\nfaucibus adipiscing.",
"Mauris aliquam,\nlectus interdum\ntincidunt luctus.",
"\n\n\n\n\n\n\n\n\n\n\n\n",
"In auctor lorem\nvel est euismod\ncondimentum.",
"\n\n\n\n\n\n\n\n\n\n\n\n",
"Ut vitae magna\nid dui placerat vehicula\nin id lectus.",
"\n\n\n\n\n\n\n\n\n\n\n\n",
"Sed lacus leo,\nmolestie et luctus ac,\ntincidunt sit amet nisi.",
"\n\n\n\n\n\n\n\n\n\n\n\n",
"Sed ligula neque,\ngravida semper vulputate laoreet,\ngravida eu tellus.",
"Donec dolor dolor,\nscelerisque in consequat ornare,\ntempor nec nisl."
} ;
int k ;
ci->tag_text [0] = 0 ;
for (k = 0 ; strlen (ci->tag_text) < ci->tag_text_size - 1 ; k ++)
append_snprintf (ci->tag_text, ci->tag_text_size, "%s\n", lines [k % ARRAY_LEN (lines)]) ;
return ;
} /* fill_tag_text */
void
test_cart_var (void)
{ SF_PRIVATE sf_private, *psf ;
SF_CART_TIMER timer ;
int k ;
psf = &sf_private ;
memset (psf, 0, sizeof (sf_private)) ;
print_test_name ("Testing cart_var_set ") ;
for (k = 64 ; k < CART_MAX ; k++)
{
SF_CART_INFO_512 ci ;
memset (&ci, 0, sizeof (ci)) ;
memset (&timer, 0, sizeof (timer)) ;
memcpy (ci.post_timers, &timer, sizeof (timer)) ;
ci.tag_text_size = k ;
fill_tag_text (&ci) ;
ci.tag_text_size -- ;
cart_var_set (psf, (SF_CART_INFO*) &ci, sizeof (ci)) ;
} ;
if (psf->cart_16k != NULL)
free (psf->cart_16k) ;
puts ("ok") ;
} /* test_cart_var */
+11 -5
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2006-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2006-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -20,7 +20,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
@@ -34,7 +33,7 @@
** This is a bit rough, but it is the nicest way to do it.
*/
#define cmp_test(line,ival,tval,str) \
#define cmp_test(line, ival, tval, str) \
if (ival != tval) \
{ printf (str, line, ival, tval) ; \
exit (1) ; \
@@ -62,7 +61,10 @@ conversion_test (char endian)
psf = &sf_private ;
memset (psf, 0, sizeof (sf_private)) ;
if (psf_fopen (psf, filename, SFM_WRITE) != 0)
psf->file.mode = SFM_WRITE ;
snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
if (psf_fopen (psf) != 0)
{ printf ("\n\nError : failed to open file '%s' for write.\n\n", filename) ;
exit (1) ;
} ;
@@ -72,7 +74,11 @@ conversion_test (char endian)
psf_fclose (psf) ;
memset (psf, 0, sizeof (sf_private)) ;
if (psf_fopen (psf, filename, SFM_READ) != 0)
psf->file.mode = SFM_READ ;
snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
if (psf_fopen (psf) != 0)
{ printf ("\n\nError : failed to open file '%s' for read.\n\n", filename) ;
exit (1) ;
} ;
+1 -1
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
+20
View File
@@ -18,3 +18,23 @@ int_type = {
format = FMT_INT64 ;
} ;
int_size = {
name = 16 ;
typename = int16_t ;
value = 0x4142 ;
strval = "AB" ;
} ;
int_size = {
name = 32 ;
typename = int32_t ;
value = 0x30313233 ;
strval = "0123" ;
} ;
int_size = {
name = 64 ;
typename = int64_t ;
value = 0x3031323334353637 ;
strval = "01234567" ;
} ;
+35 -1
View File
@@ -1,6 +1,6 @@
[+ AutoGen5 template c +]
/*
** Copyright (C) 2002-2005 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -105,6 +105,34 @@ test_endswap_[+ (get "name") +] (void)
[+ ENDFOR int_type
+]
[+ FOR int_size +]
static void
test_psf_put_be[+ (get "name") +] (void)
{ const char *test = "[+ (get "strval") +]" ;
uint8_t array [32] ;
int k ;
printf (" %-40s : ", __func__) ;
fflush (stdout) ;
for (k = 0 ; k < 10 ; k++)
{ memset (array, 0, sizeof (array)) ;
psf_put_be[+ (get "name") +] (array, k, [+ (get "value") +]) ;
if (memcmp (array + k, test, sizeof ([+ (get "typename") +])) != 0)
{ printf ("\n\nLine %d : Put failed at index %d.\n", __LINE__, k) ;
exit (1) ;
} ;
if (psf_get_be[+ (get "name") +] (array, k) != [+ (get "value") +])
{ printf ("\n\nLine %d : Get failed at index %d.\n", __LINE__, k) ;
exit (1) ;
} ;
} ;
puts ("ok") ;
} /* test_psf_put_be[+ (get "name") +] */
[+ ENDFOR int_size
+]
void
test_endswap (void)
@@ -113,5 +141,11 @@ test_endswap (void)
+] test_endswap_[+ (get "name") +] () ;
[+ ENDFOR int_type
+]
[+ FOR int_size
+] test_psf_put_be[+ (get "name") +] () ;
[+ ENDFOR int_endsize
+]
} /* test_endswap */
+33 -31
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2002-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2002-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -27,6 +27,7 @@
#include <string.h>
#include <errno.h>
#include <inttypes.h>
#include "common.h"
@@ -68,10 +69,11 @@ file_open_test (const char *filename)
exit (1) ;
} ;
snprintf (psf->filename, sizeof (psf->filename), "%s", filename) ;
psf->file.mode = SFM_READ ;
snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
/* Test that open for read fails if the file doesn't exist. */
error = psf_fopen (psf, psf->filename, SFM_READ) ;
error = psf_fopen (psf) ;
if (error == 0)
{ printf ("\n\nLine %d: psf_fopen() should have failed.\n\n", __LINE__) ;
exit (1) ;
@@ -81,26 +83,26 @@ file_open_test (const char *filename)
psf->error = SFE_NO_ERROR ;
/* Test file open in write mode. */
psf->mode = SFM_WRITE ;
psf->file.mode = SFM_WRITE ;
test_open_or_die (psf, __LINE__) ;
test_close_or_die (psf, __LINE__) ;
unlink (psf->filename) ;
unlink (psf->file.path.c) ;
/* Test file open in read/write mode for a non-existant file. */
psf->mode = SFM_RDWR ;
psf->file.mode = SFM_RDWR ;
test_open_or_die (psf, __LINE__) ;
test_close_or_die (psf, __LINE__) ;
/* Test file open in read/write mode for an existing file. */
psf->mode = SFM_RDWR ;
psf->file.mode = SFM_RDWR ;
test_open_or_die (psf, __LINE__) ;
test_close_or_die (psf, __LINE__) ;
unlink (psf->filename) ;
unlink (psf->file.path.c) ;
puts ("ok") ;
} /* file_open_test */
@@ -121,17 +123,17 @@ file_read_write_test (const char *filename)
memset (&sf_data, 0, sizeof (sf_data)) ;
psf = &sf_data ;
snprintf (psf->filename, sizeof (psf->filename), "%s", filename) ;
snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
/* Test file open in write mode. */
psf->mode = SFM_WRITE ;
psf->file.mode = SFM_WRITE ;
test_open_or_die (psf, __LINE__) ;
make_data (data_out, ARRAY_LEN (data_out), 1) ;
test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), sizeof (data_out), __LINE__) ;
if ((retval = psf_get_filelen (psf)) != sizeof (data_out))
{ printf ("\n\nLine %d: file length after write is not correct (%ld should be %d).\n\n", __LINE__, (long) retval, (int) sizeof (data_out)) ;
{ printf ("\n\nLine %d: file length after write is not correct (%" PRId64 " should be %zd).\n\n", __LINE__, retval, sizeof (data_out)) ;
if (retval == 0)
printf ("An fsync() may be necessary before fstat() in psf_get_filelen().\n\n") ;
exit (1) ;
@@ -141,7 +143,7 @@ file_read_write_test (const char *filename)
test_write_or_die (psf, data_out, ARRAY_LEN (data_out), sizeof (data_out [0]), 2 * sizeof (data_out), __LINE__) ;
if ((retval = psf_get_filelen (psf)) != 2 * sizeof (data_out))
{ printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 2 * ((int) sizeof (data_out))) ;
{ printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %zd)\n\n", __LINE__, retval, 2 * sizeof (data_out)) ;
exit (1) ;
} ;
@@ -156,7 +158,7 @@ file_read_write_test (const char *filename)
print_test_name ("Testing file read") ;
/* Test file open in write mode. */
psf->mode = SFM_READ ;
psf->file.mode = SFM_READ ;
test_open_or_die (psf, __LINE__) ;
make_data (data_out, ARRAY_LEN (data_out), 1) ;
@@ -180,7 +182,7 @@ file_read_write_test (const char *filename)
print_test_name ("Testing file seek") ;
/* Test file open in read/write mode. */
psf->mode = SFM_RDWR ;
psf->file.mode = SFM_RDWR ;
test_open_or_die (psf, __LINE__) ;
test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ;
@@ -218,12 +220,12 @@ file_read_write_test (const char *filename)
print_test_name ("Testing file offset") ;
/* Test file open in read/write mode. */
psf->mode = SFM_RDWR ;
psf->file.mode = SFM_RDWR ;
psf->fileoffset = sizeof (data_out [0]) * ARRAY_LEN (data_out) ;
test_open_or_die (psf, __LINE__) ;
if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out))
{ printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ;
{ printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %zd)\n\n", __LINE__, retval, 3 * sizeof (data_out)) ;
exit (1) ;
} ;
@@ -234,12 +236,12 @@ file_read_write_test (const char *filename)
/* final test with psf->fileoffset == 0. */
psf->mode = SFM_RDWR ;
psf->file.mode = SFM_RDWR ;
psf->fileoffset = 0 ;
test_open_or_die (psf, __LINE__) ;
if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out))
{ printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ;
{ printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %zd)\n\n", __LINE__, retval, 3 * sizeof (data_out)) ;
exit (1) ;
} ;
@@ -277,20 +279,20 @@ file_truncate_test (const char *filename)
memset (buffer, 0xEE, sizeof (buffer)) ;
psf = &sf_data ;
snprintf (psf->filename, sizeof (psf->filename), "%s", filename) ;
snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ;
/*
** Open the file write mode, write 0xEE data and then extend the file
** using truncate (the extended data should be 0x00).
*/
psf->mode = SFM_WRITE ;
psf->file.mode = SFM_WRITE ;
test_open_or_die (psf, __LINE__) ;
test_write_or_die (psf, buffer, sizeof (buffer) / 2, 1, sizeof (buffer) / 2, __LINE__) ;
psf_ftruncate (psf, sizeof (buffer)) ;
test_close_or_die (psf, __LINE__) ;
/* Open the file in read mode and check the data. */
psf->mode = SFM_READ ;
psf->file.mode = SFM_READ ;
test_open_or_die (psf, __LINE__) ;
test_read_or_die (psf, buffer, sizeof (buffer), 1, sizeof (buffer), __LINE__) ;
test_close_or_die (psf, __LINE__) ;
@@ -308,13 +310,13 @@ file_truncate_test (const char *filename)
} ;
/* Open the file in read/write and shorten the file using truncate. */
psf->mode = SFM_RDWR ;
psf->file.mode = SFM_RDWR ;
test_open_or_die (psf, __LINE__) ;
psf_ftruncate (psf, sizeof (buffer) / 4) ;
test_close_or_die (psf, __LINE__) ;
/* Check the file length. */
psf->mode = SFM_READ ;
psf->file.mode = SFM_READ ;
test_open_or_die (psf, __LINE__) ;
test_seek_or_die (psf, 0, SEEK_END, SIGNED_SIZEOF (buffer) / 4, __LINE__) ;
test_close_or_die (psf, __LINE__) ;
@@ -331,7 +333,7 @@ test_open_or_die (SF_PRIVATE *psf, int linenum)
{ int error ;
/* Test that open for read fails if the file doesn't exist. */
error = psf_fopen (psf, psf->filename, psf->mode) ;
error = psf_fopen (psf) ;
if (error)
{ printf ("\n\nLine %d: psf_fopen() failed : %s\n\n", linenum, strerror (errno)) ;
exit (1) ;
@@ -344,7 +346,7 @@ test_close_or_die (SF_PRIVATE *psf, int linenum)
{
psf_fclose (psf) ;
if (psf_file_valid (psf))
{ printf ("\n\nLine %d: psf->filedes should not be valid.\n\n", linenum) ;
{ printf ("\n\nLine %d: psf->file.filedes should not be valid.\n\n", linenum) ;
exit (1) ;
} ;
@@ -356,12 +358,12 @@ test_write_or_die (SF_PRIVATE *psf, void *data, sf_count_t bytes, sf_count_t ite
retval = psf_fwrite (data, bytes, items, psf) ;
if (retval != items)
{ printf ("\n\nLine %d: psf_write() returned %ld (should be %ld)\n\n", linenum, (long) retval, (long) items) ;
{ printf ("\n\nLine %d: psf_write() returned %" PRId64 " (should be %" PRId64 ")\n\n", linenum, retval, items) ;
exit (1) ;
} ;
if ((retval = psf_ftell (psf)) != new_position)
{ printf ("\n\nLine %d: file length after write is not correct. (%ld should be %ld)\n\n", linenum, (long) retval, (long) new_position) ;
{ printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %" PRId64 ")\n\n", linenum, retval, new_position) ;
exit (1) ;
} ;
@@ -374,12 +376,12 @@ test_read_or_die (SF_PRIVATE *psf, void *data, sf_count_t bytes, sf_count_t item
retval = psf_fread (data, bytes, items, psf) ;
if (retval != items)
{ printf ("\n\nLine %d: psf_write() returned %ld (should be %ld)\n\n", linenum, (long) retval, (long) items) ;
{ printf ("\n\nLine %d: psf_write() returned %" PRId64 " (should be %" PRId64 ")\n\n", linenum, retval, items) ;
exit (1) ;
} ;
if ((retval = psf_ftell (psf)) != new_position)
{ printf ("\n\nLine %d: file length after write is not correct. (%ld should be %ld)\n\n", linenum, (long) retval, (long) new_position) ;
{ printf ("\n\nLine %d: file length after write is not correct. (%" PRId64 " should be %" PRId64 ")\n\n", linenum, retval, new_position) ;
exit (1) ;
} ;
@@ -393,8 +395,8 @@ test_seek_or_die (SF_PRIVATE *psf, sf_count_t offset, int whence, sf_count_t new
retval = psf_fseek (psf, offset, whence) ;
if (retval != new_position)
{ printf ("\n\nLine %d: psf_fseek() failed. New position is %ld (should be %ld).\n\n",
linenum, (long) retval, (long) new_position) ;
{ printf ("\n\nLine %d: psf_fseek() failed. New position is %" PRId64 " (should be %" PRId64 ").\n\n",
linenum, retval, new_position) ;
exit (1) ;
} ;
+3 -3
View File
@@ -1,5 +1,5 @@
/*
** Copyright (C) 2006-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2006-2012 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as published by
@@ -48,7 +48,7 @@ test_float_convert (void)
test = float32_le_read (bytes) ;
if (fabs (data [k] - test) > 1e-20)
{ printf ("\n\nLine %d : Test %d, little endian error %.15g -> %.15g.\n\n", __LINE__, k, data [k], test ) ;
{ printf ("\n\nLine %d : Test %d, little endian error %.15g -> %.15g.\n\n", __LINE__, k, data [k], test) ;
exit (1) ;
} ;
@@ -85,7 +85,7 @@ test_double_convert (void)
test = double64_le_read (bytes) ;
if (fabs (data [k] - test) > 1e-20)
{ printf ("\n\nLine %d : Test %d, little endian error %.15g -> %.15g.\n\n", __LINE__, k, data [k], test ) ;
{ printf ("\n\nLine %d : Test %d, little endian error %.15g -> %.15g.\n\n", __LINE__, k, data [k], test) ;
exit (1) ;
} ;
+4 -2
View File
@@ -1,6 +1,6 @@
/*
** Copyright (C) 2007-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (c) 2007 <robs@users.sourceforge.net>
** Copyright (C) 2007-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** This library is free software; you can redistribute it and/or modify it
** under the terms of the GNU Lesser General Public License as published by
@@ -17,6 +17,8 @@
** Fifth Floor, 51 Franklin Street, Boston, MA 02111-1301, USA.
*/
#include "sfconfig.h"
#include <stdio.h>
#include "test_main.h"
@@ -71,7 +73,7 @@ test_oki_adpcm (void)
print_test_name ("Testing ima/oki decoder") ;
ima_oki_adpcm_init (&adpcm, IMA_OKI_ADPCM_TYPE_OKI) ;
for (i = 0 ; i < ARRAY_LEN (test_pcm) - 1 ; i += j)
for (i = 0 ; i < ARRAY_LEN (test_pcm) - 1 ; i += 2)
{ code = adpcm_encode (&adpcm, test_pcm [i]) ;
code = (code << 4) | adpcm_encode (&adpcm, test_pcm [i + 1]) ;
if (code != test_codes [i / 2])
Loaded 100 of 291 files, more files were not shown because too many files have changed in this diff. Show more