Skip to content

Commit

Permalink
Refactor audio conversion.
Browse files Browse the repository at this point in the history
  • Loading branch information
mpruett committed Nov 15, 2010
1 parent 5843091 commit 2bbebc4
Show file tree
Hide file tree
Showing 49 changed files with 3,356 additions and 5,122 deletions.
4 changes: 4 additions & 0 deletions ChangeLog
@@ -1,3 +1,7 @@
2010-11-14 Michael Pruett <michael@68k.org>

Refactor audio conversion.

2010-11-14 Michael Pruett <michael@68k.org>

Refactor file I/O.
Expand Down
119 changes: 119 additions & 0 deletions libaudiofile/AudioFormat.cpp
@@ -0,0 +1,119 @@
#include "afinternal.h"
#include "byteorder.h"
#include "compression.h"
#include "units.h"
#include "util.h"
#include <assert.h>

size_t _AudioFormat::bytesPerSample(bool stretch3to4) const
{
return _af_format_sample_size_uncompressed(this, stretch3to4);
}

size_t _AudioFormat::bytesPerFrame(bool stretch3to4) const
{
return _af_format_frame_size_uncompressed(this, stretch3to4);
}

size_t _AudioFormat::bytesPerSample() const
{
return bytesPerSample(!isPacked());
}

size_t _AudioFormat::bytesPerFrame() const
{
return bytesPerFrame(!isPacked());
}

bool _AudioFormat::isInteger() const
{
return sampleFormat == AF_SAMPFMT_TWOSCOMP ||
sampleFormat == AF_SAMPFMT_UNSIGNED;
}

bool _AudioFormat::isSigned() const
{
return sampleFormat == AF_SAMPFMT_TWOSCOMP;
}

bool _AudioFormat::isUnsigned() const
{
return sampleFormat == AF_SAMPFMT_UNSIGNED;
}

bool _AudioFormat::isFloat() const
{
return sampleFormat == AF_SAMPFMT_FLOAT ||
sampleFormat == AF_SAMPFMT_DOUBLE;
}

bool _AudioFormat::isCompressed() const
{
return compressionType != AF_COMPRESSION_NONE;
}

bool _AudioFormat::isUncompressed() const
{
return compressionType == AF_COMPRESSION_NONE;
}

std::string _AudioFormat::description() const
{
std::string d;
char s[1024];
/* sampleRate, channelCount */
sprintf(s, "{ %7.2f Hz %d ch ", sampleRate, channelCount);
d += s;

/* sampleFormat, sampleWidth */
switch (sampleFormat)
{
case AF_SAMPFMT_TWOSCOMP:
sprintf(s, "%db 2 ", sampleWidth);
break;
case AF_SAMPFMT_UNSIGNED:
sprintf(s, "%db u ", sampleWidth);
break;
case AF_SAMPFMT_FLOAT:
sprintf(s, "flt ");
break;
case AF_SAMPFMT_DOUBLE:
sprintf(s, "dbl ");
break;
default:
assert(false);
break;
}

d += s;

/* pcm */
sprintf(s, "(%.30g+-%.30g [%.30g,%.30g]) ",
pcm.intercept, pcm.slope,
pcm.minClip, pcm.maxClip);
d += s;

/* byteOrder */
switch (byteOrder)
{
case AF_BYTEORDER_BIGENDIAN:
d += "big ";
break;
case AF_BYTEORDER_LITTLEENDIAN:
d += "little ";
break;
default:
assert(false);
break;
}

if (isCompressed())
{
int compressionIndex = _af_compression_index_from_id(compressionType);
assert(compressionIndex >= 0);
d += "compression: ";
d += _af_compression[compressionIndex].label;
}

return d;
}
9 changes: 5 additions & 4 deletions libaudiofile/Makefile.am
Expand Up @@ -7,10 +7,10 @@ lib_LTLIBRARIES = libaudiofile.la
EXTRA_DIST = audiofile.exports

