2.5 Audio:

- recode of the whole sequencer audio handling
- encode audio flag removed, instead you choose None as audio codec, added None for video codec too
- ffmpeg formats/codecs: enabled: theora, ogg, vorbis; added: matroska, flac (not working, who can fix?), mp3, wav
- sequencer wave drawing
- volume animation (now also working when mixing down to a file!)
- made sequencer strip position and length values unanimatable
This commit is contained in:
Joerg Mueller
2010-02-07 23:41:17 +00:00
parent 2f72b91a54
commit 9827a3e9ea
37 changed files with 1108 additions and 514 deletions

View File

@@ -31,6 +31,7 @@
AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
AUD_EffectReader(reader), m_loop(loop)
{
m_samples = -1;
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
}
@@ -51,6 +52,7 @@ bool AUD_LoopReader::notify(AUD_Message &message)
if(message.type == AUD_MSG_LOOP)
{
m_loop = message.loopcount;
m_samples = message.time * m_reader->getSpecs().rate;
m_reader->notify(message);
@@ -64,6 +66,13 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
AUD_Specs specs = m_reader->getSpecs();
int samplesize = AUD_SAMPLE_SIZE(specs);
if(m_samples >= 0)
{
if(length > m_samples)
length = m_samples;
m_samples -= length;
}
int len = length;
m_reader->read(len, buffer);

View File

@@ -46,6 +46,11 @@ private:
*/
int m_loop;
/**
* The left samples.
*/
int m_samples;
public:
/**
* Creates a new loop reader.

View File

@@ -180,7 +180,7 @@ void AUD_OpenALDevice::updateStreams()
AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if(alGetError() != AL_NO_ERROR)
if((err = alGetError()) != AL_NO_ERROR)
{
sound->data_end = true;
break;
@@ -839,13 +839,14 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
if(info != AL_PLAYING)
{
if(info != AL_STOPPED)
if(info == AL_PAUSED)
alSourceStop(alhandle->source);
alSourceUnqueueBuffers(alhandle->source,
AUD_OPENAL_CYCLE_BUFFERS,
alhandle->buffers);
if(alGetError() == AL_NO_ERROR)
alSourcei(alhandle->source, AL_BUFFER, 0);
alhandle->current = 0;
ALenum err;
if((err = alGetError()) == AL_NO_ERROR)
{
sample_t* buf;
int length;

View File

@@ -25,6 +25,7 @@
#include <cstdlib>
#include <cstring>
#include <cmath>
#include "AUD_NULLDevice.h"
#include "AUD_I3DDevice.h"
@@ -47,6 +48,7 @@
#include "AUD_ReadDevice.h"
#include "AUD_SourceCaps.h"
#include "AUD_IReader.h"
#include "AUD_SequencerFactory.h"
#ifdef WITH_SDL
#include "AUD_SDLDevice.h"
@@ -231,7 +233,7 @@ AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
}
}
extern AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
{
assert(sound);
@@ -273,13 +275,14 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound)
}
}
int AUD_stopLoop(AUD_Handle* handle)
int AUD_setLoop(AUD_Handle* handle, int loops, float time)
{
if(handle)
{
AUD_Message message;
message.type = AUD_MSG_LOOP;
message.loopcount = 0;
message.loopcount = loops;
message.time = time;
try
{
@@ -537,14 +540,16 @@ AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
}
}
AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound)
AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
{
assert(device);
assert(sound);
try
{
return device->play(sound);
AUD_Handle* handle = device->play(sound);
device->seek(handle, seek);
return handle;
}
catch(AUD_Exception)
{
@@ -663,3 +668,97 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high,
*length = position;
return result;
}
AUD_Sound* AUD_createSequencer(void* data, AUD_volumeFunction volume)
{
if(AUD_device)
{
return new AUD_SequencerFactory(AUD_device->getSpecs().specs, data, volume);
}
else
{
AUD_Specs specs;
specs.channels = AUD_CHANNELS_STEREO;
specs.rate = AUD_RATE_44100;
return new AUD_SequencerFactory(specs, data, volume);
}
}
void AUD_destroySequencer(AUD_Sound* sequencer)
{
delete ((AUD_SequencerFactory*)sequencer);
}
AUD_SequencerEntry* AUD_addSequencer(AUD_Sound** sequencer, AUD_Sound* sound,
float begin, float end, float skip, void* data)
{
return ((AUD_SequencerFactory*)sequencer)->add((AUD_IFactory**) sound, begin, end, skip, data);
}
void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry)
{
((AUD_SequencerFactory*)sequencer)->remove(entry);
}
void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
float begin, float end, float skip)
{
((AUD_SequencerFactory*)sequencer)->move(entry, begin, end, skip);
}
void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry, char mute)
{
((AUD_SequencerFactory*)sequencer)->mute(entry, mute);
}
int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
{
AUD_IReader* reader = sound->createReader();
AUD_DeviceSpecs specs;
sample_t* buf;
specs.specs = reader->getSpecs();
specs.channels = AUD_CHANNELS_MONO;
specs.format = AUD_FORMAT_FLOAT32;
AUD_ChannelMapperFactory mapper(reader, specs);
if(!reader || reader->getType() != AUD_TYPE_BUFFER)
return -1;
reader = mapper.createReader();
if(!reader)
return -1;
int len = reader->getLength();
float samplejump = (float)len / (float)length;
float min, max;
for(int i = 0; i < length; i++)
{
len = floor(samplejump * (i+1)) - floor(samplejump * i);
reader->read(len, buf);
if(len < 1)
{
length = i;
break;
}
max = min = *buf;
for(int j = 1; j < len; j++)
{
if(buf[j] < min)
min = buf[j];
if(buf[j] > max)
max = buf[j];
buffer[i * 2] = min;
buffer[i * 2 + 1] = max;
}
}
delete reader; AUD_DELETE("reader")
return length;
}

View File

@@ -50,6 +50,8 @@ typedef struct
typedef void AUD_Sound;
typedef void AUD_Handle;
typedef void AUD_Device;
typedef void AUD_SequencerEntry;
typedef float (*AUD_volumeFunction)(void*, void*, float);
#endif
/**
@@ -143,11 +145,13 @@ extern AUD_Sound* AUD_pingpongSound(AUD_Sound* sound);
extern AUD_Sound* AUD_loopSound(AUD_Sound* sound);
/**
* Stops a looping sound when the current playback finishes.
* Sets a remaining loop count of a looping sound that currently plays.
* \param handle The playback handle.
* \param loops The count of remaining loops, -1 for infinity.
* \param time The time after which playback should stop, -1 for infinity.
* \return Whether the handle is valid.
*/
extern int AUD_stopLoop(AUD_Handle* handle);
extern int AUD_setLoop(AUD_Handle* handle, int loops, float time);
/**
* Rectifies a sound.
@@ -211,6 +215,7 @@ extern int AUD_seek(AUD_Handle* handle, float seekTo);
/**
* Retrieves the playback position of a handle.
* \param handle The handle to the sound.
* \return The current playback position in seconds or 0.0 if the handle is
* invalid.
*/
@@ -318,9 +323,10 @@ extern int AUD_setDeviceVolume(AUD_Device* device, float volume);
* Plays back a sound file through a read device.
* \param device The read device.
* \param sound The handle of the sound file.
* \param seek The position where the sound should be seeked to.
* \return A handle to the played back sound.
*/
extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound);
extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek);
/**
* Sets the volume of a played back sound of a read device.
@@ -360,6 +366,23 @@ extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
float sthreshold, int samplerate,
int* length);
extern AUD_Sound* AUD_createSequencer(void* data, AUD_volumeFunction volume);
extern void AUD_destroySequencer(AUD_Sound* sequencer);
extern AUD_SequencerEntry* AUD_addSequencer(AUD_Sound** sequencer, AUD_Sound* sound,
float begin, float end, float skip, void* data);
extern void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry);
extern void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
float begin, float end, float skip);
extern void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
char mute);
extern int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length);
#ifdef __cplusplus
}
#endif

View File

@@ -68,6 +68,11 @@ AUD_IReader* AUD_Mixer::prepare(AUD_IReader* reader)
return reader;
}
AUD_DeviceSpecs AUD_Mixer::getSpecs()
{
return m_specs;
}
void AUD_Mixer::setSpecs(AUD_DeviceSpecs specs)
{
m_specs = specs;
@@ -115,10 +120,11 @@ void AUD_Mixer::setSpecs(AUD_DeviceSpecs specs)
}
}
void AUD_Mixer::add(sample_t* buffer, int length, float volume)
void AUD_Mixer::add(sample_t* buffer, int start, int length, float volume)
{
AUD_MixerBuffer buf;
buf.buffer = buffer;
buf.start = start;
buf.length = length;
buf.volume = volume;
m_buffers.push_back(buf);
@@ -145,11 +151,11 @@ void AUD_Mixer::superpose(data_t* buffer, int length, float volume)
buf = m_buffers.front();
m_buffers.pop_front();
end = buf.length*channels;
end = buf.length * channels;
in = buf.buffer;
for(int i = 0; i < end; i++)
out[i] += in[i]*buf.volume * volume;
out[i + buf.start * channels] += in[i] * buf.volume * volume;
}
m_convert(buffer, (data_t*) out, length * channels);

View File

@@ -37,6 +37,7 @@ class AUD_IReader;
struct AUD_MixerBuffer
{
sample_t* buffer;
int start;
int length;
float volume;
};
@@ -98,6 +99,12 @@ public:
*/
AUD_IReader* prepare(AUD_IReader* reader);
/**
* Returns the target specification for superposing.
* \return The target specification.
*/
AUD_DeviceSpecs getSpecs();
/**
* Sets the target specification for superposing.
* \param specs The target specification.
@@ -111,7 +118,7 @@ public:
* \param length The length of the buffer in samples.
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
*/
void add(sample_t* buffer, int length, float volume);
void add(sample_t* buffer, int start, int length, float volume);
/**
* Superposes all added buffers into an output buffer.

View File

@@ -0,0 +1,109 @@
/*
* $Id$
*
* ***** BEGIN LGPL LICENSE BLOCK *****
*
* Copyright 2009 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* AudaSpace 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 3 of the License, or
* (at your option) any later version.
*
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
*
* ***** END LGPL LICENSE BLOCK *****
*/
#include "AUD_SequencerFactory.h"
#include "AUD_SequencerReader.h"
typedef std::list<AUD_SequencerReader*>::iterator AUD_ReaderIterator;
AUD_SequencerFactory::AUD_SequencerFactory(AUD_Specs specs, void* data, AUD_volumeFunction volume)
{
m_specs = specs;
m_data = data;
m_volume = volume;
}
AUD_SequencerFactory::~AUD_SequencerFactory()
{
AUD_SequencerReader* reader;
AUD_SequencerEntry* entry;
while(!m_readers.empty())
{
reader = m_readers.front();
m_readers.pop_front();
reader->destroy();
}
while(!m_entries.empty())
{
entry = m_entries.front();
m_entries.pop_front();
delete entry; AUD_DELETE("seqentry")
}
}
AUD_SequencerEntry* AUD_SequencerFactory::add(AUD_IFactory** sound, float begin, float end, float skip, void* data)
{
AUD_SequencerEntry* entry = new AUD_SequencerEntry; AUD_NEW("seqentry")
entry->sound = sound;
entry->begin = begin;
entry->skip = skip;
entry->end = end;
entry->muted = false;
entry->data = data;
m_entries.push_front(entry);
for(AUD_ReaderIterator i = m_readers.begin(); i != m_readers.end(); i++)
(*i)->add(entry);
return entry;
}
void AUD_SequencerFactory::remove(AUD_SequencerEntry* entry)
{
for(AUD_ReaderIterator i = m_readers.begin(); i != m_readers.end(); i++)
(*i)->remove(entry);
m_entries.remove(entry);
delete entry; AUD_DELETE("seqentry")
}
void AUD_SequencerFactory::move(AUD_SequencerEntry* entry, float begin, float end, float skip)
{
entry->begin = begin;
entry->skip = skip;
entry->end = end;
}
void AUD_SequencerFactory::mute(AUD_SequencerEntry* entry, bool mute)
{
entry->muted = mute;
}
AUD_IReader* AUD_SequencerFactory::createReader()
{
AUD_SequencerReader* reader = new AUD_SequencerReader(this, m_entries, m_specs, m_data, m_volume); AUD_NEW("reader")
m_readers.push_front(reader);
return reader;
}
void AUD_SequencerFactory::removeReader(AUD_SequencerReader* reader)
{
m_readers.remove(reader);
}

