Extern: update Audaspace to latest version

No behavior changes, but no need to have a local modification
that sets JOS resampler quality to Medium

This basically contains two PRs that got accepted upstream:
- https://github.com/audaspace/audaspace/pull/19
- https://github.com/audaspace/audaspace/pull/20

Pull Request: https://projects.blender.org/blender/blender/pulls/118896
This commit is contained in:
Aras Pranckevicius 2024-02-29 12:08:00 +01:00 committed by Aras Pranckevicius
parent da2ac8ee92
commit 79707c2ae8
56 changed files with 162 additions and 142 deletions

@ -1,5 +1,5 @@
Project: Audaspace
URL: https://github.com/audaspace/audaspace
License: Apache 2.0
Upstream version: 1.4+ (0d18fe7, 2024 Jan 2)
Local modifications: JOSResampleReader default quality set to MEDIUM
Upstream version: 1.4+ (ae29ce2, 2024 Feb 26)
Local modifications: none

@ -560,7 +560,7 @@ AUD_API AUD_Sound* AUD_Sound_rechannel(AUD_Sound* sound, AUD_Channels channels)
}
}
AUD_API AUD_Sound* AUD_Sound_resample(AUD_Sound* sound, AUD_SampleRate rate, bool high_quality)
AUD_API AUD_Sound* AUD_Sound_resample(AUD_Sound* sound, AUD_SampleRate rate, AUD_ResampleQuality quality)
{
assert(sound);
@ -570,10 +570,14 @@ AUD_API AUD_Sound* AUD_Sound_resample(AUD_Sound* sound, AUD_SampleRate rate, boo
specs.channels = CHANNELS_INVALID;
specs.rate = rate;
specs.format = FORMAT_INVALID;
if(high_quality)
return new AUD_Sound(new JOSResample(*sound, specs));
else
if (quality == AUD_RESAMPLE_QUALITY_FASTEST)
{
return new AUD_Sound(new LinearResample(*sound, specs));
}
else
{
return new AUD_Sound(new JOSResample(*sound, specs, static_cast<ResampleQuality>(quality)));
}
}
catch(Exception&)
{

@ -300,10 +300,10 @@ extern AUD_API AUD_Sound* AUD_Sound_rechannel(AUD_Sound* sound, AUD_Channels cha
* Resamples the sound.
* \param sound The sound to resample.
* \param rate The new sample rate.
* \param high_quality When true use a higher quality but slower resampler.
* \param quality Resampling quality vs performance choice.
* \return The resampled sound.
*/
extern AUD_API AUD_Sound* AUD_Sound_resample(AUD_Sound* sound, AUD_SampleRate rate, bool high_quality);
extern AUD_API AUD_Sound* AUD_Sound_resample(AUD_Sound* sound, AUD_SampleRate rate, AUD_ResampleQuality quality);
/**
* Reverses a sound. Make sure the sound source can be reversed.

@ -270,14 +270,14 @@ AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int sampl
return length;
}
AUD_API int AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate, void(*callback)(float, void*), void* data, char* error, size_t errorsize)
AUD_API int AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate, AUD_ResampleQuality quality, void(*callback)(float, void*), void* data, char* error, size_t errorsize)
{
try
{
Sequence* f = dynamic_cast<Sequence *>(sound->get());
f->setSpecs(convCToSpec(specs.specs));
std::shared_ptr<IReader> reader = f->createQualityReader();
std::shared_ptr<IReader> reader = f->createQualityReader(static_cast<ResampleQuality>(quality));
reader->seek(start);
std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate);
FileWriter::writeReader(reader, writer, length, buffersize, callback, data);
@ -295,7 +295,7 @@ AUD_API int AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int lengt
}
}
AUD_API int AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate, void(*callback)(float, void*), void* data, char* error, size_t errorsize)
AUD_API int AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate, AUD_ResampleQuality quality, void(*callback)(float, void*), void* data, char* error, size_t errorsize)
{
try
{
@ -329,7 +329,7 @@ AUD_API int AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsign
writers.push_back(FileWriter::createWriter(stream.str(), convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate));
}
std::shared_ptr<IReader> reader = f->createQualityReader();
std::shared_ptr<IReader> reader = f->createQualityReader(static_cast<ResampleQuality>(quality));
reader->seek(start);
FileWriter::writeReader(reader, writers, length, buffersize, callback, data);
@ -346,19 +346,19 @@ AUD_API int AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsign
}
}
AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, double start)
AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, AUD_ResampleQuality quality, double start)
{
try
{
ReadDevice* device = new ReadDevice(convCToDSpec(specs));
device->setQuality(true);
device->setQuality(static_cast<ResampleQuality>(quality));
device->setVolume(volume);
Sequence* f = dynamic_cast<Sequence*>(sequencer->get());
f->setSpecs(convCToSpec(specs.specs));
AUD_Handle handle = device->play(f->createQualityReader());
AUD_Handle handle = device->play(f->createQualityReader(static_cast<ResampleQuality>(quality)));
if(handle.get())
{
handle->seek(start);

@ -69,6 +69,7 @@ extern AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, in
* \param format The file's container format.
* \param codec The codec used for encoding the audio data.
* \param bitrate The bitrate for encoding.
* \param quality The resampling quality.
* \param callback A callback function that is called periodically during mixdown, reporting progress if length > 0. Can be NULL.
* \param data Pass through parameter that is passed to the callback.
* \param error String buffer to copy the error message to in case of failure.
@ -78,7 +79,7 @@ extern AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, in
extern AUD_API int AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length,
unsigned int buffersize, const char* filename,
AUD_DeviceSpecs specs, AUD_Container format,
AUD_Codec codec, unsigned int bitrate,
AUD_Codec codec, unsigned int bitrate, AUD_ResampleQuality quality,
void(*callback)(float, void*), void* data, char* error, size_t errorsize);
/**
@ -92,6 +93,7 @@ extern AUD_API int AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned in
* \param format The file's container format.
* \param codec The codec used for encoding the audio data.
* \param bitrate The bitrate for encoding.
* \param quality The resampling quality.
* \param callback A callback function that is called periodically during mixdown, reporting progress if length > 0. Can be NULL.
* \param data Pass through parameter that is passed to the callback.
* \param error String buffer to copy the error message to in case of failure.
@ -101,7 +103,7 @@ extern AUD_API int AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned in
extern AUD_API int AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length,
unsigned int buffersize, const char* filename,
AUD_DeviceSpecs specs, AUD_Container format,
AUD_Codec codec, unsigned int bitrate,
AUD_Codec codec, unsigned int bitrate, AUD_ResampleQuality quality,
void(*callback)(float, void*), void* data, char* error, size_t errorsize);
/**
@ -109,10 +111,12 @@ extern AUD_API int AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start,
* \param specs Output audio specifications.
* \param sequencer The sound scene to mix down.
* \param volume The overall mixdown volume.
* \param quality The resampling quality.
* \param start The start time of the mixdown in the sound scene.
* \return The read device for the mixdown.
*/
extern AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, double start);
extern AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer,
float volume, AUD_ResampleQuality quality, double start);
/**
* Initializes audio routines (FFMPEG/JACK if it is enabled).

@ -119,6 +119,15 @@ typedef enum
AUD_CHANNELS_SURROUND71 = 8 /// 7.1 surround sound.
} AUD_Channels;
/// Resampling algorithm and quality.
typedef enum
{
AUD_RESAMPLE_QUALITY_FASTEST = 0, /// Linear resample, very fast but lowest quality.
AUD_RESAMPLE_QUALITY_LOW = 1, /// JOS resample at low quality preset.
AUD_RESAMPLE_QUALITY_MEDIUM = 2, /// JOS resample at medium quality preset.
AUD_RESAMPLE_QUALITY_HIGH = 3 /// JOS resample at high quality preset.
} AUD_ResampleQuality;
/**
* The sample rate tells how many samples are played back within one second.
* Some exotic formats may use other sample rates than provided here.

@ -1269,12 +1269,12 @@ Sound_rechannel(Sound* self, PyObject* args)
}
PyDoc_STRVAR(M_aud_Sound_resample_doc,
".. method:: resample(rate, high_quality)\n\n"
".. method:: resample(rate, quality)\n\n"
" Resamples the sound.\n\n"
" :arg rate: The new sample rate.\n"
" :type rate: double\n"
" :arg high_quality: When true use a higher quality but slower resampler.\n"
" :type high_quality: bool\n"
" :arg quality: Resampler performance vs quality choice (0=fastest, 3=slowest).\n"
" :type quality: int\n"
" :return: The created :class:`Sound` object.\n"
" :rtype: :class:`Sound`");
@ -1282,20 +1282,11 @@ static PyObject *
Sound_resample(Sound* self, PyObject* args)
{
double rate;
PyObject* high_qualityo;
bool high_quality = false;
int quality = 0;
if(!PyArg_ParseTuple(args, "d|O:resample", &rate, &high_qualityo))
if(!PyArg_ParseTuple(args, "d|i:resample", &rate, &quality))
return nullptr;
if(!PyBool_Check(high_qualityo))
{
PyErr_SetString(PyExc_TypeError, "high_quality is not a boolean!");
return nullptr;
}
high_quality = high_qualityo == Py_True;
PyTypeObject* type = Py_TYPE(self);
Sound* parent = (Sound*)type->tp_alloc(type, 0);
@ -1307,10 +1298,10 @@ Sound_resample(Sound* self, PyObject* args)
specs.channels = CHANNELS_INVALID;
specs.rate = rate;
specs.format = FORMAT_INVALID;
if(high_quality)
parent->sound = new std::shared_ptr<ISound>(new JOSResample(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), specs));
else
if (quality == int(ResampleQuality::FASTEST))
parent->sound = new std::shared_ptr<ISound>(new LinearResample(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), specs));
else
parent->sound = new std::shared_ptr<ISound>(new JOSResample(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), specs, static_cast<ResampleQuality>(quality)));
}
catch(Exception& e)
{

@ -69,7 +69,7 @@ protected:
* @param file The source code file in which the exception was thrown.
* @param line The source code line from which the exception was thrown.
*/
Exception(std::string message, std::string file, int line);
Exception(const std::string &message, const std::string &file, int line);
public:
/**
* Destroys the object.
@ -120,7 +120,7 @@ public:
* @param file The source code file in which the exception was thrown.
* @param line The source code line from which the exception was thrown.
*/
FileException(std::string message, std::string file, int line);
FileException(const std::string &message, const std::string &file, int line);
/**
* Copy constructor.
@ -145,7 +145,7 @@ public:
* @param file The source code file in which the exception was thrown.
* @param line The source code line from which the exception was thrown.
*/
DeviceException(std::string message, std::string file, int line);
DeviceException(const std::string &message, const std::string &file, int line);
/**
* Copy constructor.
@ -171,7 +171,7 @@ public:
* @param file The source code file in which the exception was thrown.
* @param line The source code line from which the exception was thrown.
*/
StateException(std::string message, std::string file, int line);
StateException(const std::string &message, const std::string &file, int line);
/**
* Copy constructor.

@ -62,14 +62,14 @@ public:
* @param name A representative name for the device.
* @param factory The factory that creates the device.
*/
static void registerDevice(std::string name, std::shared_ptr<IDeviceFactory> factory);
static void registerDevice(const std::string &name, std::shared_ptr<IDeviceFactory> factory);
/**
* Returns the factory for a specific device.
* @param name The representative name of the device.
* @return The factory if it was found, or nullptr otherwise.
*/
static std::shared_ptr<IDeviceFactory> getDeviceFactory(std::string name);
static std::shared_ptr<IDeviceFactory> getDeviceFactory(const std::string &name);
/**
* Returns the default device based on the priorities of the registered factories.
@ -92,7 +92,7 @@ public:
* If a device is currently being handled it will be released.
* @param name The representative name of the device.
*/
static void openDevice(std::string name);
static void openDevice(const std::string &name);
/**
* Opens the default device which will then be handled by the manager.

@ -71,7 +71,7 @@ public:
* Sets a name for the device.
* \param name The internal name for the device.
*/
virtual void setName(std::string name)=0;
virtual void setName(const std::string &name)=0;
};
AUD_NAMESPACE_END

