|
@@ -80,34 +80,35 @@ class QueueTypeMismatchException : public love::Exception
|
|
public:
|
|
public:
|
|
|
|
|
|
QueueTypeMismatchException()
|
|
QueueTypeMismatchException()
|
|
- : Exception("Only \"queue\" type sound Sources can be queued with sound data.")
|
|
|
|
|
|
+ : Exception("Only queueable Sources can be queued with sound data.")
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
-class QueueNegativeLengthException : public love::Exception
|
|
|
|
|
|
+class QueueMalformedLengthException : public love::Exception
|
|
{
|
|
{
|
|
public:
|
|
public:
|
|
|
|
|
|
- QueueNegativeLengthException()
|
|
|
|
- : Exception("Data length cannot be negative.")
|
|
|
|
|
|
+ QueueMalformedLengthException(int bytes)
|
|
|
|
+ : Exception("Data length must be a multiple of sample size (%d bytes).", bytes)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
-class QueueMalformedLengthException : public love::Exception
|
|
|
|
|
|
+class QueueLoopingException : public love::Exception
|
|
{
|
|
{
|
|
public:
|
|
public:
|
|
|
|
|
|
- QueueMalformedLengthException(int bytes)
|
|
|
|
- : Exception("Data lenght must be a multiple of sample size (%d bytes).", bytes)
|
|
|
|
|
|
+ QueueLoopingException()
|
|
|
|
+ : Exception("Queueable Sources can not be looped.")
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+
|
|
StaticDataBuffer::StaticDataBuffer(ALenum format, const ALvoid *data, ALsizei size, ALsizei freq)
|
|
StaticDataBuffer::StaticDataBuffer(ALenum format, const ALvoid *data, ALsizei size, ALsizei freq)
|
|
: size(size)
|
|
: size(size)
|
|
{
|
|
{
|
|
@@ -317,10 +318,10 @@ bool Source::isPlaying() const
|
|
}
|
|
}
|
|
|
|
|
|
bool Source::isFinished() const
|
|
bool Source::isFinished() const
|
|
-{
|
|
|
|
|
|
+{
|
|
if (!valid)
|
|
if (!valid)
|
|
return false;
|
|
return false;
|
|
-
|
|
|
|
|
|
+
|
|
if (type == TYPE_STREAM && (isLooping() || !decoder->isFinished()))
|
|
if (type == TYPE_STREAM && (isLooping() || !decoder->isFinished()))
|
|
return false;
|
|
return false;
|
|
|
|
|
|
@@ -342,7 +343,7 @@ bool Source::update()
|
|
alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE);
|
|
alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE);
|
|
return !isFinished();
|
|
return !isFinished();
|
|
case TYPE_STREAM:
|
|
case TYPE_STREAM:
|
|
- if (isLooping() || !isFinished())
|
|
|
|
|
|
+ if (!isFinished())
|
|
{
|
|
{
|
|
ALint processed;
|
|
ALint processed;
|
|
ALuint buffers[MAX_BUFFERS];
|
|
ALuint buffers[MAX_BUFFERS];
|
|
@@ -696,6 +697,9 @@ bool Source::isRelative() const
|
|
|
|
|
|
void Source::setLooping(bool enable)
|
|
void Source::setLooping(bool enable)
|
|
{
|
|
{
|
|
|
|
+ if (type == TYPE_QUEUE)
|
|
|
|
+ throw QueueLoopingException();
|
|
|
|
+
|
|
if (valid && type == TYPE_STATIC)
|
|
if (valid && type == TYPE_STATIC)
|
|
alSourcei(source, AL_LOOPING, enable ? AL_TRUE : AL_FALSE);
|
|
alSourcei(source, AL_LOOPING, enable ? AL_TRUE : AL_FALSE);
|
|
|
|
|
|
@@ -707,25 +711,24 @@ bool Source::isLooping() const
|
|
return looping;
|
|
return looping;
|
|
}
|
|
}
|
|
|
|
|
|
-bool Source::queueData(void *data, int length, int dataSampleRate, int dataBitDepth, int dataChannels)
|
|
|
|
|
|
+bool Source::queue(void *data, int length, int dataSampleRate, int dataBitDepth, int dataChannels)
|
|
{
|
|
{
|
|
if (type != TYPE_QUEUE)
|
|
if (type != TYPE_QUEUE)
|
|
throw QueueTypeMismatchException();
|
|
throw QueueTypeMismatchException();
|
|
|
|
|
|
- if (length < 0)
|
|
|
|
- throw QueueNegativeLengthException();
|
|
|
|
-
|
|
|
|
if (dataSampleRate != sampleRate || dataBitDepth != bitDepth || dataChannels != channels )
|
|
if (dataSampleRate != sampleRate || dataBitDepth != bitDepth || dataChannels != channels )
|
|
throw QueueFormatMismatchException();
|
|
throw QueueFormatMismatchException();
|
|
|
|
|
|
if (length % (bitDepth / 8 * channels) != 0)
|
|
if (length % (bitDepth / 8 * channels) != 0)
|
|
throw QueueMalformedLengthException(bitDepth / 8 * channels);
|
|
throw QueueMalformedLengthException(bitDepth / 8 * channels);
|
|
|
|
|
|
- if (length > 0)
|
|
|
|
- return pool->queueData(this, data, (ALsizei)length);
|
|
|
|
|
|
+ if (length == 0)
|
|
|
|
+ return true;
|
|
|
|
+
|
|
|
|
+ return pool->queue(this, data, (ALsizei)length);
|
|
}
|
|
}
|
|
|
|
|
|
-bool Source::queueDataAtomic(void *data, ALsizei length)
|
|
|
|
|
|
+bool Source::queueAtomic(void *data, ALsizei length)
|
|
{
|
|
{
|
|
if (valid)
|
|
if (valid)
|
|
{
|
|
{
|
|
@@ -752,11 +755,17 @@ bool Source::queueDataAtomic(void *data, ALsizei length)
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
|
|
-bool Source::isQueueable() const
|
|
|
|
|
|
+int Source::getFreeBufferCount() const
|
|
{
|
|
{
|
|
- if (type != TYPE_QUEUE || (valid && unusedBufferTop < 0) || (!valid && unusedBufferTop >= (int)MAX_BUFFERS - 1))
|
|
|
|
- return false;
|
|
|
|
- return true;
|
|
|
|
|
|
+ switch (type) //why not :^)
|
|
|
|
+ {
|
|
|
|
+ case TYPE_STATIC:
|
|
|
|
+ return 0;
|
|
|
|
+ case TYPE_STREAM:
|
|
|
|
+ return unusedBufferTop + 1;
|
|
|
|
+ case TYPE_QUEUE:
|
|
|
|
+ return valid ? unusedBufferTop + 1 : (int)MAX_BUFFERS - unusedBufferTop - 1;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
void Source::prepareAtomic()
|
|
void Source::prepareAtomic()
|
|
@@ -799,7 +808,6 @@ void Source::prepareAtomic()
|
|
if (offsetSamples >= 0)
|
|
if (offsetSamples >= 0)
|
|
alSourcef(source, AL_SAMPLE_OFFSET, offsetSamples);
|
|
alSourcef(source, AL_SAMPLE_OFFSET, offsetSamples);
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -839,7 +847,6 @@ void Source::teardownAtomic()
|
|
//stack needs to be filled in reverse order
|
|
//stack needs to be filled in reverse order
|
|
for (unsigned int i = queued; i > 0; i--)
|
|
for (unsigned int i = queued; i > 0; i--)
|
|
{
|
|
{
|
|
- //since we only unqueue 1 buffer, it's OK to use singular variable pointer instead of array
|
|
|
|
alSourceUnqueueBuffers(source, 1, &buffer);
|
|
alSourceUnqueueBuffers(source, 1, &buffer);
|
|
unusedBufferPush(buffer);
|
|
unusedBufferPush(buffer);
|
|
}
|
|
}
|