View File

@@ -0,0 +1,77 @@
/*
* $Id$
*
* ***** BEGIN LGPL LICENSE BLOCK *****
*
* Copyright 2009 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* AudaSpace 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 3 of the License, or
* (at your option) any later version.
*
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
*
* ***** END LGPL LICENSE BLOCK *****
*/
#ifndef AUD_SEQUENCERFACTORY
#define AUD_SEQUENCERFACTORY
#include "AUD_IFactory.h"
#include <list>
typedef float (*AUD_volumeFunction)(void*, void*, float);
struct AUD_SequencerEntry
{
AUD_IFactory** sound;
float begin;
float end;
float skip;
bool muted;
void* data;
};
class AUD_SequencerReader;
/**
* This factory creates a resampling reader that does simple linear resampling.
*/
class AUD_SequencerFactory : public AUD_IFactory
{
private:
/**
* The target specification.
*/
AUD_Specs m_specs;
std::list<AUD_SequencerEntry*> m_entries;
std::list<AUD_SequencerReader*> m_readers;
void* m_data;
AUD_volumeFunction m_volume;
public:
AUD_SequencerFactory(AUD_Specs specs, void* data, AUD_volumeFunction volume);
~AUD_SequencerFactory();
AUD_SequencerEntry* add(AUD_IFactory** sound, float begin, float end, float skip, void* data);
void remove(AUD_SequencerEntry* entry);
void move(AUD_SequencerEntry* entry, float begin, float end, float skip);
void mute(AUD_SequencerEntry* entry, bool mute);
virtual AUD_IReader* createReader();
void removeReader(AUD_SequencerReader* reader);
};
#endif //AUD_SEQUENCERFACTORY