@ -231,9 +231,9 @@ protected:
std::shared_ptr<Mixer> m_mixer;
/**
* Whether to do high or low quality resampling.
* Resampling quality.
*/
bool m_quality;
ResampleQuality m_quality;
/**
* Initializes member variables.
@ -347,9 +347,9 @@ public:
/**
* Sets the resampling quality.
* \param quality Low (false) or high (true) quality.
* \param quality Resampling quality vs performance setting.
*/
void setQuality(bool quality);
void setQuality(ResampleQuality quality);
virtual DeviceSpecs getSpecs() const;
virtual std::shared_ptr<IHandle> play(std::shared_ptr<IReader> reader, bool keep = false);

@ -69,7 +69,7 @@ public:
* \param filename The sound file path.
* \param stream The index of the audio stream within the file if it contains multiple audio streams.
*/
File(std::string filename, int stream = 0);
File(const std::string &filename, int stream = 0);
/**
* Creates a new sound.

@ -72,7 +72,7 @@ public:
* @return The reader created.
* @exception Exception If no file input can read the file an exception is thrown.
*/
static std::shared_ptr<IReader> createReader(std::string filename, int stream = 0);
static std::shared_ptr<IReader> createReader(const std::string &filename, int stream = 0);
/**
* Creates a file reader for the given buffer if a registed IFileInput is able to read it.
@ -89,7 +89,7 @@ public:
* \return A vector with as many streams as there are in the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
static std::vector<StreamInfo> queryStreams(std::string filename);
static std::vector<StreamInfo> queryStreams(const std::string &filename);
/**
* Queries the streams of a sound file.
@ -110,7 +110,7 @@ public:
* @return A writer that creates the file.
* @exception Exception If no file output can write the file with the given specification an exception is thrown.
*/
static std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
static std::shared_ptr<IWriter> createWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
};
AUD_NAMESPACE_END

