3D Audio GSoC:
- Converting AUD_SampleRate to a double - Removing AUD_DefaultMixer - Introducing AUD_ResampleReader as base class for all resampling readers.
This commit is contained in:
@@ -82,8 +82,6 @@ set(SRC
|
|||||||
intern/AUD_ConverterFunctions.h
|
intern/AUD_ConverterFunctions.h
|
||||||
intern/AUD_ConverterReader.cpp
|
intern/AUD_ConverterReader.cpp
|
||||||
intern/AUD_ConverterReader.h
|
intern/AUD_ConverterReader.h
|
||||||
intern/AUD_DefaultMixer.cpp
|
|
||||||
intern/AUD_DefaultMixer.h
|
|
||||||
intern/AUD_FileFactory.cpp
|
intern/AUD_FileFactory.cpp
|
||||||
intern/AUD_FileFactory.h
|
intern/AUD_FileFactory.h
|
||||||
intern/AUD_I3DDevice.h
|
intern/AUD_I3DDevice.h
|
||||||
@@ -108,6 +106,8 @@ set(SRC
|
|||||||
intern/AUD_Reference.h
|
intern/AUD_Reference.h
|
||||||
intern/AUD_ReferenceHandler.cpp
|
intern/AUD_ReferenceHandler.cpp
|
||||||
intern/AUD_ResampleFactory.h
|
intern/AUD_ResampleFactory.h
|
||||||
|
intern/AUD_ResampleReader.cpp
|
||||||
|
intern/AUD_ResampleReader.h
|
||||||
intern/AUD_SequencerFactory.cpp
|
intern/AUD_SequencerFactory.cpp
|
||||||
intern/AUD_SequencerFactory.h
|
intern/AUD_SequencerFactory.h
|
||||||
intern/AUD_SequencerReader.cpp
|
intern/AUD_SequencerReader.cpp
|
||||||
|
@@ -39,6 +39,6 @@ AUD_PitchReader::AUD_PitchReader(AUD_Reference<AUD_IReader> reader, float pitch)
|
|||||||
AUD_Specs AUD_PitchReader::getSpecs() const
|
AUD_Specs AUD_PitchReader::getSpecs() const
|
||||||
{
|
{
|
||||||
AUD_Specs specs = m_reader->getSpecs();
|
AUD_Specs specs = m_reader->getSpecs();
|
||||||
specs.rate = (AUD_SampleRate)((int)(specs.rate * m_pitch));
|
specs.rate *= m_pitch;
|
||||||
return specs;
|
return specs;
|
||||||
}
|
}
|
||||||
|
@@ -2111,13 +2111,13 @@ Device_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||||||
|
|
||||||
static const char *kwlist[] = {"type", "rate", "channels", "format", "buffer_size", "name", NULL};
|
static const char *kwlist[] = {"type", "rate", "channels", "format", "buffer_size", "name", NULL};
|
||||||
int device;
|
int device;
|
||||||
int rate = AUD_RATE_44100;
|
double rate = AUD_RATE_44100;
|
||||||
int channels = AUD_CHANNELS_STEREO;
|
int channels = AUD_CHANNELS_STEREO;
|
||||||
int format = AUD_FORMAT_FLOAT32;
|
int format = AUD_FORMAT_FLOAT32;
|
||||||
int buffersize = AUD_DEFAULT_BUFFER_SIZE;
|
int buffersize = AUD_DEFAULT_BUFFER_SIZE;
|
||||||
const char* name = "Audaspace";
|
const char* name = "Audaspace";
|
||||||
|
|
||||||
if(!PyArg_ParseTupleAndKeywords(args, kwds, "i|iiiis:Device", const_cast<char**>(kwlist),
|
if(!PyArg_ParseTupleAndKeywords(args, kwds, "i|diiis:Device", const_cast<char**>(kwlist),
|
||||||
&device, &rate, &channels, &format, &buffersize, &name))
|
&device, &rate, &channels, &format, &buffersize, &name))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@@ -45,8 +45,7 @@ static const char* state_error = "AUD_SRCResampleReader: SRC State couldn't be "
|
|||||||
|
|
||||||
AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader,
|
AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader,
|
||||||
AUD_Specs specs) :
|
AUD_Specs specs) :
|
||||||
AUD_EffectReader(reader),
|
AUD_ResampleReader(reader, specs.rate),
|
||||||
m_rate(specs.rate),
|
|
||||||
m_channels(reader->getSpecs().channels),
|
m_channels(reader->getSpecs().channels),
|
||||||
m_position(0)
|
m_position(0)
|
||||||
{
|
{
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
#ifndef AUD_SRCRESAMPLEREADER
|
#ifndef AUD_SRCRESAMPLEREADER
|
||||||
#define AUD_SRCRESAMPLEREADER
|
#define AUD_SRCRESAMPLEREADER
|
||||||
|
|
||||||
#include "AUD_EffectReader.h"
|
#include "AUD_ResampleReader.h"
|
||||||
#include "AUD_Buffer.h"
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
#include <samplerate.h>
|
#include <samplerate.h>
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
/**
|
/**
|
||||||
* This resampling reader uses libsamplerate for resampling.
|
* This resampling reader uses libsamplerate for resampling.
|
||||||
*/
|
*/
|
||||||
class AUD_SRCResampleReader : public AUD_EffectReader
|
class AUD_SRCResampleReader : public AUD_ResampleReader
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
@@ -48,11 +48,6 @@ private:
|
|||||||
*/
|
*/
|
||||||
AUD_Buffer m_buffer;
|
AUD_Buffer m_buffer;
|
||||||
|
|
||||||
/**
|
|
||||||
* The target sampling rate.
|
|
||||||
*/
|
|
||||||
AUD_SampleRate m_rate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The reader channels.
|
* The reader channels.
|
||||||
*/
|
*/
|
||||||
|
@@ -795,7 +795,7 @@ void AUD_closeReadDevice(AUD_Device* device)
|
|||||||
float* AUD_readSoundBuffer(const char* filename, float low, float high,
|
float* AUD_readSoundBuffer(const char* filename, float low, float high,
|
||||||
float attack, float release, float threshold,
|
float attack, float release, float threshold,
|
||||||
int accumulate, int additive, int square,
|
int accumulate, int additive, int square,
|
||||||
float sthreshold, int samplerate, int* length)
|
float sthreshold, double samplerate, int* length)
|
||||||
{
|
{
|
||||||
AUD_Buffer buffer;
|
AUD_Buffer buffer;
|
||||||
AUD_DeviceSpecs specs;
|
AUD_DeviceSpecs specs;
|
||||||
|
@@ -441,7 +441,7 @@ extern void AUD_closeReadDevice(AUD_Device* device);
|
|||||||
extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
|
extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
|
||||||
float attack, float release, float threshold,
|
float attack, float release, float threshold,
|
||||||
int accumulate, int additive, int square,
|
int accumulate, int additive, int square,
|
||||||
float sthreshold, int samplerate,
|
float sthreshold, double samplerate,
|
||||||
int* length);
|
int* length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -38,8 +38,7 @@
|
|||||||
|
|
||||||
AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_Reference<AUD_IReader> reader,
|
AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_Reference<AUD_IReader> reader,
|
||||||
AUD_Specs specs) :
|
AUD_Specs specs) :
|
||||||
AUD_EffectReader(reader),
|
AUD_ResampleReader(reader, specs.rate),
|
||||||
m_rate(specs.rate),
|
|
||||||
m_channels(reader->getSpecs().channels),
|
m_channels(reader->getSpecs().channels),
|
||||||
m_position(0),
|
m_position(0),
|
||||||
m_cache_pos(0),
|
m_cache_pos(0),
|
||||||
|
@@ -32,20 +32,15 @@
|
|||||||
#ifndef AUD_LINEARRESAMPLEREADER
|
#ifndef AUD_LINEARRESAMPLEREADER
|
||||||
#define AUD_LINEARRESAMPLEREADER
|
#define AUD_LINEARRESAMPLEREADER
|
||||||
|
|
||||||
#include "AUD_EffectReader.h"
|
#include "AUD_ResampleReader.h"
|
||||||
#include "AUD_Buffer.h"
|
#include "AUD_Buffer.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This resampling reader uses libsamplerate for resampling.
|
* This resampling reader uses libsamplerate for resampling.
|
||||||
*/
|
*/
|
||||||
class AUD_LinearResampleReader : public AUD_EffectReader
|
class AUD_LinearResampleReader : public AUD_ResampleReader
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/**
|
|
||||||
* The target specification.
|
|
||||||
*/
|
|
||||||
AUD_SampleRate m_rate;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The reader channels.
|
* The reader channels.
|
||||||
*/
|
*/
|
||||||
|
@@ -81,13 +81,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
AUD_DeviceSpecs getSpecs() const;
|
AUD_DeviceSpecs getSpecs() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* This funuction prepares a reader for playback.
|
|
||||||
* \param reader The reader to prepare.
|
|
||||||
* \return The reader that should be used for playback.
|
|
||||||
*/
|
|
||||||
virtual AUD_Reference<AUD_IReader> prepare(AUD_Reference<AUD_IReader> reader)=0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mixes a buffer.
|
* Mixes a buffer.
|
||||||
* \param buffer The buffer to superpose.
|
* \param buffer The buffer to superpose.
|
||||||
@@ -95,20 +88,20 @@ public:
|
|||||||
* \param length The length of the buffer in samples.
|
* \param length The length of the buffer in samples.
|
||||||
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
||||||
*/
|
*/
|
||||||
virtual void mix(sample_t* buffer, int start, int length, float volume);
|
void mix(sample_t* buffer, int start, int length, float volume);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the mixing buffer into an output buffer.
|
* Writes the mixing buffer into an output buffer.
|
||||||
* \param buffer The target buffer for superposing.
|
* \param buffer The target buffer for superposing.
|
||||||
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
|
||||||
*/
|
*/
|
||||||
virtual void read(data_t* buffer, float volume);
|
void read(data_t* buffer, float volume);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the mixing buffer.
|
* Clears the mixing buffer.
|
||||||
* \param length The length of the buffer in samples.
|
* \param length The length of the buffer in samples.
|
||||||
*/
|
*/
|
||||||
virtual void clear(int length);
|
void clear(int length);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //AUD_MIXER
|
#endif //AUD_MIXER
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "AUD_DefaultMixer.h"
|
|
||||||
#include "AUD_ReadDevice.h"
|
#include "AUD_ReadDevice.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
|
|
||||||
|
@@ -24,38 +24,24 @@
|
|||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \file audaspace/intern/AUD_DefaultMixer.cpp
|
/** \file audaspace/intern/AUD_ResampleReader.cpp
|
||||||
* \ingroup audaspaceintern
|
* \ingroup audaspaceintern
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "AUD_DefaultMixer.h"
|
#include "AUD_ResampleReader.h"
|
||||||
#ifdef WITH_SAMPLERATE
|
|
||||||
#include "AUD_SRCResampleReader.h"
|
|
||||||
#else
|
|
||||||
#include "AUD_LinearResampleReader.h"
|
|
||||||
#endif
|
|
||||||
#include "AUD_ChannelMapperReader.h"
|
|
||||||
#include "AUD_ChannelMapperFactory.h"
|
|
||||||
|
|
||||||
#include <cstring>
|
AUD_ResampleReader::AUD_ResampleReader(AUD_Reference<AUD_IReader> reader, AUD_SampleRate rate) :
|
||||||
|
AUD_EffectReader(reader), m_rate(rate)
|
||||||
AUD_DefaultMixer::AUD_DefaultMixer(AUD_DeviceSpecs specs) :
|
|
||||||
AUD_Mixer(specs)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
AUD_Reference<AUD_IReader> AUD_DefaultMixer::prepare(AUD_Reference<AUD_IReader> reader)
|
void AUD_ResampleReader::setRate(AUD_SampleRate rate)
|
||||||
{
|
{
|
||||||
// resample
|
m_rate = rate;
|
||||||
#ifdef WITH_SAMPLERATE
|
}
|
||||||
reader = new AUD_SRCResampleReader(reader, m_specs.specs);
|
|
||||||
#else
|
AUD_SampleRate AUD_ResampleReader::getRate()
|
||||||
reader = new AUD_LinearResampleReader(reader, m_specs.specs);
|
{
|
||||||
#endif
|
return m_rate;
|
||||||
|
|
||||||
// rechannel
|
|
||||||
reader = new AUD_ChannelMapperReader(reader, m_specs.channels);
|
|
||||||
|
|
||||||
return reader;
|
|
||||||
}
|
}
|
@@ -24,36 +24,28 @@
|
|||||||
* ***** END GPL LICENSE BLOCK *****
|
* ***** END GPL LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** \file audaspace/intern/AUD_DefaultMixer.h
|
/** \file audaspace/intern/AUD_ResampleReader.h
|
||||||
* \ingroup audaspaceintern
|
* \ingroup audaspaceintern
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef AUD_RESAMPLEREADER
|
||||||
|
#define AUD_RESAMPLEREADER
|
||||||
|
|
||||||
#ifndef AUD_DEFAULTMIXER
|
#include "AUD_EffectReader.h"
|
||||||
#define AUD_DEFAULTMIXER
|
|
||||||
|
|
||||||
#include "AUD_Mixer.h"
|
class AUD_ResampleReader : public AUD_EffectReader
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is able to mix audiosignals of different channel count and sample
|
|
||||||
* rate and convert it to a specific output format.
|
|
||||||
* It uses a default ChannelMapperFactory and a SRCResampleFactory for
|
|
||||||
* the perparation.
|
|
||||||
*/
|
|
||||||
class AUD_DefaultMixer : public AUD_Mixer
|
|
||||||
{
|
{
|
||||||
public:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Creates the mixer.
|
* The target sampling rate.
|
||||||
*/
|
*/
|
||||||
AUD_DefaultMixer(AUD_DeviceSpecs specs);
|
AUD_SampleRate m_rate;
|
||||||
|
|
||||||
/**
|
AUD_ResampleReader(AUD_Reference<AUD_IReader> reader, AUD_SampleRate rate);
|
||||||
* This funuction prepares a reader for playback.
|
|
||||||
* \param reader The reader to prepare.
|
public:
|
||||||
* \return The reader that should be used for playback.
|
virtual void setRate(AUD_SampleRate rate);
|
||||||
*/
|
AUD_SampleRate getRate();
|
||||||
virtual AUD_Reference<AUD_IReader> prepare(AUD_Reference<AUD_IReader> reader);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //AUD_DEFAULTMIXER
|
#endif // AUD_RESAMPLEREADER
|
@@ -30,7 +30,14 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "AUD_SequencerReader.h"
|
#include "AUD_SequencerReader.h"
|
||||||
#include "AUD_DefaultMixer.h"
|
#include "AUD_Mixer.h"
|
||||||
|
|
||||||
|
#ifdef WITH_SAMPLERATE
|
||||||
|
#include "AUD_SRCResampleReader.h"
|
||||||
|
#else
|
||||||
|
#include "AUD_LinearResampleReader.h"
|
||||||
|
#endif
|
||||||
|
#include "AUD_ChannelMapperReader.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@@ -46,7 +53,7 @@ AUD_SequencerReader::AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> fac
|
|||||||
dspecs.specs = specs;
|
dspecs.specs = specs;
|
||||||
dspecs.format = AUD_FORMAT_FLOAT32;
|
dspecs.format = AUD_FORMAT_FLOAT32;
|
||||||
|
|
||||||
m_mixer = new AUD_DefaultMixer(dspecs);
|
m_mixer = new AUD_Mixer(dspecs);
|
||||||
|
|
||||||
AUD_Reference<AUD_SequencerStrip> strip;
|
AUD_Reference<AUD_SequencerStrip> strip;
|
||||||
|
|
||||||
@@ -139,7 +146,16 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
strip->reader = m_mixer->prepare((*strip->old_sound)->createReader());
|
strip->reader = (*strip->old_sound)->createReader();
|
||||||
|
// resample
|
||||||
|
#ifdef WITH_SAMPLERATE
|
||||||
|
strip->reader = new AUD_SRCResampleReader(strip->reader, m_mixer->getSpecs().specs);
|
||||||
|
#else
|
||||||
|
strip->reader = new AUD_LinearResampleReader(strip->reader, m_mixer->getSpecs().specs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// rechannel
|
||||||
|
strip->reader = new AUD_ChannelMapperReader(strip->reader, m_mixer->getSpecs().channels);
|
||||||
}
|
}
|
||||||
catch(AUD_Exception)
|
catch(AUD_Exception)
|
||||||
{
|
{
|
||||||
|
@@ -77,8 +77,7 @@ void AUD_SinusReader::read(int& length, bool& eos, sample_t* buffer)
|
|||||||
// fill with sine data
|
// fill with sine data
|
||||||
for(int i = 0; i < length; i++)
|
for(int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
buffer[i] = sin((m_position + i) * 2 * M_PI * m_frequency /
|
buffer[i] = sin((m_position + i) * 2 * M_PI * m_frequency / m_sampleRate);
|
||||||
(float)m_sampleRate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_position += length;
|
m_position += length;
|
||||||
|
@@ -31,8 +31,14 @@
|
|||||||
|
|
||||||
#include "AUD_SoftwareDevice.h"
|
#include "AUD_SoftwareDevice.h"
|
||||||
#include "AUD_IReader.h"
|
#include "AUD_IReader.h"
|
||||||
#include "AUD_DefaultMixer.h"
|
#include "AUD_Mixer.h"
|
||||||
#include "AUD_IFactory.h"
|
#include "AUD_IFactory.h"
|
||||||
|
#ifdef WITH_SAMPLERATE
|
||||||
|
#include "AUD_SRCResampleReader.h"
|
||||||
|
#else
|
||||||
|
#include "AUD_LinearResampleReader.h"
|
||||||
|
#endif
|
||||||
|
#include "AUD_ChannelMapperReader.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
@@ -238,7 +244,7 @@ void AUD_SoftwareDevice::create()
|
|||||||
{
|
{
|
||||||
m_playback = false;
|
m_playback = false;
|
||||||
m_volume = 1.0f;
|
m_volume = 1.0f;
|
||||||
m_mixer = new AUD_DefaultMixer(m_specs);
|
m_mixer = new AUD_Mixer(m_specs);
|
||||||
|
|
||||||
pthread_mutexattr_t attr;
|
pthread_mutexattr_t attr;
|
||||||
pthread_mutexattr_init(&attr);
|
pthread_mutexattr_init(&attr);
|
||||||
@@ -352,7 +358,16 @@ AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const
|
|||||||
AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
|
AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
|
||||||
{
|
{
|
||||||
// prepare the reader
|
// prepare the reader
|
||||||
reader = m_mixer->prepare(reader);
|
// resample
|
||||||
|
#ifdef WITH_SAMPLERATE
|
||||||
|
reader = new AUD_SRCResampleReader(reader, m_specs.specs);
|
||||||
|
#else
|
||||||
|
reader = new AUD_LinearResampleReader(reader, m_specs.specs);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// rechannel
|
||||||
|
reader = new AUD_ChannelMapperReader(reader, m_specs.channels);
|
||||||
|
|
||||||
if(reader.isNull())
|
if(reader.isNull())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@@ -117,7 +117,7 @@ typedef enum
|
|||||||
AUD_RATE_88200 = 88200, /// 88200 Hz.
|
AUD_RATE_88200 = 88200, /// 88200 Hz.
|
||||||
AUD_RATE_96000 = 96000, /// 96000 Hz.
|
AUD_RATE_96000 = 96000, /// 96000 Hz.
|
||||||
AUD_RATE_192000 = 192000 /// 192000 Hz.
|
AUD_RATE_192000 = 192000 /// 192000 Hz.
|
||||||
} AUD_SampleRate;
|
} AUD_DefaultSampleRate;
|
||||||
|
|
||||||
/// Status of a playback handle.
|
/// Status of a playback handle.
|
||||||
typedef enum
|
typedef enum
|
||||||
@@ -166,6 +166,9 @@ typedef float sample_t;
|
|||||||
/// Sample data type (format samples)
|
/// Sample data type (format samples)
|
||||||
typedef unsigned char data_t;
|
typedef unsigned char data_t;
|
||||||
|
|
||||||
|
/// Sample rate type.
|
||||||
|
typedef double AUD_SampleRate;
|
||||||
|
|
||||||
/// Specification of a sound source.
|
/// Specification of a sound source.
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user