View File

@@ -0,0 +1,245 @@
/*
* $Id$
*
* ***** BEGIN LGPL LICENSE BLOCK *****
*
* Copyright 2009 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* AudaSpace 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 3 of the License, or
* (at your option) any later version.
*
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
*
* ***** END LGPL LICENSE BLOCK *****
*/
#include "AUD_SequencerReader.h"
#include "AUD_Buffer.h"
#include <math.h>
typedef std::list<AUD_SequencerStrip*>::iterator AUD_StripIterator;
typedef std::list<AUD_SequencerEntry*>::iterator AUD_EntryIterator;
AUD_SequencerReader::AUD_SequencerReader(AUD_SequencerFactory* factory, std::list<AUD_SequencerEntry*> &entries, AUD_Specs specs, void* data, AUD_volumeFunction volume)
{
AUD_DeviceSpecs dspecs;
dspecs.specs = specs;
dspecs.format = AUD_FORMAT_FLOAT32;
m_mixer.setSpecs(dspecs);
m_factory = factory;
m_data = data;
m_volume = volume;
AUD_SequencerStrip* strip;
for(AUD_EntryIterator i = entries.begin(); i != entries.end(); i++)
{
strip = new AUD_SequencerStrip; AUD_NEW("seqstrip")
strip->entry = *i;
strip->old_sound = NULL;
if(strip->old_sound)
strip->reader = m_mixer.prepare(strip->old_sound->createReader());
else
strip->reader = NULL;
m_strips.push_front(strip);
}
m_position = 0;
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
}
AUD_SequencerReader::~AUD_SequencerReader()
{
if(m_factory != NULL)
m_factory->removeReader(this);
AUD_SequencerStrip* strip;
while(!m_strips.empty())
{
strip = m_strips.front();
m_strips.pop_front();
if(strip->reader)
{
delete strip->reader; AUD_DELETE("reader")
}
delete strip; AUD_DELETE("seqstrip")
}
delete m_buffer; AUD_DELETE("buffer")
}
void AUD_SequencerReader::destroy()
{
m_factory = NULL;
AUD_SequencerStrip* strip;
while(!m_strips.empty())
{
strip = m_strips.front();
m_strips.pop_front();
delete strip; AUD_DELETE("seqstrip")
}
}
void AUD_SequencerReader::add(AUD_SequencerEntry* entry)
{
AUD_SequencerStrip* strip = new AUD_SequencerStrip; AUD_NEW("seqstrip")
strip->entry = entry;
strip->old_sound = NULL;
if(strip->old_sound)
strip->reader = m_mixer.prepare(strip->old_sound->createReader());
else
strip->reader = NULL;
m_strips.push_front(strip);
}
void AUD_SequencerReader::remove(AUD_SequencerEntry* entry)
{
AUD_SequencerStrip* strip;
for(AUD_StripIterator i = m_strips.begin(); i != m_strips.end(); i++)
{
strip = *i;
if(strip->entry == entry)
{
i++;
if(strip->reader)
{
delete strip->reader; AUD_DELETE("reader")
}
m_strips.remove(strip);
delete strip;
return;
}
}
}
bool AUD_SequencerReader::isSeekable()
{
return true;
}
void AUD_SequencerReader::seek(int position)
{
m_position = position;
}
int AUD_SequencerReader::getLength()
{
return -1;
}
int AUD_SequencerReader::getPosition()
{
return m_position;
}
AUD_Specs AUD_SequencerReader::getSpecs()
{
return m_mixer.getSpecs().specs;
}
AUD_ReaderType AUD_SequencerReader::getType()
{
return AUD_TYPE_STREAM;
}
bool AUD_SequencerReader::notify(AUD_Message &message)
{
bool result = false;
AUD_SequencerStrip* strip;
for(AUD_StripIterator i = m_strips.begin(); i != m_strips.end(); i++)
{
strip = *i;
if(strip->reader)
result |= (*i)->reader->notify(message);
}
return result;
}
void AUD_SequencerReader::read(int & length, sample_t* & buffer)
{
AUD_DeviceSpecs specs = m_mixer.getSpecs();
int samplesize = AUD_SAMPLE_SIZE(specs);
int rate = specs.rate;
int size = length * samplesize;
int start, end, current, skip, len;
AUD_SequencerStrip* strip;
sample_t* buf;
if(m_buffer->getSize() < size)
m_buffer->resize(size);
buffer = m_buffer->getBuffer();
for(AUD_StripIterator i = m_strips.begin(); i != m_strips.end(); i++)
{
strip = *i;
if(!strip->entry->muted)
{
if(strip->old_sound != *strip->entry->sound)
{
strip->old_sound = *strip->entry->sound;
if(strip->reader)
{
delete strip->reader; AUD_DELETE("reader")
}
if(strip->old_sound)
strip->reader = m_mixer.prepare(strip->old_sound->createReader());
else
strip->reader = NULL;
}
if(strip->reader)
{
end = floor(strip->entry->end * rate);
if(m_position < end)
{
start = floor(strip->entry->begin * rate);
if(m_position + length > start)
{
current = m_position - start;
if(current < 0)
{
skip = -current;
current = 0;
}
else
skip = 0;
current += strip->entry->skip * rate;
len = length > end - m_position ? end - m_position : length;
len -= skip;
if(strip->reader->getPosition() != current)
strip->reader->seek(current);
strip->reader->read(len, buf);
m_mixer.add(buf, skip, len, m_volume(m_data, strip->entry->data, (float)m_position / (float)rate));
}
}
}
}
}
m_mixer.superpose((data_t*)buffer, length, 1.0f);
m_position += length;
}