@ -54,7 +54,7 @@ public:
* \param bitrate The bitrate for encoding.
* \return The writer to write data to.
*/
static std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
static std::shared_ptr<IWriter> createWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
/**
* Writes a reader to a writer.

@ -54,7 +54,7 @@ public:
* \return The reader that reads the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
virtual std::shared_ptr<IReader> createReader(std::string filename, int stream = 0)=0;
virtual std::shared_ptr<IReader> createReader(const std::string &filename, int stream = 0)=0;
/**
* Creates a reader for a file to be read from memory.
@ -71,7 +71,7 @@ public:
* \return A vector with as many streams as there are in the file.
* \exception Exception Thrown if the file specified cannot be read.
*/
virtual std::vector<StreamInfo> queryStreams(std::string filename)=0;
virtual std::vector<StreamInfo> queryStreams(const std::string &filename)=0;
/**
* Queries the streams of a sound file.

@ -46,7 +46,7 @@ public:
* \param bitrate The bitrate for encoding.
* \exception Exception Thrown if the file specified cannot be written.
*/
virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)=0;
virtual std::shared_ptr<IWriter> createWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)=0;
};
AUD_NAMESPACE_END

@ -36,13 +36,15 @@ private:
JOSResample(const JOSResample&) = delete;
JOSResample& operator=(const JOSResample&) = delete;
ResampleQuality m_quality;
public:
/**
* Creates a new sound.
* \param sound The input sound.
* \param specs The target specifications.
*/
JOSResample(std::shared_ptr<ISound> sound, DeviceSpecs specs);
JOSResample(std::shared_ptr<ISound> sound, DeviceSpecs specs, ResampleQuality quality = ResampleQuality::HIGH);
virtual std::shared_ptr<IReader> createReader();
};

