SoundSource::SoundSource()
{
    priv::ensureALInit();

    alCheck(alGenSources(1, &m_source));
    alCheck(alSourcei(m_source, AL_BUFFER, 0));
}
Beispiel #2
0
mad_flow MADStream::ms_output(void* user, mad_header const* header,
                              mad_pcm* pcm) {
    RW_UNUSED(header);

    MADStream* self = static_cast<MADStream*>(user);

    if (self->stopped) {
        return MAD_FLOW_STOP;
    }

    if (!self->numFreeBuffers) {
        ALint buffersProcessed;
        do {
            /**
             * Sleep a bit while waiting for OpenAL buffers to become available.
             * The number is arbitrary and depends on the size of the
             * buffer/audio samples,
             * as well as how quickly the computer can feed more buffers into
             * OpenAL.
             */
            std::this_thread::sleep_for(std::chrono::milliseconds(20));
            alGetSourcei(self->alSource, AL_BUFFERS_PROCESSED,
                         &buffersProcessed);
        } while (buffersProcessed <= 0);

        alCheck(alSourceUnqueueBuffers(self->alSource, buffersProcessed,
                                       self->unqueuedBuffers));
        self->numFreeBuffers += buffersProcessed;
    }

    int nsamples = pcm->length;
    mad_fixed_t const *left, *right;

    left = pcm->samples[0];
    right = pcm->samples[1];

    int s = 0;
    while (nsamples--) {
        signed int sample = *left++;
        self->mCurrentSamples.push_back(scale(sample));

        sample = *right++;
        self->mCurrentSamples.push_back(scale(sample));
        s++;
    }

    alCheck(alBufferData(self->buffers[self->currentBuffer], AL_FORMAT_STEREO16,
                         self->mCurrentSamples.data(),
                         self->mCurrentSamples.size() * sizeof(uint16_t),
                         pcm->samplerate));
    alCheck(alSourceQueueBuffers(self->alSource, 1,
                                 self->buffers + self->currentBuffer));

    self->mCurrentSamples.clear();
    self->currentBuffer++;
    self->currentBuffer %= numALbuffers;
    self->numFreeBuffers--;

    return MAD_FLOW_CONTINUE;
}
Beispiel #3
0
bool SoundStream::fillAndPushBuffer(unsigned int bufferNum, bool immediateLoop)
{
    bool requestStop = false;

    // Acquire audio data, also address EOF and error cases if they occur
    Chunk data = {NULL, 0};
    for (Uint32 retryCount = 0; !onGetData(data) && (retryCount < BufferRetries); ++retryCount)
    {
        // Mark the buffer as the last one (so that we know when to reset the playing position)
        m_endBuffers[bufferNum] = true;

        // Check if the stream must loop or stop
        if (!m_loop)
        {
            // Not looping: request stop
            requestStop = true;
            break;
        }

        // Return to the beginning of the stream source
        onSeek(Time::Zero);

        // If we got data, break and process it, else try to fill the buffer once again
        if (data.samples && data.sampleCount)
            break;

        // If immediateLoop is specified, we have to immediately adjust the sample count
        if (immediateLoop)
        {
            // We just tried to begin preloading at EOF: reset the sample count
            m_samplesProcessed = 0;
            m_endBuffers[bufferNum] = false;
        }

        // We're a looping sound that got no data, so we retry onGetData()
    }

    // Fill the buffer if some data was returned
    if (data.samples && data.sampleCount)
    {
        unsigned int buffer = m_buffers[bufferNum];

        // Fill the buffer
        ALsizei size = static_cast<ALsizei>(data.sampleCount) * sizeof(Int16);
        alCheck(alBufferData(buffer, m_format, data.samples, size, m_sampleRate));

        // Push it into the sound queue
        alCheck(alSourceQueueBuffers(m_source, 1, &buffer));
    }
    else
    {
        // If we get here, we most likely ran out of retries
        requestStop = true;
    }

    return requestStop;
}
Beispiel #4
0
void SoundStream::clearQueue()
{
    // Get the number of buffers still in the queue
    ALint nbQueued;
    alCheck(alGetSourcei(m_source, AL_BUFFERS_QUEUED, &nbQueued));

    // Unqueue them all
    ALuint buffer;
    for (ALint i = 0; i < nbQueued; ++i)
        alCheck(alSourceUnqueueBuffers(m_source, 1, &buffer));
}
Beispiel #5
0
SoundSource::SoundSource(const SoundSource& copy)
{
    alCheck(alGenSources(1, &m_source));
    alCheck(alSourcei(m_source, AL_BUFFER, 0));

    setPitch(copy.getPitch());
    setVolume(copy.getVolume());
    setPosition(copy.getPosition());
    setRelativeToListener(copy.isRelativeToListener());
    setMinDistance(copy.getMinDistance());
    setAttenuation(copy.getAttenuation());
}
Beispiel #6
0
bool SoundManager::SoundBuffer::bufferData(SoundSource& soundSource)
{
	alCheck(alBufferData(
		buffer,
		soundSource.fileInfo.channels == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
		&soundSource.data.front(),
		soundSource.data.size() * sizeof(uint16_t),
		soundSource.fileInfo.samplerate
	));
	alCheck(alSourcei(source, AL_BUFFER, buffer));

	return true;
}
Beispiel #7
0
Time Sound::getPlayingOffset() const
{
    ALfloat secs = 0.f;
    alCheck(alGetSourcef(m_source, AL_SEC_OFFSET, &secs));

    return seconds(secs);
}
Beispiel #8
0
bool Sound::getLoop() const
{
    ALint loop;
    alCheck(alGetSourcei(m_source, AL_LOOPING, &loop));

    return loop != 0;
}
void Listener::setDirection(float x, float y, float z)
{
    priv::ensureALInit();

    float orientation[] = {x, y, z, 0.f, 1.f, 0.f};
    alCheck(alListenerfv(AL_ORIENTATION, orientation));
}
Beispiel #10
0
bool SoundBuffer::update(unsigned int channelCount, unsigned int sampleRate)
{
    // Check parameters
    if (!channelCount || !sampleRate || m_samples.empty())
        return false;

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

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

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

    // Compute the duration
    m_duration = seconds(static_cast<float>(m_samples.size()) / sampleRate / channelCount);

    return true;
}
Beispiel #11
0
Vector3f Listener::getDirection()
{
    float orientation[6];
    alCheck(alGetListenerfv(AL_ORIENTATION, orientation));

    return Vector3f(orientation[0], orientation[1], orientation[2]);
}
Beispiel #12
0
Vector3f Listener::getPosition()
{
    Vector3f position;
    alCheck(alGetListener3f(AL_POSITION, &position.x, &position.y, &position.z));

    return position;
}
Beispiel #13
0
float Listener::getGlobalVolume()
{
    float volume = 0.f;
    alCheck(alGetListenerf(AL_GAIN, &volume));

    return volume * 100;
}
Beispiel #14
0
Channel::Channel()
{
    alGenSources(1, &m_source);

    if (alCheck())
    {
        GetLogger()->Debug("Failed to create sound source. Code: %d\n", alGetCode());
        m_ready = false;
    }
    else
    {
        m_ready = true;
    }

    m_priority = 0;
    m_buffer = nullptr;
    m_loop = false;
    m_mute = false;
    m_initFrequency = 0.0f;
    m_startAmplitude = 0.0f;
    m_startFrequency = 0.0f;
    m_changeFrequency = 0.0f;
    m_volume = 0.0f;
    m_id = 0;
}
Beispiel #15
0
SoundBuffer::SoundBuffer() :
m_buffer  (0),
m_duration()
{
    // Create the buffer
    alCheck(alGenBuffers(1, &m_buffer));
}
Beispiel #16
0
unsigned int SoundBuffer::getChannelCount() const
{
    ALint channelCount;
    alCheck(alGetBufferi(m_buffer, AL_CHANNELS, &channelCount));

    return channelCount;
}
Beispiel #17
0
float SoundSource::getPitch() const
{
    ALfloat pitch;
    alCheck(alGetSourcef(m_source, AL_PITCH, &pitch));

    return pitch;
}
Beispiel #18
0
void AudioDevice::setPosition(const Vector3f& position)
{
    if (audioContext)
        alCheck(alListener3f(AL_POSITION, position.x, position.y, position.z));

    listenerPosition = position;
}
Beispiel #19
0
unsigned int SoundBuffer::getSampleRate() const
{
    ALint sampleRate;
    alCheck(alGetBufferi(m_buffer, AL_FREQUENCY, &sampleRate));

    return sampleRate;
}
Beispiel #20
0
float SoundSource::getAttenuation() const
{
    ALfloat attenuation;
    alCheck(alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &attenuation));

    return attenuation;
}
Beispiel #21
0
void AudioDevice::setGlobalVolume(float volume)
{
    if (audioContext)
        alCheck(alListenerf(AL_GAIN, volume * 0.01f));

    listenerVolume = volume;
}
Beispiel #22
0
float SoundSource::getMinDistance() const
{
    ALfloat distance;
    alCheck(alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &distance));

    return distance;
}
Beispiel #23
0
bool SoundSource::isRelativeToListener() const
{
    ALint relative;
    alCheck(alGetSourcei(m_source, AL_SOURCE_RELATIVE, &relative));

    return relative != 0;
}
Beispiel #24
0
Vector3f SoundSource::getPosition() const
{
    Vector3f position;
    alCheck(alGetSource3f(m_source, AL_POSITION, &position.x, &position.y, &position.z));

    return position;
}
Beispiel #25
0
float SoundSource::getVolume() const
{
    ALfloat gain;
    alCheck(alGetSourcef(m_source, AL_GAIN, &gain));

    return gain * 100.f;
}
Beispiel #26
0
Source::~Source()
{
    stop();
    if (id)
    {
        alCheck(alDeleteSources(1, &id));
    }
}
Beispiel #27
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)
        m_endBuffers[bufferNum] = true;

        // Check if the stream must loop or stop
        if (m_loop)
        {
            // Return to the beginning of the stream source
            onSeek(Time::Zero);

            // 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 = m_buffers[bufferNum];

        // Fill the buffer
        ALsizei size = static_cast<ALsizei>(data.sampleCount) * sizeof(Int16);
        alCheck(alBufferData(buffer, m_format, data.samples, size, m_sampleRate));

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

    return requestStop;
}
Beispiel #28
0
SoundBuffer::SoundBuffer() :
m_buffer  (0),
m_duration()
{
    priv::ensureALInit();

    // Create the buffer
    alCheck(alGenBuffers(1, &m_buffer));
}
float Listener::getGlobalVolume()
{
    priv::ensureALInit();

    float volume = 0.f;
    alCheck(alGetListenerf(AL_GAIN, &volume));

    return volume * 100;
}
Vector3f Listener::getPosition()
{
    priv::ensureALInit();

    Vector3f position;
    alCheck(alGetListener3f(AL_POSITION, &position.x, &position.y, &position.z));

    return position;
}