Beispiel #1
0
void SoundStream::ClearQueue()
{
    // Get the number of buffers still in the queue
    ALint nbQueued;
    ALCheck(alGetSourcei(mySource, AL_BUFFERS_QUEUED, &nbQueued));

    // Unqueue them all
    ALuint buffer;
    for (ALint i = 0; i < nbQueued; ++i)
        ALCheck(alSourceUnqueueBuffers(mySource, 1, &buffer));
}
Beispiel #2
0
////////////////////////////////////////////////////////////
/// Get the current value of the global volume of all the sounds
////////////////////////////////////////////////////////////
float Listener::GetGlobalVolume()
{
    float Volume = 0.f;
    ALCheck(alGetListenerf(AL_GAIN, &Volume));

    return Volume;
}
Beispiel #3
0
////////////////////////////////////////////////////////////
/// Get the sample rate
////////////////////////////////////////////////////////////
unsigned int SoundBuffer::GetSampleRate() const
{
    ALint SampleRate;
    ALCheck(alGetBufferi(myBuffer, AL_FREQUENCY, &SampleRate));

    return SampleRate;
}
Beispiel #4
0
float Sound::GetPlayingOffset() const
{
    ALfloat seconds = 0.f;
    ALCheck(alGetSourcef(mySource, AL_SEC_OFFSET, &seconds));

    return seconds;
}
Beispiel #5
0
////////////////////////////////////////////////////////////
/// Return the number of channels (1 = mono, 2 = stereo, ...)
////////////////////////////////////////////////////////////
unsigned int SoundBuffer::GetChannelsCount() const
{
    ALint ChannelsCount;
    ALCheck(alGetBufferi(myBuffer, AL_CHANNELS, &ChannelsCount));

    return ChannelsCount;
}
Beispiel #6
0
bool Sound::GetLoop() const
{
    ALint loop;
    ALCheck(alGetSourcei(mySource, AL_LOOPING, &loop));

    return loop != 0;
}
Beispiel #7
0
////////////////////////////////////////////////////////////
/// Default constructor
////////////////////////////////////////////////////////////
SoundBuffer::SoundBuffer() :
myBuffer  (0),
myDuration(0.f)
{
    // Create the buffer
    ALCheck(alGenBuffers(1, &myBuffer));
}
Beispiel #8
0
////////////////////////////////////////////////////////////
/// Update the internal buffer with the audio samples
////////////////////////////////////////////////////////////
bool SoundBuffer::Update(unsigned int ChannelsCount, unsigned int SampleRate)
{
    // Check parameters
    if (!SampleRate || !ChannelsCount || mySamples.empty())
        return false;

    // Find the good format according to the number of channels
    ALenum Format = priv::AudioDevice::GetInstance().GetFormatFromChannelsCount(ChannelsCount);

    // Check if the format is valid
    if (Format == 0)
    {
        std::cerr << "Unsupported number of channels (" << ChannelsCount << ")" << std::endl;
        return false;
    }

    // Fill the buffer
    ALsizei Size = static_cast<ALsizei>(mySamples.size()) * sizeof(Int16);
    ALCheck(alBufferData(myBuffer, Format, &mySamples[0], Size, SampleRate));

    // Compute the duration
    myDuration = static_cast<float>(mySamples.size()) / SampleRate / ChannelsCount;

    return true;
}
Beispiel #9
0
bool SoundBuffer::Update(unsigned int channelsCount, unsigned int sampleRate)
{
    // Check parameters
    if (!channelsCount || !sampleRate || mySamples.empty())
        return false;

    // Find the good format according to the number of channels
    ALenum format = priv::AudioDevice::GetFormatFromChannelsCount(channelsCount);

    // Check if the format is valid
    if (format == 0)
    {
        Err() << "Failed to load sound buffer (unsupported number of channels: " << channelsCount << ")" << std::endl;
        return false;
    }

    // Fill the buffer
    ALsizei size = static_cast<ALsizei>(mySamples.size()) * sizeof(Int16);
    ALCheck(alBufferData(myBuffer, format, &mySamples[0], size, sampleRate));

    // Compute the duration
    myDuration = static_cast<Uint32>(1000 * mySamples.size() / sampleRate / channelsCount);

    return true;
}
Beispiel #10
0
////////////////////////////////////////////////////////////
/// Get the current position of the listener
////////////////////////////////////////////////////////////
ofxVec3f Listener::GetPosition()
{
    ofxVec3f Position;
    ALCheck(alGetListener3f(AL_POSITION, &Position.x, &Position.y, &Position.z));

    return Position;
}
Beispiel #11
0
Uint32 SoundStream::GetPlayingOffset() const
{
    ALfloat seconds = 0.f;
    ALCheck(alGetSourcef(mySource, AL_SEC_OFFSET, &seconds));

    return static_cast<Uint32>(1000 * seconds + 1000 * mySamplesProcessed / mySampleRate / myChannelCount);
}
Beispiel #12
0
////////////////////////////////////////////////////////////
/// Get the current orientation of the listener (the point
/// he's looking at)
////////////////////////////////////////////////////////////
ofxVec3f Listener::GetTarget()
{
    float Orientation[6];
    ALCheck(alGetListenerfv(AL_ORIENTATION, Orientation));

    return ofxVec3f(Orientation[0], Orientation[1], Orientation[2]);
}
Beispiel #13
0
bool SoundStream::FillAndPushBuffer(unsigned int bufferNum)
{
    bool requestStop = false;

    // Acquire audio data
    Chunk data = {NULL, 0};
    if (!OnGetData(data))
    {
        // Mark the buffer as the last one (so that we know when to reset the playing position)
        myEndBuffers[bufferNum] = true;

        // Check if the stream must loop or stop
        if (myLoop)
        {
            // Return to the beginning of the stream source
            OnSeek(0);

            // If we previously had no data, try to fill the buffer once again
            if (!data.Samples || (data.SampleCount == 0))
            {
                return FillAndPushBuffer(bufferNum);
            }
        }
        else
        {
            // Not looping: request stop
            requestStop = true;
        }
    }

    // Fill the buffer if some data was returned
    if (data.Samples && data.SampleCount)
    {
        unsigned int buffer = myBuffers[bufferNum];

        // Fill the buffer
        ALsizei size = static_cast<ALsizei>(data.SampleCount) * sizeof(Int16);
        ALCheck(alBufferData(buffer, myFormat, data.Samples, size, mySampleRate));

        // Push it into the sound queue
        ALCheck(alSourceQueueBuffers(mySource, 1, &buffer));
    }

    return requestStop;
}
Beispiel #14
0
void Sound::ResetBuffer()
{
    // First stop the sound in case it is playing
    Stop();

    // Detach the buffer
    ALCheck(alSourcei(mySource, AL_BUFFER, 0));
    myBuffer = NULL;
}
Beispiel #15
0
SoundBuffer::SoundBuffer() :
myBuffer  (0),
myDuration(0)
{
    priv::EnsureALInit();

    // Create the buffer
    ALCheck(alGenBuffers(1, &myBuffer));
}
Beispiel #16
0
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
SoundBuffer::~SoundBuffer()
{
    // First detach the buffer from the sounds that use it (to avoid OpenAL errors)
    for (SoundList::const_iterator it = mySounds.begin(); it != mySounds.end(); ++it)
        (*it)->ResetBuffer();

    // Destroy the buffer
    if (myBuffer)
        ALCheck(alDeleteBuffers(1, &myBuffer));
}
Beispiel #17
0
////////////////////////////////////////////////////////////
/// Fill a new buffer with audio data, and push it to the
/// playing queue
////////////////////////////////////////////////////////////
bool SoundStream::FillAndPushBuffer(unsigned int BufferNum)
{
    bool RequestStop = false;

    // Acquire audio data
    Chunk Data = {NULL, 0};
    if (!OnGetData(Data))
    {
        // Mark the buffer as the last one (so that we know when to reset the playing position)
        myEndBuffers[BufferNum] = true;

        // Check if the stream must loop or stop
        if (myLoop && OnStart())
        {
            // If we succeeded to restart and we previously had no data, try to fill the buffer once again
            if (!Data.Samples || (Data.NbSamples == 0))
            {
                return FillAndPushBuffer(BufferNum);
            }
        }
        else
        {
            // Not looping or restart failed: request stop
            RequestStop = true;
        }
    }

    // Fill the buffer if some data was returned
    if (Data.Samples && Data.NbSamples)
    {
        unsigned int Buffer = myBuffers[BufferNum];

        // Fill the buffer
        ALsizei Size = static_cast<ALsizei>(Data.NbSamples) * sizeof(Int16);
        ALCheck(alBufferData(Buffer, myFormat, Data.Samples, Size, mySampleRate));

        // Push it into the sound queue
        ALCheck(alSourceQueueBuffers(Sound::mySource, 1, &Buffer));
    }

    return RequestStop;
}
Beispiel #18
0
////////////////////////////////////////////////////////////
/// Copy constructor
////////////////////////////////////////////////////////////
SoundBuffer::SoundBuffer(const SoundBuffer& Copy) :
AudioResource(Copy),
myBuffer     (0),
mySamples    (Copy.mySamples),
myDuration   (Copy.myDuration)
{
    // Create the buffer
    ALCheck(alGenBuffers(1, &myBuffer));

    // Update the internal buffer with the new samples
    Update(Copy.GetChannelsCount(), Copy.GetSampleRate());
}
Beispiel #19
0
SoundBuffer::SoundBuffer(const SoundBuffer& copy) :
myBuffer  (0),
mySamples (copy.mySamples),
myDuration(copy.myDuration),
mySounds  () // don't copy the attached sounds
{
    // Create the buffer
    ALCheck(alGenBuffers(1, &myBuffer));

    // Update the internal buffer with the new samples
    Update(copy.GetChannelsCount(), copy.GetSampleRate());
}
Beispiel #20
0
////////////////////////////////////////////////////////////
/// Destroy all sound data and buffer
////////////////////////////////////////////////////////////
void SoundBufferDestroy()
{
	Int32 i = 0;

	for (i = 0; i < SOUND_BUFFER_SIZE; i++)
	{
		if (SoundData[i].Buffer != 0)
		{
			// Stop sound
			SoundStop(&SoundData[i]);

			// Delete source
			ALCheck(alDeleteSources(1, &SoundData[i].Source));

			// Delete buffer
			ALCheck(alDeleteBuffers(1, &SoundData[i].Buffer));

			// Free data
			Delete(SoundData[i].Samples);
		}
	}
}
Beispiel #21
0
////////////////////////////////////////////////////////////
/// Fill a new buffer with audio data, and push it to the
/// playing queue
////////////////////////////////////////////////////////////
bool SoundStream::FillAndPushBuffer(unsigned int Buffer)
{
    bool RequestStop = false;

    // Acquire audio data
    Chunk Data = {NULL, 0};
    if (!OnGetData(Data))
        RequestStop = true;

    // Create and fill the buffer, and push it to the queue
    if (Data.Samples && Data.NbSamples)
    {
        // Fill the buffer
        ALsizei Size = static_cast<ALsizei>(Data.NbSamples) * sizeof(Int16);
        ALCheck(alBufferData(Buffer, myFormat, Data.Samples, Size, mySampleRate));

        // Push it into the sound queue
        ALCheck(alSourceQueueBuffers(Sound::mySource, 1, &Buffer));
    }

    return RequestStop;
}
Beispiel #22
0
void Sound::SetBuffer(const SoundBuffer& buffer)
{
    // First detach from the previous buffer
    if (myBuffer)
    {
        Stop();
        myBuffer->DetachSound(this);
    }

    // Assign and use the new buffer
    myBuffer = &buffer;
    myBuffer->AttachSound(this);
    ALCheck(alSourcei(mySource, AL_BUFFER, myBuffer->myBuffer));
}
Beispiel #23
0
void SoundStream::Play()
{
    // Check if the sound parameters have been set
    if (myFormat == 0)
    {
        Err() << "Failed to play audio stream: sound parameters have not been initialized (call Initialize first)" << std::endl;
        return;
    }

    // If the sound is already playing (probably paused), just resume it
    if (myIsStreaming)
    {
        ALCheck(alSourcePlay(mySource));
        return;
    }

    // Move to the beginning
    OnSeek(0);

    // Start updating the stream in a separate thread to avoid blocking the application
    mySamplesProcessed = 0;
    myIsStreaming = true;
    myThread.Launch();
}
Beispiel #24
0
////////////////////////////////////////////////////////////
/// Load sound into buffer
////////////////////////////////////////////////////////////
void SoundBufferLoad(struct Sound * SoundStruct, char * File)
{
	UInt32 MinorTime = 0; // Minor time means the most old file
	UInt32 Dimension = 0; // Dimension found
	Int32 i = 0;

	// Search if the sound is loaded
	for (i = 0; i < SOUND_BUFFER_SIZE; i++)
	{
		if (SoundData[i].File != NULL)
		{
			if (strcmp(SoundData[i].File, File) == 0)
			{
				// The sound is loaded.. just play it
				SoundStruct = &SoundData[i];
				return;
			}
		}
	}

	// Search free sound
	for (i = 0; i < SOUND_BUFFER_SIZE; i++)
	{
		if (SoundData[i].Buffer == 0)
		{
			// Load sound
			if (SOUND_FROM_MEMORY)
			{
				char * BufferData;
				UInt32 BufferSize;

				// Load buffer from pack
				// if (!PackLoadData(File, BufferData, &BufferSize))
				// {
				//	return;
				// }

				// Load buffer data from memory
				if (SoundFileOpenReadFromMemory(SoundStruct, BufferData, BufferSize))
				{
					// Destroy data
					Delete(BufferData);
					return;
				}
			}
			else
			{
				if (SoundFileOpenReadFromFile(SoundStruct, File))
				{
					strcpy(SoundStruct->File, File);
					return;
				}
			}
		}
	}

	// Search last used
	for (i = 0; i < SOUND_BUFFER_SIZE; i++)
	{
		if (SoundStatus(&SoundData[i]) == Stopped)
		{
			if (SoundData[i].Time < MinorTime)
			{
				MinorTime = SoundData[i].Time;
				Dimension = i;
			}
		}
	}

	if (MinorTime != 0)
	{
		if (SoundData[Dimension].Buffer != 0)
		{
			// Remove data from the previous sound
			ALCheck(alDeleteBuffers(1, &SoundData[Dimension].Buffer));

			// Delete source
			ALCheck(alDeleteSources(1, &SoundData[Dimension].Source));
		}

		// Return last used
		SoundStruct = &SoundData[Dimension];
	}
	else
	{
		// There isn't sounds available
		SoundStruct = NULL;
	}
}
Beispiel #25
0
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
SoundBuffer::~SoundBuffer()
{
    if (myBuffer)
        ALCheck(alDeleteBuffers(1, &myBuffer));
}
Beispiel #26
0
void Sound::SetPlayingOffset(float timeOffset)
{
    ALCheck(alSourcef(mySource, AL_SEC_OFFSET, timeOffset));
}
Beispiel #27
0
void Sound::Play()
{
    ALCheck(alSourcePlay(mySource));
}
Beispiel #28
0
void Sound::Stop()
{
    ALCheck(alSourceStop(mySource));
}
Beispiel #29
0
void SoundStream::Stream()
{
    // Create the buffers
    ALCheck(alGenBuffers(BufferCount, myBuffers));
    for (int i = 0; i < BufferCount; ++i)
        myEndBuffers[i] = false;

    // Fill the queue
    bool requestStop = FillQueue();

    // Play the sound
    ALCheck(alSourcePlay(mySource));

    while (myIsStreaming)
    {
        // The stream has been interrupted!
        if (SoundSource::GetStatus() == Stopped)
        {
            if (!requestStop)
            {
                // Just continue
                ALCheck(alSourcePlay(mySource));
            }
            else
            {
                // End streaming
                myIsStreaming = false;
            }
        }

        // Get the number of buffers that have been processed (ie. ready for reuse)
        ALint nbProcessed = 0;
        ALCheck(alGetSourcei(mySource, AL_BUFFERS_PROCESSED, &nbProcessed));

        while (nbProcessed--)
        {
            // Pop the first unused buffer from the queue
            ALuint buffer;
            ALCheck(alSourceUnqueueBuffers(mySource, 1, &buffer));

            // Find its number
            unsigned int bufferNum = 0;
            for (int i = 0; i < BufferCount; ++i)
                if (myBuffers[i] == buffer)
                {
                    bufferNum = i;
                    break;
                }

            // Retrieve its size and add it to the samples count
            if (myEndBuffers[bufferNum])
            {
                // This was the last buffer: reset the sample count
                mySamplesProcessed = 0;
                myEndBuffers[bufferNum] = false;
            }
            else
            {
                ALint size, bits;
                ALCheck(alGetBufferi(buffer, AL_SIZE, &size));
                ALCheck(alGetBufferi(buffer, AL_BITS, &bits));
                mySamplesProcessed += size / (bits / 8);
            }

            // Fill it and push it back into the playing queue
            if (!requestStop)
            {
                if (FillAndPushBuffer(bufferNum))
                    requestStop = true;
            }
        }

        // Leave some time for the other threads if the stream is still playing
        if (SoundSource::GetStatus() != Stopped)
            Sleep(10);
    }

    // Stop the playback
    ALCheck(alSourceStop(mySource));

    // Unqueue any buffer left in the queue
    ClearQueue();

    // Delete the buffers
    ALCheck(alSourcei(mySource, AL_BUFFER, 0));
    ALCheck(alDeleteBuffers(BufferCount, myBuffers));
}
Beispiel #30
0
void SoundStream::Pause()
{
    ALCheck(alSourcePause(mySource));
}