@ -36,39 +36,39 @@ private:
typedef void (JOSResampleReader::*resample_f)(double target_factor, int length, sample_t* buffer);
/**
* The half filter length for Quality::HIGH setting.
* The half filter length for HIGH quality setting.
*/
static const int m_len_high;
/**
* The half filter length for Quality::MEDIUM setting.
* The half filter length for MEDIUM quality setting.
*/
static const int m_len_medium;
/**
* The half filter length for Quality::LOW setting.
* The half filter length for LOW quality setting.
*/
static const int m_len_low;
/**
* The filter sample step size for Quality::HIGH setting.
* The filter sample step size for HIGH quality setting.
*/
static const int m_L_high;
/**
* The filter sample step size for Quality::MEDIUM setting.
* The filter sample step size for MEDIUM quality setting.
*/
static const int m_L_medium;
/**
* The filter sample step size for Quality::LOW setting.
* The filter sample step size for LOW quality setting.
*/
static const int m_L_low;
/**
* The filter coefficients for Quality::HIGH setting.
* The filter coefficients for HIGH quality setting.
*/
static const float m_coeff_high[];
/**
* The filter coefficients for Quality::MEDIUM setting.
* The filter coefficients for MEDIUM quality setting.
*/
static const float m_coeff_medium[];
/**
* The filter coefficients for Quality::LOW setting.
* The filter coefficients for LOW quality setting.
*/
static const float m_coeff_low[];
@ -152,19 +152,13 @@ private:
void AUD_LOCAL resample(double target_factor, int length, sample_t* buffer);
public:
enum class Quality
{
LOW = 0,
MEDIUM,
HIGH,
};
/**
* Creates a resampling reader.
* \param reader The reader to mix.
* \param rate The target sampling rate.
*/
JOSResampleReader(std::shared_ptr<IReader> reader, SampleRate rate, Quality = Quality::MEDIUM);
JOSResampleReader(std::shared_ptr<IReader> reader, SampleRate rate, ResampleQuality quality = ResampleQuality::HIGH);
virtual void seek(int position);
virtual int getLength() const;

@ -83,6 +83,15 @@ enum Channel
CHANNEL_MAX
};
/// Resampling algorithm and quality.
enum class ResampleQuality
{
FASTEST = 0, /// Linear resample, very fast but lowest quality.
LOW, /// JOS resample at low quality preset.
MEDIUM, /// JOS resample at medium quality preset.
HIGH /// JOS resample at high quality preset.
};
/**
* The sample rate tells how many samples are played back within one second.
* Some exotic formats may use other sample rates than provided here.

@ -160,10 +160,11 @@ public:
void remove(std::shared_ptr<SequenceEntry> entry);
/**
* Creates a new reader with high quality resampling.
* Creates a new reader with indicated resampling quality.
* \param quality The resampling quality.
* \return The new reader.
*/
std::shared_ptr<IReader> createQualityReader();
std::shared_ptr<IReader> createQualityReader(ResampleQuality quality);
virtual std::shared_ptr<IReader> createReader();
};

