Exemplo n.º 1
0
void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_IWriter> writer, unsigned int length, unsigned int buffersize)
{
	AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(writer->getSpecs()));
	sample_t* buf = buffer.getBuffer();

	int len;
	bool eos = false;
	int channels = writer->getSpecs().channels;

	for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
	{
		len = buffersize;
		if((len > length - pos) && (length > 0))
			len = length - pos;
		reader->read(len, eos, buf);

		for(int i = 0; i < len * channels; i++)
		{
			// clamping!
			if(buf[i] > 1)
				buf[i] = 1;
			else if(buf[i] < -1)
				buf[i] = -1;
		}

		writer->write(len, buf);
	}
}
Exemplo n.º 2
0
AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds)
{
	AUD_Reference<AUD_IFactory> silence = new AUD_SilenceFactory;
	AUD_Reference<AUD_IFactory> limiter = new AUD_LimiterFactory(silence, 0, seconds);

	AUD_device->lock();

	try
	{
		AUD_Handle handle2 = AUD_device->play(limiter);
		if(!handle2.isNull())
		{
			handle2->setStopCallback((stopCallback)pauseSound, handle);
			AUD_device->unlock();
			return new AUD_Handle(handle2);
		}
	}
	catch(AUD_Exception&)
	{
	}

	AUD_device->unlock();

	return NULL;
}
Exemplo n.º 3
0
AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
{
	assert(sound);

	AUD_SoundInfo info;
	info.specs.channels = AUD_CHANNELS_INVALID;
	info.specs.rate = AUD_RATE_INVALID;
	info.length = 0.0f;

	try
	{
		AUD_Reference<AUD_IReader> reader = (*sound)->createReader();

		if(!reader.isNull())
		{
			info.specs = reader->getSpecs();
			info.length = reader->getLength() / (float) info.specs.rate;
		}
	}
	catch(AUD_Exception&)
	{
	}

	return info;
}
Exemplo n.º 4
0
void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, std::vector<AUD_Reference<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize)
{
	AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(reader->getSpecs()));
	AUD_Buffer buffer2(buffersize * sizeof(sample_t));
	sample_t* buf = buffer.getBuffer();
	sample_t* buf2 = buffer2.getBuffer();

	int len;
	bool eos = false;
	int channels = reader->getSpecs().channels;

	for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
	{
		len = buffersize;
		if((len > length - pos) && (length > 0))
			len = length - pos;
		reader->read(len, eos, buf);

		for(int channel = 0; channel < channels; channel++)
		{
			for(int i = 0; i < len; i++)
			{
				// clamping!
				if(buf[i * channels + channel] > 1)
					buf2[i] = 1;
				else if(buf[i * channels + channel] < -1)
					buf2[i] = -1;
				else
					buf2[i] = buf[i * channels + channel];
			}

			writers[channel]->write(len, buf2);
		}
	}
}
Exemplo n.º 5
0
AUD_DoubleReader::AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1,
								   AUD_Reference<AUD_IReader> reader2) :
		m_reader1(reader1), m_reader2(reader2), m_finished1(false)
{
	AUD_Specs s1, s2;
	s1 = reader1->getSpecs();
	s2 = reader2->getSpecs();
}
Exemplo n.º 6
0
int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
{
	AUD_Reference<AUD_IDevice> dev;

	if(!AUD_device.isNull())
		AUD_exit();

	try
	{
		switch(device)
		{
		case AUD_NULL_DEVICE:
			dev = new AUD_NULLDevice();
			break;
#ifdef WITH_SDL
		case AUD_SDL_DEVICE:
			dev = new AUD_SDLDevice(specs, buffersize);
			break;
#endif
#ifdef WITH_OPENAL
		case AUD_OPENAL_DEVICE:
			dev = new AUD_OpenALDevice(specs, buffersize);
			break;
#endif
#ifdef WITH_JACK
		case AUD_JACK_DEVICE:
#ifdef __APPLE__
			struct stat st;
			if(stat("/Library/Frameworks/Jackmp.framework", &st) != 0)
			{
				printf("Warning: Jack Framework not installed\n");
				// No break, fall through to default, to return false
			}
			else
			{
#endif
				dev = new AUD_JackDevice("Blender", specs, buffersize);
				break;
#ifdef __APPLE__
			}
#endif
#endif
		default:
			return false;
		}

		AUD_device = dev;
		AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device.get());

		return true;
	}
	catch(AUD_Exception&)
	{
		return false;
	}
}
int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length, int samples_per_second)
{
	AUD_DeviceSpecs specs;
	sample_t* buf;
	AUD_Buffer aBuffer;

	specs.rate = AUD_RATE_INVALID;
	specs.channels = AUD_CHANNELS_MONO;
	specs.format = AUD_FORMAT_INVALID;

	AUD_Reference<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();

	specs.specs = reader->getSpecs();
	int len;
	float samplejump = specs.rate / samples_per_second;
	float min, max, power;
	bool eos;

	for(int i = 0; i < length; i++)
	{
		len = floor(samplejump * (i+1)) - floor(samplejump * i);

		aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
		buf = aBuffer.getBuffer();

		reader->read(len, eos, buf);

		max = min = *buf;
		power = *buf * *buf;
		for(int j = 1; j < len; j++)
		{
			if(buf[j] < min)
				min = buf[j];
			if(buf[j] > max)
				max = buf[j];
			power += buf[j] * buf[j];
		}

		buffer[i * 3] = min;
		buffer[i * 3 + 1] = max;
		buffer[i * 3 + 2] = sqrt(power) / len;

		if(eos)
		{
			length = i;
			break;
		}
	}

	return length;
}
AUD_Reference<AUD_IReader> AUD_EnvelopeFactory::createReader()
{
	AUD_Reference<AUD_IReader> reader = getReader();

	EnvelopeParameters* param = new EnvelopeParameters();
	param->arthreshold = m_arthreshold;
	param->attack = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_attack));
	param->release = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release));
	param->threshold = m_threshold;

	return new AUD_CallbackIIRFilterReader(reader, 1, 2,
										   (doFilterIIR) envelopeFilter,
										   (endFilterIIR) endEnvelopeFilter,
										   param);
}
Exemplo n.º 9
0
void AUD_stopPlayback()
{
#ifdef WITH_JACK
	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
	if(device)
		device->stopPlayback();
#endif
}
Exemplo n.º 10
0
float* AUD_readSoundBuffer(const char* filename, float low, float high,
						   float attack, float release, float threshold,
						   int accumulate, int additive, int square,
						   float sthreshold, double samplerate, int* length)
{
	AUD_Buffer buffer;
	AUD_DeviceSpecs specs;
	specs.channels = AUD_CHANNELS_MONO;
	specs.rate = (AUD_SampleRate)samplerate;
	AUD_Reference<AUD_IFactory> sound;

	AUD_Reference<AUD_IFactory> file = new AUD_FileFactory(filename);

	AUD_Reference<AUD_IReader> reader = file->createReader();
	AUD_SampleRate rate = reader->getSpecs().rate;

	sound = new AUD_ChannelMapperFactory(file, specs);

	if(high < rate)
		sound = new AUD_LowpassFactory(sound, high);
	if(low > 0)
		sound = new AUD_HighpassFactory(sound, low);

	sound = new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f);
	sound = new AUD_LinearResampleFactory(sound, specs);

	if(square)
		sound = new AUD_SquareFactory(sound, sthreshold);

	if(accumulate)
		sound = new AUD_AccumulatorFactory(sound, additive);
	else if(additive)
		sound = new AUD_SumFactory(sound);

	reader = sound->createReader();

	if(reader.isNull())
		return NULL;

	int len;
	int position = 0;
	bool eos;
	do
	{
		len = samplerate;
		buffer.resize((position + len) * sizeof(float), true);
		reader->read(len, eos, buffer.getBuffer() + position);
		position += len;
	} while(!eos);

	float* result = (float*)malloc(position * sizeof(float));
	memcpy(result, buffer.getBuffer(), position * sizeof(float));
	*length = position;
	return result;
}
Exemplo n.º 11
0
int AUD_doesPlayback()
{
#ifdef WITH_JACK
	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
	if(device)
		return device->doesPlayback();
#endif
	return -1;
}
Exemplo n.º 12
0
int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
{
	AUD_Reference<AUD_IDevice> dev;

	if(!AUD_device.isNull())
		AUD_exit();

	try
	{
		switch(device)
		{
		case AUD_NULL_DEVICE:
			dev = new AUD_NULLDevice();
			break;
#ifdef WITH_SDL
		case AUD_SDL_DEVICE:
			dev = new AUD_SDLDevice(specs, buffersize);
			break;
#endif
#ifdef WITH_OPENAL
		case AUD_OPENAL_DEVICE:
			dev = new AUD_OpenALDevice(specs, buffersize);
			break;
#endif
#ifdef WITH_JACK
		case AUD_JACK_DEVICE:
			dev = new AUD_JackDevice("Blender", specs, buffersize);
			break;
#endif
		default:
			return false;
		}

		AUD_device = dev;
		AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device.get());

		return true;
	}
	catch(AUD_Exception&)
	{
		return false;
	}
}
Exemplo n.º 13
0
const char* 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)
{
	try
	{
		AUD_SequencerFactory* f = dynamic_cast<AUD_SequencerFactory*>(sound->get());

		f->setSpecs(specs.specs);
		AUD_Reference<AUD_IReader> reader = f->createQualityReader();
		reader->seek(start);
		AUD_Reference<AUD_IWriter> writer = AUD_FileWriter::createWriter(filename, specs, format, codec, bitrate);
		AUD_FileWriter::writeReader(reader, writer, length, buffersize);

		return NULL;
	}
	catch(AUD_Exception& e)
	{
		return e.str;
	}
}
Exemplo n.º 14
0
AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<AUD_IReader> reader, bool keep) :
	m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0),
	m_eos(false), m_loopcount(0), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING),
	m_device(device)
{
	AUD_DeviceSpecs specs = m_device->m_specs;
	specs.specs = m_reader->getSpecs();

	// OpenAL playback code
	alGenBuffers(CYCLE_BUFFERS, m_buffers);
	if(alGetError() != AL_NO_ERROR)
		AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);

	try
	{
		m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
		int length;
		bool eos;

		for(int i = 0; i < CYCLE_BUFFERS; i++)
		{
			length = m_device->m_buffersize;
			reader->read(length, eos, m_device->m_buffer.getBuffer());
			alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
						 length * AUD_DEVICE_SAMPLE_SIZE(specs),
						 specs.rate);
			if(alGetError() != AL_NO_ERROR)
				AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
		}

		alGenSources(1, &m_source);
		if(alGetError() != AL_NO_ERROR)
			AUD_THROW(AUD_ERROR_OPENAL, gensource_error);

		try
		{
			alSourceQueueBuffers(m_source, CYCLE_BUFFERS,
								 m_buffers);
			if(alGetError() != AL_NO_ERROR)
				AUD_THROW(AUD_ERROR_OPENAL, queue_error);
		}
		catch(AUD_Exception&)
		{
			alDeleteSources(1, &m_source);
			throw;
		}
	}
	catch(AUD_Exception&)
	{
		alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
		throw;
	}
	alSourcei(m_source, AL_SOURCE_RELATIVE, 1);
}
Exemplo n.º 15
0
const char* 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)
{
	try
	{
		AUD_SequencerFactory* f = dynamic_cast<AUD_SequencerFactory*>(sound->get());

		f->setSpecs(specs.specs);

		std::vector<AUD_Reference<AUD_IWriter> > writers;

		int channels = specs.channels;
		specs.channels = AUD_CHANNELS_MONO;

		for(int i = 0; i < channels; i++)
		{
			std::stringstream stream;
			std::string fn = filename;
			size_t index = fn.find_last_of('.');
			size_t index_slash = fn.find_last_of('/');
			size_t index_backslash = fn.find_last_of('\\');
			if((index == std::string::npos) ||
					((index < index_slash) && (index_slash != std::string::npos)) ||
					((index < index_backslash) && (index_backslash != std::string::npos)))
				stream << filename << "_" << (i + 1);
			else
				stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
			writers.push_back(AUD_FileWriter::createWriter(stream.str(), specs, format, codec, bitrate));
		}

		AUD_Reference<AUD_IReader> reader = f->createQualityReader();
		reader->seek(start);
		AUD_FileWriter::writeReader(reader, writers, length, buffersize);

		return NULL;
	}
	catch(AUD_Exception& e)
	{
		return e.str;
	}
}
Exemplo n.º 16
0
AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in,
												 int out) :
		AUD_EffectReader(reader),
		m_specs(reader->getSpecs()),
		m_xlen(in), m_ylen(out),
		m_xpos(0), m_ypos(0), m_channel(0)
{
	m_x = new sample_t[m_xlen * m_specs.channels];
	m_y = new sample_t[m_ylen * m_specs.channels];

	memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
	memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
}
Exemplo n.º 17
0
void AUD_seekSequencer(AUD_Handle* handle, float time)
{
#ifdef WITH_JACK
	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
	if(device)
		device->seekPlayback(time);
	else
#endif
	{
		assert(handle);
		(*handle)->seek(time);
	}
}
Exemplo n.º 18
0
float AUD_getSequencerPosition(AUD_Handle* handle)
{
#ifdef WITH_JACK
	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
	if(device)
		return device->getPlaybackPosition();
	else
#endif
	{
		assert(handle);
		return (*handle)->getPosition();
	}
}
Exemplo n.º 19
0
AUD_Handle* AUD_play(AUD_Sound* sound, int keep)
{
	assert(sound);
	try
	{
		AUD_Handle handle = AUD_device->play(*sound, keep);
		if(!handle.isNull())
			return new AUD_Handle(handle);
	}
	catch(AUD_Exception&)
	{
	}
	return NULL;
}
Exemplo n.º 20
0
static PyObject* AUD_getCDevice(PyObject* self)
{
	if(!AUD_device.isNull())
	{
		Device* device = (Device*)Device_empty();
		if(device != NULL)
		{
			device->device = new AUD_Reference<AUD_IDevice>(AUD_device);
			return (PyObject*)device;
		}
	}

	Py_RETURN_NONE;
}
Exemplo n.º 21
0
AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
	AUD_Specs specs = reader->getSpecs();

	// check format
	if(specs.channels == AUD_CHANNELS_INVALID)
		return AUD_Reference<AUD_IHandle>();

	if(m_specs.format != AUD_FORMAT_FLOAT32)
		reader = new AUD_ConverterReader(reader, m_specs);

	ALenum format;

	if(!getFormat(format, specs))
		return AUD_Reference<AUD_IHandle>();

	lock();
	alcSuspendContext(m_context);

	AUD_Reference<AUD_OpenALDevice::AUD_OpenALHandle> sound;

	try
	{
		// create the handle
		sound = new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep);
	}
	catch(AUD_Exception&)
	{
		alcProcessContext(m_context);
		unlock();
		throw;
	}

	alcProcessContext(m_context);

	// play sound
	m_playingSounds.push_back(sound);

	start();

	unlock();

	return AUD_Reference<AUD_IHandle>(sound);
}
Exemplo n.º 22
0
AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader,
											 AUD_Specs specs) :
		AUD_ResampleReader(reader, specs.rate),
		m_channels(reader->getSpecs().channels),
		m_position(0)
{
	int error;
	m_src = src_callback_new(src_callback,
							 SRC_SINC_MEDIUM_QUALITY,
							 m_channels,
							 &error,
							 this);

	if(!m_src)
	{
		// XXX printf("%s\n", src_strerror(error));
		AUD_THROW(AUD_ERROR_SRC, state_error);
	}
}
Exemplo n.º 23
0
AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
	// prepare the reader
	// pitch

	AUD_Reference<AUD_PitchReader> pitch = new AUD_PitchReader(reader, 1);
	reader = AUD_Reference<AUD_IReader>(pitch);

	AUD_Reference<AUD_ResampleReader> resampler;

	// resample
	if(m_quality)
		resampler = new AUD_JOSResampleReader(reader, m_specs.specs);
	else
		resampler = new AUD_LinearResampleReader(reader, m_specs.specs);
	reader = AUD_Reference<AUD_IReader>(resampler);

	// rechannel
	AUD_Reference<AUD_ChannelMapperReader> mapper = new AUD_ChannelMapperReader(reader, m_specs.channels);
	reader = AUD_Reference<AUD_IReader>(mapper);

	if(reader.isNull())
		return AUD_Reference<AUD_IHandle>();

	// play sound
	AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound = new AUD_SoftwareDevice::AUD_SoftwareHandle(this, reader, pitch, resampler, mapper, keep);

	lock();
	m_playingSounds.push_back(sound);

	if(!m_playback)
		playing(m_playback = true);
	unlock();

	return AUD_Reference<AUD_IHandle>(sound);
}
Exemplo n.º 24
0
AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
	return play(factory->createReader(), keep);
}
Exemplo n.º 25
0
void AUD_SoftwareDevice::mix(data_t* buffer, int length)
{
	m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_specs));

	lock();

	{
		AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound;
		int len;
		int pos;
		bool eos;
		std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> > stopSounds;
		std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> > pauseSounds;
		sample_t* buf = m_buffer.getBuffer();

		m_mixer->clear(length);

		// for all sounds
		AUD_HandleIterator it = m_playingSounds.begin();
		while(it != m_playingSounds.end())
		{
			sound = *it;
			// increment the iterator to make sure it's valid,
			// in case the sound gets deleted after stopping
			++it;

			// get the buffer from the source
			pos = 0;
			len = length;

			// update 3D Info
			sound->update();

			sound->m_reader->read(len, eos, buf);

			// in case of looping
			while(pos + len < length && sound->m_loopcount && eos)
			{
				m_mixer->mix(buf, pos, len, sound->m_volume);

				pos += len;

				if(sound->m_loopcount > 0)
					sound->m_loopcount--;

				sound->m_reader->seek(0);

				len = length - pos;
				sound->m_reader->read(len, eos, buf);

				// prevent endless loop
				if(!len)
					break;
			}

			m_mixer->mix(buf, pos, len, sound->m_volume);

			// in case the end of the sound is reached
			if(eos && !sound->m_loopcount)
			{
				if(sound->m_stop)
					sound->m_stop(sound->m_stop_data);

				if(sound->m_keep)
					pauseSounds.push_back(sound);
				else
					stopSounds.push_back(sound);
			}
		}

		// superpose
		m_mixer->read(buffer, m_volume);

		// cleanup
		while(!stopSounds.empty())
		{
			sound = stopSounds.front();
			stopSounds.pop_front();
			sound->stop();
		}

		while(!pauseSounds.empty())
		{
			sound = pauseSounds.front();
			pauseSounds.pop_front();
			sound->pause();
		}
	}

	unlock();
}
Exemplo n.º 26
0
void AUD_unlock()
{
	AUD_device->unlock();
}
Exemplo n.º 27
0
void AUD_lock()
{
	AUD_device->lock();
}
Exemplo n.º 28
0
void AUD_OpenALDevice::updateStreams()
{
	AUD_Reference<AUD_OpenALHandle> sound;

	int length;

	ALint info;
	AUD_DeviceSpecs specs = m_specs;
	ALCenum cerr;
	std::list<AUD_Reference<AUD_OpenALHandle> > stopSounds;
	std::list<AUD_Reference<AUD_OpenALHandle> > pauseSounds;
	AUD_HandleIterator it;

	while(1)
	{
		lock();

		alcSuspendContext(m_context);
		cerr = alcGetError(m_device);
		if(cerr == ALC_NO_ERROR)
		{
			// for all sounds
			for(it = m_playingSounds.begin(); it != m_playingSounds.end(); it++)
			{
				sound = *it;

				// is it a streamed sound?
				if(!sound->m_isBuffered)
				{
					// check for buffer refilling
					alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info);

					if(info)
					{
						specs.specs = sound->m_reader->getSpecs();
						m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));

						// for all empty buffers
						while(info--)
						{
							// if there's still data to play back
							if(!sound->m_eos)
							{
								// read data
								length = m_buffersize;
								sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());

								// looping necessary?
								if(length == 0 && sound->m_loopcount)
								{
									if(sound->m_loopcount > 0)
										sound->m_loopcount--;

									sound->m_reader->seek(0);

									length = m_buffersize;
									sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
								}

								if(sound->m_loopcount != 0)
									sound->m_eos = false;

								// read nothing?
								if(length == 0)
								{
									break;
								}

								// unqueue buffer
								alSourceUnqueueBuffers(sound->m_source, 1,
												&sound->m_buffers[sound->m_current]);
								ALenum err;
								if((err = alGetError()) != AL_NO_ERROR)
								{
									sound->m_eos = true;
									break;
								}

								// fill with new data
								alBufferData(sound->m_buffers[sound->m_current],
											 sound->m_format,
											 m_buffer.getBuffer(), length *
											 AUD_DEVICE_SAMPLE_SIZE(specs),
											 specs.rate);

								if((err = alGetError()) != AL_NO_ERROR)
								{
									sound->m_eos = true;
									break;
								}

								// and queue again
								alSourceQueueBuffers(sound->m_source, 1,
												&sound->m_buffers[sound->m_current]);
								if(alGetError() != AL_NO_ERROR)
								{
									sound->m_eos = true;
									break;
								}

								sound->m_current = (sound->m_current+1) %
												 AUD_OpenALHandle::CYCLE_BUFFERS;
							}
							else
								break;
						}
					}
				}

				// check if the sound has been stopped
				alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info);

				if(info != AL_PLAYING)
				{
					// if it really stopped
					if(sound->m_eos)
					{
						if(sound->m_stop)
							sound->m_stop(sound->m_stop_data);

						// pause or
						if(sound->m_keep)
							pauseSounds.push_back(sound);
						// stop
						else
							stopSounds.push_back(sound);
					}
					// continue playing
					else
						alSourcePlay(sound->m_source);
				}
			}

			for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
				(*it)->pause();

			for(it = stopSounds.begin(); it != stopSounds.end(); it++)
				(*it)->stop();

			pauseSounds.clear();
			stopSounds.clear();

			alcProcessContext(m_context);
		}

		// stop thread
		if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
		{
			m_playing = false;
			unlock();
			pthread_exit(NULL);
		}

		unlock();

#ifdef WIN32
		Sleep(20);
#else
		usleep(20000);
#endif
	}
}
Exemplo n.º 29
0
void AUD_setSequencerDeviceSpecs(AUD_Sound* sequencer)
{
	dynamic_cast<AUD_SequencerFactory*>(sequencer->get())->setSpecs(AUD_device->getSpecs().specs);
}
Exemplo n.º 30
0
void AUD_setSyncCallback(AUD_syncFunction function, void* data)
{
	AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
	if(device)
		device->setSyncCallback(function, data);
}