libaudiofile_la_SOURCES = \
openclose.cpp setup.c format.c data.c pcm.c \
openclose.cpp setup.c format.cpp data.cpp pcm.cpp \
error.c byteorder.h af_vfs.cpp \
util.cpp util.h debug.c aupv.c units.c compression.c \
aes.c instrument.c loop.c marker.c misc.c track.c query.c \
aes.c instrument.c loop.c marker.c misc.c track.cpp query.c \
raw.c raw.h \
aiff.c aiffwrite.c extended.c aiff.h \
next.c nextwrite.c next.h \
Expand All @@ -24,8 +24,8 @@ libaudiofile_la_SOURCES = \
compression.h error.h extended.h instrument.h marker.h \
pcm.h setup.h track.h units.h \
print.h util.h debug.h \
modules.c modules.h \
File.cpp File.h Shared.h
File.cpp File.h Shared.h \
AudioFormat.cpp

libaudiofile_la_LIBADD = modules/libmodules.la $(COVERAGE_LIBS)

Expand All @@ -40,3 +40,4 @@ include_HEADERS = audiofile.h aupvlist.h af_vfs.h
# AM_CFLAGS = -fullwarn -g
# No debugging.
AM_CFLAGS = -DNDEBUG -Wall $(COVERAGE_CFLAGS)
AM_CXXFLAGS = $(AM_CFLAGS) -fno-rtti -fno-exceptions
10 changes: 10 additions & 0 deletions libaudiofile/Shared.h
Expand Up @@ -72,6 +72,16 @@ class SharedPtr
if (T *p = m_ptr) p->release();
}

SharedPtr &operator =(T *ptr)
{
if (m_ptr != ptr)
{
if (ptr) ptr->retain();
if (m_ptr) m_ptr->release();
m_ptr = ptr;
}
return *this;
}
SharedPtr &operator =(const SharedPtr &p)
{
if (m_ptr != p.m_ptr)
Expand Down
107 changes: 24 additions & 83 deletions libaudiofile/afinternal.h
Expand Up @@ -39,6 +39,8 @@
#include "error.h"

#ifdef __cplusplus
#include <string>

extern "C" {
#endif

Expand Down Expand Up @@ -107,92 +109,27 @@ typedef struct _AudioFormat

int compressionType; /* AF_COMPRESSION_... */
void *compressionParams; /* NULL if no compression */
} _AudioFormat;

/* modules */
struct _AFmoduleinst;
struct _AFchunk;

typedef void (*_AFfnpmod) (struct _AFmoduleinst *i);
typedef void (*_AFfnpsimplemod) (struct _AFchunk *inc,
struct _AFchunk *outc, void *modspec);

typedef struct _AFmodule
{
char *name;
_AFfnpmod describe;
_AFfnpmod max_pull;
_AFfnpmod max_push;
_AFfnpmod run_pull;
_AFfnpmod reset1;
_AFfnpmod reset2;
_AFfnpmod run_push;
_AFfnpmod sync1;
_AFfnpmod sync2;
_AFfnpsimplemod run;
_AFfnpmod free;
} _AFmodule;

typedef struct _AFchunk
{
void *buf; /* chunk data */
AFframecount nframes; /* # of frames in chunk */
_AudioFormat f; /* format of data in chunk */
} _AFchunk;
bool packed : 1;

typedef struct _AFmoduleinst
{
_AFchunk *inc, *outc;
void *modspec;
union
{
struct { struct _AFmoduleinst *source; } pull;
struct { struct _AFmoduleinst *sink; } push;
} u;
const _AFmodule *mod;
bool free_on_close; /* true=don't free module until close */
bool valid; /* internal use only */
#ifdef AF_DEBUG /* these are set in _AFsetupmodules */
int margin; /* margin for printing of CHNK messages */
bool dump; /* whether to dump chunks */
#ifdef __cplusplus
size_t bytesPerSample(bool stretch3to4) const;
size_t bytesPerFrame(bool stretch3to4) const;
size_t bytesPerSample() const;
size_t bytesPerFrame() const;
bool isInteger() const;
bool isSigned() const;
bool isUnsigned() const;
bool isFloat() const;
bool isCompressed() const;
bool isUncompressed() const;
bool isPacked() const { return packed; }
std::string description() const;
#endif
} _AFmoduleinst;

/* information private to module routines */
typedef struct _AFmodulestate
{
bool modulesdirty;
int nmodules;

/* See comment at very end of arrangemodules(). */
bool mustuseatomicnvframes;

/* previous rates before user changed them */
double old_f_rate, old_v_rate;

_AFchunk *chunk;
_AFmoduleinst *module;

/* array of pointers to buffers, one for each module */
void **buffer;

/* These modules have extended lifetimes. */

/* file read / write */
_AFmoduleinst filemodinst;

/* file module's rebuffer */
_AFmoduleinst filemod_rebufferinst;

/* rate conversion */
_AFmoduleinst rateconvertinst;

/* old rates */
double rateconvert_inrate, rateconvert_outrate;
} _AudioFormat;

/* rate conversion's rebuffer */
_AFmoduleinst rateconvert_rebufferinst;
} _AFmodulestate;
typedef struct Module Module;
typedef struct ModuleState ModuleState;