@ -74,9 +74,9 @@ public:
/**
* Creates a resampling reader.
* \param sequence The sequence data.
* \param quality Whether a high quality resample should be used for resampling.
* \param quality Resampling quality vs performance option.
*/
SequenceReader(std::shared_ptr<SequenceData> sequence, bool quality = false);
SequenceReader(std::shared_ptr<SequenceData> sequence, ResampleQuality quality = ResampleQuality::FASTEST);
/**
* Destroys the reader.

@ -210,7 +210,7 @@ public:
m_buffersize = buffersize;
}
virtual void setName(std::string name)
virtual void setName(const std::string &name)
{
}
};

@ -35,7 +35,7 @@ void FFMPEG::registerPlugin()
FileManager::registerOutput(plugin);
}
std::shared_ptr<IReader> FFMPEG::createReader(std::string filename, int stream)
std::shared_ptr<IReader> FFMPEG::createReader(const std::string &filename, int stream)
{
return std::shared_ptr<IReader>(new FFMPEGReader(filename, stream));
}
@ -45,7 +45,7 @@ std::shared_ptr<IReader> FFMPEG::createReader(std::shared_ptr<Buffer> buffer, in
return std::shared_ptr<IReader>(new FFMPEGReader(buffer, stream));
}
std::vector<StreamInfo> FFMPEG::queryStreams(std::string filename)
std::vector<StreamInfo> FFMPEG::queryStreams(const std::string &filename)
{
return FFMPEGReader(filename).queryStreams();
}
@ -55,7 +55,7 @@ std::vector<StreamInfo> FFMPEG::queryStreams(std::shared_ptr<Buffer> buffer)
return FFMPEGReader(buffer).queryStreams();
}
std::shared_ptr<IWriter> FFMPEG::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
std::shared_ptr<IWriter> FFMPEG::createWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
{
return std::shared_ptr<IWriter>(new FFMPEGWriter(filename, specs, format, codec, bitrate));
}

@ -52,11 +52,11 @@ public:
*/
static void registerPlugin();
virtual std::shared_ptr<IReader> createReader(std::string filename, int stream = 0);
virtual std::shared_ptr<IReader> createReader(const std::string &filename, int stream = 0);
virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer, int stream = 0);
virtual std::vector<StreamInfo> queryStreams(std::string filename);
virtual std::vector<StreamInfo> queryStreams(const std::string &filename);
virtual std::vector<StreamInfo> queryStreams(std::shared_ptr<Buffer> buffer);
virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
virtual std::shared_ptr<IWriter> createWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
};
AUD_NAMESPACE_END

@ -239,7 +239,7 @@ void FFMPEGReader::init(int stream)
m_specs.rate = (SampleRate) m_codecCtx->sample_rate;
}
FFMPEGReader::FFMPEGReader(std::string filename, int stream) :
FFMPEGReader::FFMPEGReader(const std::string &filename, int stream) :
m_pkgbuf(),
m_formatCtx(nullptr),
m_codecCtx(nullptr),

@ -154,7 +154,7 @@ public:
* \exception Exception Thrown if the file specified does not exist or
* cannot be read with ffmpeg.
*/
FFMPEGReader(std::string filename, int stream = 0);
FFMPEGReader(const std::string &filename, int stream = 0);
/**
* Creates a new reader.

@ -158,7 +158,7 @@ void FFMPEGWriter::close()
#endif
}
FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate) :
FFMPEGWriter::FFMPEGWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate) :
m_position(0),
m_specs(specs),
m_formatCtx(nullptr),

@ -135,7 +135,7 @@ public:
* \exception Exception Thrown if the file specified does not exist or
* cannot be read with ffmpeg.
*/
FFMPEGWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
FFMPEGWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
/**
* Destroys the writer and closes the file.

@ -162,7 +162,7 @@ void JackDevice::jack_shutdown(void* data)
device->m_valid = false;
}
JackDevice::JackDevice(std::string name, DeviceSpecs specs, int buffersize) :
JackDevice::JackDevice(const std::string &name, DeviceSpecs specs, int buffersize) :
m_synchronizer(this)
{
if(specs.channels == CHANNELS_INVALID)
@ -358,7 +358,7 @@ public:
m_buffersize = buffersize;
}
virtual void setName(std::string name)
virtual void setName(const std::string &name)
{
m_name = name;
}

@ -151,7 +151,7 @@ public:
* \param buffersize The size of the internal buffer.
* \exception Exception Thrown if the audio device cannot be opened.
*/
JackDevice(std::string name, DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
JackDevice(const std::string &name, DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
/**
* Closes the JACK client.

@ -32,7 +32,7 @@ void SndFile::registerPlugin()
FileManager::registerOutput(plugin);
}
std::shared_ptr<IReader> SndFile::createReader(std::string filename, int stream)
std::shared_ptr<IReader> SndFile::createReader(const std::string &filename, int stream)
{
return std::shared_ptr<IReader>(new SndFileReader(filename));
}
@ -42,7 +42,7 @@ std::shared_ptr<IReader> SndFile::createReader(std::shared_ptr<Buffer> buffer, i
return std::shared_ptr<IReader>(new SndFileReader(buffer));
}
std::vector<StreamInfo> SndFile::queryStreams(std::string filename)
std::vector<StreamInfo> SndFile::queryStreams(const std::string &filename)
{
return SndFileReader(filename).queryStreams();
}
@ -52,7 +52,7 @@ std::vector<StreamInfo> SndFile::queryStreams(std::shared_ptr<Buffer> buffer)
return SndFileReader(buffer).queryStreams();
}
std::shared_ptr<IWriter> SndFile::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
std::shared_ptr<IWriter> SndFile::createWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
{
return std::shared_ptr<IWriter>(new SndFileWriter(filename, specs, format, codec, bitrate));
}

@ -52,11 +52,11 @@ public:
*/
static void registerPlugin();
virtual std::shared_ptr<IReader> createReader(std::string filename, int stream = 0);
virtual std::shared_ptr<IReader> createReader(const std::string &filename, int stream = 0);
virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer, int stream = 0);
virtual std::vector<StreamInfo> queryStreams(std::string filename);
virtual std::vector<StreamInfo> queryStreams(const std::string &filename);
virtual std::vector<StreamInfo> queryStreams(std::shared_ptr<Buffer> buffer);
virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
virtual std::shared_ptr<IWriter> createWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
};
AUD_NAMESPACE_END