View File

@@ -0,0 +1,102 @@
/*
* $Id$
*
* ***** BEGIN LGPL LICENSE BLOCK *****
*
* Copyright 2009 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* AudaSpace 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 3 of the License, or
* (at your option) any later version.
*
* AudaSpace 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 AudaSpace. If not, see <http://www.gnu.org/licenses/>.
*
* ***** END LGPL LICENSE BLOCK *****
*/
#ifndef AUD_SEQUENCERREADER
#define AUD_SEQUENCERREADER
#include "AUD_IReader.h"
#include "AUD_SequencerFactory.h"
#include "AUD_Mixer.h"
class AUD_Buffer;
struct AUD_SequencerStrip
{
AUD_IFactory* old_sound;
AUD_IReader* reader;
AUD_SequencerEntry* entry;
};
/**
* This resampling reader uses libsamplerate for resampling.
*/
class AUD_SequencerReader : public AUD_IReader
{
private:
/**
* The current position.
*/
int m_position;
/**
* The sound output buffer.
*/
AUD_Buffer *m_buffer;
/**
* The target specification.
*/
AUD_Mixer m_mixer;
/**
* Saves the SequencerFactory the reader belongs to.
*/
AUD_SequencerFactory* m_factory;
std::list<AUD_SequencerStrip*> m_strips;
void* m_data;
AUD_volumeFunction m_volume;
public:
/**
* Creates a resampling reader.
* \param reader The reader to mix.
* \param specs The target specification.
* \exception AUD_Exception Thrown if the reader is NULL.
*/
AUD_SequencerReader(AUD_SequencerFactory* factory, std::list<AUD_SequencerEntry*> &entries, AUD_Specs specs, void* data, AUD_volumeFunction volume);
/**
* Destroys the reader.
*/
~AUD_SequencerReader();
void destroy();
void add(AUD_SequencerEntry* entry);
void remove(AUD_SequencerEntry* entry);
virtual bool isSeekable();
virtual void seek(int position);
virtual int getLength();
virtual int getPosition();
virtual AUD_Specs getSpecs();
virtual AUD_ReaderType getType();
virtual bool notify(AUD_Message &message);
virtual void read(int & length, sample_t* & buffer);
};
#endif //AUD_SEQUENCERREADER

View File

@@ -100,7 +100,6 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
AUD_SoftwareHandle* sound;
int len;
sample_t* buf;
int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
std::list<AUD_SoftwareHandle*> stopSounds;
// for all sounds
@@ -116,7 +115,7 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
len = length;
sound->reader->read(len, buf);
m_mixer->add(buf, len, sound->volume);
m_mixer->add(buf, 0, len, sound->volume);
// in case the end of the sound is reached
if(len < length)
@@ -128,12 +127,6 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
}
}
// fill with silence
if(m_specs.format == AUD_FORMAT_U8)
memset(buffer, 0x80, length * sample_size);
else
memset(buffer, 0, length * sample_size);
// superpose
m_mixer->superpose(buffer, length, m_volume);

View File

@@ -294,7 +294,11 @@ typedef struct
union
{
// loop reader
int loopcount;
struct
{
int loopcount;
float time;
};
// volume reader
float volume;