typedef struct _Track
{
Expand All @@ -218,12 +155,16 @@ typedef struct _Track
AFframecount nextvframe;
AFfileoffset data_size; /* trackBytes */

_AFmodulestate ms;
ModuleState *ms;

double taper, dynamic_range;
bool ratecvt_filter_params_set;

bool filemodhappy;

#ifdef __cplusplus
void print();
#endif
} _Track;

typedef struct _TrackSetup
Expand Down
1 change: 0 additions & 1 deletion libaudiofile/audiofile.exports
Expand Up @@ -71,7 +71,6 @@ afNewFileSetup
afOpenFD
afOpenFile
afOpenNamedFD
afOpenVirtualFile
afQuery
afQueryDouble
afQueryLong
Expand Down
47 changes: 33 additions & 14 deletions libaudiofile/byteorder.h
Expand Up @@ -90,20 +90,32 @@

#endif

static inline uint16_t _af_byteswap_int16 (uint16_t x)
inline uint16_t _af_byteswap_int16 (uint16_t x)
{
return (x >> 8) | (x << 8);
}

static inline uint32_t _af_byteswap_int32 (uint32_t x)
inline uint32_t _af_byteswap_int32 (uint32_t x)
{
return ((x & 0x000000ffU) << 24) |
((x & 0x0000ff00U) << 8) |
((x & 0x00ff0000U) >> 8) |
((x & 0xff000000U) >> 24);
}

static inline float _af_byteswap_float32 (float x)
inline uint64_t _af_byteswap_int64 (uint64_t x)
{
return ((x & 0x00000000000000ffULL) << 56) |
((x & 0x000000000000ff00ULL) << 40) |
((x & 0x0000000000ff0000ULL) << 24) |
((x & 0x00000000ff000000ULL) << 8) |
((x & 0x000000ff00000000ULL) >> 8) |
((x & 0x0000ff0000000000ULL) >> 24) |
((x & 0x00ff000000000000ULL) >> 40) |
((x & 0xff00000000000000ULL) >> 56);
}

inline float _af_byteswap_float32 (float x)
{
union
{
Expand All @@ -115,19 +127,26 @@ static inline float _af_byteswap_float32 (float x)
return u.f;
}

inline double _af_byteswap_float64 (double x)
{
union
{
uint64_t i;
double f;
} u;
u.f = x;
u.i = _af_byteswap_int64(u.i);
return u.f;
}

#ifdef __cplusplus

template <typename T>
T byteswap(T value);

template <>
uint32_t byteswap(uint32_t value) { return _af_byteswap_int32(value); }
template <>
int32_t byteswap(int32_t value) { return _af_byteswap_int32(value); }
template <>
uint16_t byteswap(uint16_t value) { return _af_byteswap_int16(value); }
template <>
int16_t byteswap(int16_t value) { return _af_byteswap_int16(value); }
inline uint64_t byteswap(uint64_t value) { return _af_byteswap_int64(value); }
inline int64_t byteswap(int64_t value) { return _af_byteswap_int64(value); }
inline uint32_t byteswap(uint32_t value) { return _af_byteswap_int32(value); }
inline int32_t byteswap(int32_t value) { return _af_byteswap_int32(value); }
inline uint16_t byteswap(uint16_t value) { return _af_byteswap_int16(value); }
inline int16_t byteswap(int16_t value) { return _af_byteswap_int16(value); }

template <typename T>
T bigToHost(T value)
Expand Down

0 comments on commit 2bbebc4

Please sign in to comment.