@ -71,7 +71,7 @@ sf_count_t SndFileReader::vio_tell(void* user_data)
return reader->m_memoffset;
}
SndFileReader::SndFileReader(std::string filename) :
SndFileReader::SndFileReader(const std::string &filename) :
m_position(0)
{
SF_INFO sfinfo;

@ -103,7 +103,7 @@ public:
* \exception Exception Thrown if the file specified does not exist or
* cannot be read with libsndfile.
*/
SndFileReader(std::string filename);
SndFileReader(const std::string &filename);
/**
* Creates a new reader.

@ -21,7 +21,7 @@
AUD_NAMESPACE_BEGIN
SndFileWriter::SndFileWriter(std::string filename, DeviceSpecs specs,
SndFileWriter::SndFileWriter(const std::string &filename, DeviceSpecs specs,
Container format, Codec codec, unsigned int bitrate) :
m_position(0), m_specs(specs)
{

@ -69,7 +69,7 @@ public:
* \exception Exception Thrown if the file specified cannot be written
* with libsndfile.
*/
SndFileWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
SndFileWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
/**
* Destroys the writer and closes the file.

@ -1131,7 +1131,7 @@ void OpenALDevice::updateStreams()
/**************************** IDevice Code ************************************/
/******************************************************************************/
OpenALDevice::OpenALDevice(DeviceSpecs specs, int buffersize, std::string name) :
OpenALDevice::OpenALDevice(DeviceSpecs specs, int buffersize, const std::string &name) :
m_name(name), m_playing(false), m_buffersize(buffersize)
{
// cannot determine how many channels or which format OpenAL uses, but
@ -1561,7 +1561,7 @@ private:
std::string m_name;
public:
OpenALDeviceFactory(std::string name = "") :
OpenALDeviceFactory(const std::string &name = "") :
m_buffersize(AUD_DEFAULT_BUFFER_SIZE),
m_name(name)
{
@ -1590,7 +1590,7 @@ public:
m_buffersize = buffersize;
}
virtual void setName(std::string name)
virtual void setName(const std::string &name)
{
}
};
@ -1599,7 +1599,7 @@ void OpenALDevice::registerPlugin()
{
auto names = OpenALDevice::getDeviceNames();
DeviceManager::registerDevice("OpenAL", std::shared_ptr<IDeviceFactory>(new OpenALDeviceFactory));
for(std::string &name : names)
for(const std::string &name : names)
{
DeviceManager::registerDevice("OpenAL - " + name, std::shared_ptr<IDeviceFactory>(new OpenALDeviceFactory(name)));
}

@ -269,7 +269,7 @@ public:
* \note The buffersize will be multiplicated by three for this device.
* \exception DeviceException Thrown if the audio device cannot be opened.
*/
OpenALDevice(DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE, std::string name = "");
OpenALDevice(DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE, const std::string &name = "");
virtual ~OpenALDevice();

@ -121,7 +121,7 @@ void PulseAudioDevice::playing(bool playing)
AUD_pa_threaded_mainloop_unlock(m_mainloop);
}
PulseAudioDevice::PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize) :
PulseAudioDevice::PulseAudioDevice(const std::string &name, DeviceSpecs specs, int buffersize) :
m_synchronizer(this),
m_playback(false),
m_state(PA_CONTEXT_UNCONNECTED),
@ -321,7 +321,7 @@ public:
m_buffersize = buffersize;
}
virtual void setName(std::string name)
virtual void setName(const std::string &name)
{
m_name = name;
}

@ -128,7 +128,7 @@ public:
* \note The specification really used for opening the device may differ.
* \exception Exception Thrown if the audio device cannot be opened.
*/
PulseAudioDevice(std::string name, DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
PulseAudioDevice(const std::string &name, DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
/**
* Closes the PulseAudio audio device.

@ -157,7 +157,7 @@ public:
m_buffersize = buffersize;
}
virtual void setName(std::string name)
virtual void setName(const std::string &name)
{
}
};

@ -458,7 +458,7 @@ public:
m_buffersize = buffersize;
}
virtual void setName(std::string name)
virtual void setName(const std::string &name)
{
}
};

@ -25,7 +25,7 @@ Exception::Exception(const Exception& exception) :
{
}
Exception::Exception(std::string message, std::string file, int line) :
Exception::Exception(const std::string &message, const std::string &file, int line) :
m_message(message),
m_file(file),
m_line(line)
@ -65,7 +65,7 @@ int Exception::getLine() const
return m_line;
}
FileException::FileException(std::string message, std::string file, int line) :
FileException::FileException(const std::string &message, const std::string &file, int line) :
Exception(message, file, line)
{
}
@ -79,7 +79,7 @@ FileException::~FileException() AUD_NOEXCEPT
{
}
DeviceException::DeviceException(std::string message, std::string file, int line) :
DeviceException::DeviceException(const std::string &message, const std::string &file, int line) :
Exception(message, file, line)
{
}
@ -93,7 +93,7 @@ DeviceException::~DeviceException() AUD_NOEXCEPT
{
}
StateException::StateException(std::string message, std::string file, int line) :
StateException::StateException(const std::string &message, const std::string &file, int line) :
Exception(message, file, line)
{
}

@ -28,12 +28,12 @@ AUD_NAMESPACE_BEGIN
std::unordered_map<std::string, std::shared_ptr<IDeviceFactory>> DeviceManager::m_factories;
std::shared_ptr<IDevice> DeviceManager::m_device;
void DeviceManager::registerDevice(std::string name, std::shared_ptr<IDeviceFactory> factory)
void DeviceManager::registerDevice(const std::string &name, std::shared_ptr<IDeviceFactory> factory)
{
m_factories[name] = factory;
}
std::shared_ptr<IDeviceFactory> DeviceManager::getDeviceFactory(std::string name)
std::shared_ptr<IDeviceFactory> DeviceManager::getDeviceFactory(const std::string &name)
{
auto it = m_factories.find(name);
@ -66,7 +66,7 @@ void DeviceManager::setDevice(std::shared_ptr<IDevice> device)
m_device = device;
}
void DeviceManager::openDevice(std::string name)
void DeviceManager::openDevice(const std::string &name)
{
setDevice(getDeviceFactory(name)->openDevice());
}

@ -180,7 +180,7 @@ public:
{
}
virtual void setName(std::string name)
virtual void setName(const std::string &name)
{
}
};

@ -718,7 +718,7 @@ void SoftwareDevice::create()
m_doppler_factor = 1.0f;
m_distance_model = DISTANCE_MODEL_INVERSE_CLAMPED;
m_flags = 0;
m_quality = false;
m_quality = ResampleQuality::FASTEST;
}
void SoftwareDevice::destroy()
@ -829,7 +829,7 @@ void SoftwareDevice::setPanning(IHandle* handle, float pan)
h->m_user_pan = pan;
}
void SoftwareDevice::setQuality(bool quality)
void SoftwareDevice::setQuality(ResampleQuality quality)
{
m_quality = quality;
}
@ -886,10 +886,14 @@ std::shared_ptr<IHandle> SoftwareDevice::play(std::shared_ptr<IReader> reader, b
std::shared_ptr<ResampleReader> resampler;
// resample
if(m_quality)
resampler = std::shared_ptr<ResampleReader>(new JOSResampleReader(reader, m_specs.rate));
else
if (m_quality == ResampleQuality::FASTEST)
{
resampler = std::shared_ptr<ResampleReader>(new LinearResampleReader(reader, m_specs.rate));
}
else
{
resampler = std::shared_ptr<ResampleReader>(new JOSResampleReader(reader, m_specs.rate, m_quality));
}
reader = std::shared_ptr<IReader>(resampler);
// rechannel

@ -23,7 +23,7 @@
AUD_NAMESPACE_BEGIN
File::File(std::string filename, int stream) :
File::File(const std::string &filename, int stream) :
m_filename(filename), m_stream(stream)
{
}

@ -43,7 +43,7 @@ void FileManager::registerOutput(std::shared_ptr<aud::IFileOutput> output)
outputs().push_back(output);
}
std::shared_ptr<IReader> FileManager::createReader(std::string filename, int stream)
std::shared_ptr<IReader> FileManager::createReader(const std::string &filename, int stream)
{
for(std::shared_ptr<IFileInput> input : inputs())
{
@ -71,7 +71,7 @@ std::shared_ptr<IReader> FileManager::createReader(std::shared_ptr<Buffer> buffe
AUD_THROW(FileException, "The file couldn't be read with any installed file reader.");
}
std::vector<StreamInfo> FileManager::queryStreams(std::string filename)
std::vector<StreamInfo> FileManager::queryStreams(const std::string &filename)
{
for(std::shared_ptr<IFileInput> input : inputs())
{
@ -99,7 +99,7 @@ std::vector<StreamInfo> FileManager::queryStreams(std::shared_ptr<Buffer> buffer
AUD_THROW(FileException, "The file couldn't be read with any installed file reader.");
}
std::shared_ptr<IWriter> FileManager::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
std::shared_ptr<IWriter> FileManager::createWriter(const std::string &filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
{
for(std::shared_ptr<IFileOutput> output : outputs())
{

@ -22,7 +22,7 @@
AUD_NAMESPACE_BEGIN
std::shared_ptr<IWriter> FileWriter::createWriter(std::string filename,DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
std::shared_ptr<IWriter> FileWriter::createWriter(const std::string &filename,DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
{
return FileManager::createWriter(filename, specs, format, codec, bitrate);
}

@ -19,15 +19,14 @@
AUD_NAMESPACE_BEGIN
JOSResample::JOSResample(std::shared_ptr<ISound> sound,
DeviceSpecs specs) :
SpecsChanger(sound, specs)
JOSResample::JOSResample(std::shared_ptr<ISound> sound, DeviceSpecs specs, ResampleQuality quality) :
SpecsChanger(sound, specs), m_quality(quality)
{
}
std::shared_ptr<IReader> JOSResample::createReader()
{
return std::shared_ptr<IReader>(new JOSResampleReader(getReader(), m_specs.rate));
return std::shared_ptr<IReader>(new JOSResampleReader(getReader(), m_specs.rate, m_quality));
}
AUD_NAMESPACE_END

@ -45,7 +45,7 @@ static inline int lrint_impl(double x)
AUD_NAMESPACE_BEGIN
JOSResampleReader::JOSResampleReader(std::shared_ptr<IReader> reader, SampleRate rate, Quality quality) :
JOSResampleReader::JOSResampleReader(std::shared_ptr<IReader> reader, SampleRate rate, ResampleQuality quality) :
ResampleReader(reader, rate),
m_channels(CHANNELS_INVALID),
m_n(0),
@ -55,17 +55,17 @@ JOSResampleReader::JOSResampleReader(std::shared_ptr<IReader> reader, SampleRate
{
switch(quality)
{
case Quality::LOW:
case ResampleQuality::LOW:
m_len = m_len_low;
m_L = m_L_low;
m_coeff = m_coeff_low;
break;
case Quality::MEDIUM:
case ResampleQuality::MEDIUM:
m_len = m_len_medium;
m_L = m_L_medium;
m_coeff = m_coeff_medium;
break;
case Quality::HIGH:
case ResampleQuality::HIGH:
m_len = m_len_high;
m_L = m_L_high;
m_coeff = m_coeff_high;

@ -100,9 +100,9 @@ void Sequence::remove(std::shared_ptr<SequenceEntry> entry)
m_sequence->remove(entry);
}
std::shared_ptr<IReader> Sequence::createQualityReader()
std::shared_ptr<IReader> Sequence::createQualityReader(ResampleQuality quality)
{
return std::shared_ptr<IReader>(new SequenceReader(m_sequence, true));
return std::shared_ptr<IReader>(new SequenceReader(m_sequence, quality));
}
std::shared_ptr<IReader> Sequence::createReader()

@ -25,7 +25,7 @@
AUD_NAMESPACE_BEGIN
SequenceReader::SequenceReader(std::shared_ptr<SequenceData> sequence, bool quality) :
SequenceReader::SequenceReader(std::shared_ptr<SequenceData> sequence, ResampleQuality quality) :
m_position(0), m_device(sequence->m_specs), m_sequence(sequence), m_status(0), m_entry_status(0)
{
m_device.setQuality(quality);

@ -19,7 +19,7 @@ PERFORMANCE OF THIS SOFTWARE.
------
** Audaspace; version 1.3.0 -- https://audaspace.github.io/
** Audaspace; version 1.4+ (ae29ce2) -- https://audaspace.github.io/
** Cuda Wrangler; version cbf465b -- https://github.com/CudaWrangler/cuew
** Draco; version 1.3.6 -- https://google.github.io/draco/
** Embree; version 4.1.0 -- https://github.com/embree/embree
@ -244,7 +244,7 @@ See the License for the specific language governing permissions and
limitations under the License.
* For Audaspace see also this required NOTICE:
Copyright © 2009-2020 Jörg Müller. All rights reserved.
Copyright © 2009-2023 Jörg Müller. All rights reserved.
* For Cuda Wrangler see also this required NOTICE:
Copyright 2011-2014 Blender Foundation
* For Draco see also this required NOTICE:

@ -599,7 +599,8 @@ void BKE_sound_load(Main *bmain, bSound *sound)
AUD_Device *BKE_sound_mixdown(const Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
{
sound_verify_evaluated_id(&scene->id);
return AUD_openMixdownDevice(specs, scene->sound_scene, volume, start / FPS);
return AUD_openMixdownDevice(
specs, scene->sound_scene, volume, AUD_RESAMPLE_QUALITY_MEDIUM, start / FPS);
}
void BKE_sound_create_scene(Scene *scene)

@ -370,6 +370,7 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
container,
codec,
bitrate,
AUD_RESAMPLE_QUALITY_MEDIUM,
nullptr,
nullptr,
error_message,
@ -385,6 +386,7 @@ static int sound_mixdown_exec(bContext *C, wmOperator *op)
container,
codec,
bitrate,
AUD_RESAMPLE_QUALITY_MEDIUM,
nullptr,
nullptr,
error_message,