Ejemplo n.º 1
0
void play_sound_p(Sound *snd) {
	if(tconfig.intval[NO_AUDIO] || snd->lastplayframe == global.frames)
		return;
	
	snd->lastplayframe = global.frames;
	
	ALuint i,res = -1;
	ALint play;
	for(i = 0; i < SNDSRC_COUNT; i++) {
		alGetSourcei(resources.sndsrc[i],AL_SOURCE_STATE,&play);
		if(play != AL_PLAYING) {
			res = i;
			break;
		}
	}
	
	if(res != -1) {
		alSourcei(resources.sndsrc[res],AL_BUFFER, snd->alsnd);
		alSourcePlay(resources.sndsrc[res]);
	} else {
		warnx("play_sound_p():\n!- not enough sources");
	}
}
Ejemplo n.º 2
0
nzSoundStatus NzSoundEmitter::GetInternalStatus() const
{
	ALint state;
	alGetSourcei(m_source, AL_SOURCE_STATE, &state);

	switch (state)
	{
		case AL_INITIAL:
		case AL_STOPPED:
			return nzSoundStatus_Stopped;

		case AL_PAUSED:
			return nzSoundStatus_Paused;

		case AL_PLAYING:
			return nzSoundStatus_Playing;

		default:
			NazaraInternalError("Source state unrecognized");
	}

	return nzSoundStatus_Stopped;
}
Ejemplo n.º 3
0
 void OpenALChannel::stop()
 {
    if (mUseStream)
    {
       if (mStream)
       {
          mStream->release();
          delete mStream;
          mStream = 0;
          mWasPlaying = false;
       }
    }
    else
    {
       ALint state;
       alGetSourcei(mSourceID, AL_SOURCE_STATE, &state);
       
       if (state == AL_PLAYING)
       {
          alSourceStop(mSourceID);
       }
    }
 }
Ejemplo n.º 4
0
//*
// =======================================================================================================================
// =======================================================================================================================
//
BOOL sound_SampleIsFinished( AUDIO_SAMPLE *psSample )
{
#ifndef WZ_NOSOUND
	//~~~~~~~~~~
	ALenum	state;
	//~~~~~~~~~~

	alGetSourcei( psSample->iSample, AL_SOURCE_STATE, &state );
	sound_GetError(); // check for an error and clear the error state for later on in this function
	if (state == AL_PLAYING || state == AL_PAUSED)
	{
		return false;
	}

	if (psSample->iSample != (ALuint)AL_INVALID)
	{
		alDeleteSources(1, &(psSample->iSample));
		sound_GetError();
		psSample->iSample = AL_INVALID;
	}
#endif
	return true;
}
void cSoundSourceStream::Step(){
	int processed = 0;

	if(RemainingBytes() == 0 && IsPlaying() && !IsPaused()){
		// sound is finished
		Stop();
	} else if(IsPlaying() && RemainingBytes() > 0){
		// read the number of played buffers
		alGetSourcei(miId, AL_BUFFERS_PROCESSED, &processed);
		CheckOpenAl();
		
		// and refill them
		while(processed--){
			ALuint buffer;
			alSourceUnqueueBuffers(miId, 1, &buffer);
			CheckOpenAl();
			StreamBuffer(buffer);		
			alSourceQueueBuffers(miId, 1, &buffer);
			CheckOpenAl();
			//printf("#### source step remaining=%i playing=%d paused=%d\n",mpStream->RemainingBytes(),IsPlaying(),IsPaused());
		}
	}
}
Ejemplo n.º 6
0
private_audio::AudioSource *AudioEngine::_AcquireAudioSource()
{
    // (1) Find and return the first source that does not have an owner
    for(std::vector<AudioSource *>::iterator i = _audio_sources.begin(); i != _audio_sources.end(); ++i) {
        if((*i)->owner == NULL) {
            return *i;
        }
    }

    // (2) If all sources are owned, find one that is in the initial or stopped state and change its ownership
    for(std::vector<AudioSource *>::iterator i = _audio_sources.begin(); i != _audio_sources.end(); ++i) {
        ALint state;
        alGetSourcei((*i)->source, AL_SOURCE_STATE, &state);
        if(state == AL_INITIAL || state == AL_STOPPED) {
            (*i)->owner->_source = NULL;
            (*i)->Reset(); // this call sets the source owner pointer to NULL
            return *i;
        }
    }

    // (3) Return NULL in the (extremely rare) case that all sources are owned and actively playing or paused
    return NULL;
}
Ejemplo n.º 7
0
//=================================================================================================
void Sounds::play()
{
  if (!file)
    return;

  ALint state;
  alGetSourcei( source, AL_SOURCE_STATE, &state );

  if (state == AL_PLAYING)
    return;

  if (state != AL_PAUSED && flag & STREAM)
  {
    file->read( buffer, BUFFER_SIZE );
    alBufferData( buffers[0], format, buffer, BUFFER_SIZE, file->freq );
    file->read( buffer, BUFFER_SIZE );
    alBufferData( buffers[1], format, buffer, BUFFER_SIZE, file->freq );
    alSourceQueueBuffers( source, 2, buffers );
    ALApp::addStream( this );
  }

  alSourcePlay( source );
}
Ejemplo n.º 8
0
/* Function: alureGetSourceOffset
 *
 * Gets the sample offset of the specified source. For sources started with
 * <alurePlaySourceStream>, this will be the total samples played. The offset
 * will loop back to 0 when the stream rewinds for any specified loopcount. For
 * non-streamed sources, the function will behave as if retrieving the
 * AL_SAMPLE_OFFSET source value.
 *
 * Returns:
 * (alureUInt)-1 on error.
 *
 * See Also:
 * <alurePlaySourceStream>
 */
ALURE_API alureUInt64 ALURE_APIENTRY alureGetSourceOffset(ALuint source)
{
	if(alGetError() != AL_NO_ERROR)
	{
		SetError("Existing OpenAL error");
		return (alureUInt64)-1;
	}

	EnterCriticalSection(&cs_StreamPlay);

	ALint pos;
	if((alGetSourcei(source, AL_SAMPLE_OFFSET, &pos),alGetError()) != AL_NO_ERROR)
	{
		LeaveCriticalSection(&cs_StreamPlay);
		SetError("Error retrieving source offset");
		return (alureUInt64)-1;
	}

	alureUInt64 retval = static_cast<ALuint>(pos);
	std::list<AsyncPlayEntry>::iterator i = AsyncPlayList.begin(),
	                                    end = AsyncPlayList.end();
	while(i != end)
	{
		if(i->source == source)
		{
			retval += i->base_time;
			if(i->max_time)
				retval %= i->max_time;
			break;
		}
		i++;
	}

	LeaveCriticalSection(&cs_StreamPlay);

	return retval;
}
Ejemplo n.º 9
0
    void hdW32SoundVoiceDevice::UpdateVoice()
    {
        if ( voice_ )
        {
            ALint processed;
            ALint queued;
            alGetSourceiv( voice_, AL_BUFFERS_PROCESSED, &processed );
            HEART_CHECK_OPENAL_ERRORS();
            alGetSourceiv( voice_, AL_BUFFERS_QUEUED, &queued );
            HEART_CHECK_OPENAL_ERRORS();
            if ( processed > 0 )
            {
                ALuint proBufs[BUFFER_COUNT];
                alSourceUnqueueBuffers( voice_, processed, proBufs );
                HEART_CHECK_OPENAL_ERRORS();
            }

            ALint playing;
            alGetSourcei( voice_, AL_SOURCE_STATE, &playing );
            HEART_CHECK_OPENAL_ERRORS();

            if ( queued && playing != AL_PLAYING && playing != AL_PAUSED )
            {
                alSourcePlay( voice_ );
            }

            if ( queued == 0 && sourceComplete_ == hTrue )
            {
                info_.callback_( this, VOICE_STOPPED );
            }

            if ( queued < BUFFER_COUNT && sourceComplete_ != hTrue )
            {
                info_.callback_( this, NEED_MORE_PCM_DATA );
            }
        }
    }
Ejemplo n.º 10
0
void FSoundManager::Update( F32 fDTime )
{
    FSoundIterator iIt = lSoundList.Begin();
    for( ;iIt != lSoundList.End(); )
    {
        ALint iSourceState;
        I32 iInd = iIt->GetSourceInd();
        alGetSourcei( lpSources[iInd].iSourceID, AL_SOURCE_STATE, &iSourceState );
        
        if( LogOpenAL() )
            NSLog( @"SourceID %d Index %ld", lpSources[iInd].iSourceID, iInd );
        
        if( (iSourceState == AL_PLAYING) || (iSourceState == AL_PAUSED) )
        {
            iIt++;
            continue;
        }
        
        delete *iIt;
        iIt = lSoundList.Erase( iIt );
    }
    
/*    for( I32 i = 0;i < iMaxSources;i++ )
    {
        ALint iSourceState;
        if( !lpSources[i].bBusy )
            continue;
        
        alGetSourcei( lpSources[i].iSourceID, AL_SOURCE_STATE, &iSourceState );
        LogOpenAL();
        if( (iSourceState == AL_PLAYING) || (iSourceState == AL_PAUSED) )
            continue;
        
        StopSound( lpSources[i].lpSoundObj );
        LogOpenAL();
    }*/
}
Ejemplo n.º 11
0
bool CStreamItem::IdleTask()
{
	AL_CHECK
	HandleFade();
	AL_CHECK

	int proc_state;
	alGetSourceiv(m_ALSource, AL_SOURCE_STATE, &proc_state);
	AL_CHECK
	
	if (proc_state == AL_STOPPED)
	{
		if (m_LastPlay)
			return (proc_state != AL_STOPPED);
	}
	else
	{
		COggData* tmp = (COggData*)m_SoundData;
		
		if (! tmp->IsFileFinished())
		{
			int num_processed;
			alGetSourcei(m_ALSource, AL_BUFFERS_PROCESSED, &num_processed);
			AL_CHECK
			
			if (num_processed > 0)
			{
				ALuint* al_buf = new ALuint[num_processed];
				alSourceUnqueueBuffers(m_ALSource, num_processed, al_buf);
				AL_CHECK
				int didWrite = tmp->FetchDataIntoBuffer(num_processed, al_buf);
				alSourceQueueBuffers(m_ALSource, didWrite, al_buf);
				AL_CHECK
				delete[] al_buf;
			}
		}
		else if (GetLooping())
Ejemplo n.º 12
0
bool SoundSource::_updateSound(Ogre::Real ElapsedTime)
{
	_update();
	if(mActive)
	{
		alSource3f(mSource, AL_POSITION, mDerivedPosition.x, mDerivedPosition.y, mDerivedPosition.z);
		alSource3f(mSource, AL_DIRECTION, mDerivedDirection.x, mDerivedDirection.y, mDerivedDirection.z);
		mBuffer->update(mSource, ElapsedTime);
		alGetSourcei(mSource, AL_SOURCE_STATE, &mState);
		SoundSystem::checkError(__FUNCTION__);

		updateDistanceAttenuation();
		updateEffectiveGain();
	}
	else 
	{
		switch(mState)
		{
		case AL_PLAYING:
			//if not looping and duration has passed stop
			if (mTimer->getPosition() > mBuffer->getDuration() && ! mLoop)
			{
				mTimer->stop();
				mState = AL_STOPPED;
			}
			break;
		case AL_STOPPED:
		case AL_INITIAL:
		case AL_PAUSED:
			//NOOP;
			break;
		}
	}

	return true;
}
int EOSAudioDevice::getAvailableSource()
{
	int state = -1;
	for(unsigned int handle=0; handle<sourcesHandle.size(); handle++)
	{
		alGetSourcei(sourcesHandle[handle], AL_SOURCE_STATE, &state);
        checkErrors("getAvailableSource[source status query]");

		if(state == AL_STOPPED || state == AL_INITIAL)
		{
		    resetSource(sourcesHandle[handle]);
		    return sourcesHandle[handle];
		}
	}

    // reset error status
    int alError = alGetError();
    _skippedSounds++;

	//checkErrors("GetAvailableSource()");
	//LOGERROR("[eos.audio] getAvailableSource() -> No available sources.");

	return SOURCE_NONE;
}
Ejemplo n.º 14
0
	void ActiveSound::clear()
	{
		if(mActive)
		{
			if(!mData.mBuffer->isOgg())
			{
				ALint state;
				alGetSourcei(mSource,AL_SOURCE_STATE,&state);
				alSourceStop(mSource);
				alSourcei(mSource,AL_BUFFER,AL_NONE);
				mActive = false;
			}
			else
			{
				mActive = false;
				mOgg->release();
			}

			if (alGetError() != AL_NO_ERROR)
			{
				//add log message here
			}
		}
	}
Ejemplo n.º 15
0
int SoundManager::_getSource(bool reserved)
{
	// Find a unused source
	ALint state;
	
	//LOOP - Search in container
	for( unsigned int i=0; i < mSources.size(); i++)
	{
		//If - Not reserved
		if (!mSources[i].reserved)
		{
			// Check if it is being used
			alGetSourcei(mSources[i].source,AL_SOURCE_STATE, &state);
			if (state != AL_PLAYING && state != AL_PAUSED)
			{
				mSources[i].reserved = reserved;
				return i;
			}			
		}
	}//LOOP
		
	//All sources are used
	return -1;
}
Ejemplo n.º 16
0
void CBufferItem::ReleaseOpenALBuffer()
{
	if ( m_ALSource == 0 )
		return;

	int num_processed;
	AL_CHECK;
	alGetSourcei(m_ALSource, AL_BUFFERS_PROCESSED, &num_processed);
	AL_CHECK;

	if (num_processed > 0)
	{
		ALuint* al_buf = new ALuint[num_processed];
		alSourceUnqueueBuffers(m_ALSource, num_processed, al_buf);
		
		AL_CHECK;
		delete[] al_buf;
	}
	alSourcei(m_ALSource, AL_BUFFER, 0);
	((CSoundManager*)g_SoundManager)->ReleaseALSource(m_ALSource);
	AL_CHECK;

	m_ALSource = 0;
}
Ejemplo n.º 17
0
DWORD WINAPI stream_run(void * data)
{
  SoundThread * me = (SoundThread *) data;
  while(me->running) {
    if(me->sound) {
      Sound * sound = me->sound;
      ALuint uiSource;
      ALint iState = AL_PLAYING;
      ALuint uiBuffers[1];

      alGenBuffers(1, uiBuffers);
      alGenSources(1, &uiSource);
      alBufferData(uiBuffers[0], sound->format, sound->data, sound->size, sound->freq);
      assert(AL_NO_ERROR == alGetError());
      alSourceQueueBuffers(uiSource, 1, &uiBuffers[0]);
      alSourcef(uiSource, AL_GAIN, sound->volume);
      alSourcePlay(uiSource);

      while(iState == AL_PLAYING) {
        Sleep(16);
        alGetSourcei(uiSource, AL_SOURCE_STATE, &iState);
      }

      alSourceStop(uiSource);
      alSourcei(uiSource, AL_BUFFER, 0);

      alDeleteSources(1, &uiSource);
      alDeleteBuffers(1, uiBuffers);

      me->occupied = false;
      me->sound = 0;
    }
    if(me->running) SuspendThread(me->handle);
  }
  return 0;
}
Ejemplo n.º 18
0
void playSound() {
    char * sound [] = {"scale-a6.wav", "scale-c6.wav", "scale-c7.wav"
        , "scale-d6.wav", "scale-e6.wav", "scale-f6.wav",
        "scale-g6.wav", "scale-h6.wav"};
    int index = rand() % 8;
    ALuint buffer, source;
    ALuint state;

    // Initialize the environment
    alutInit(0, NULL);

    // Capture errors
    alGetError();

    // Load pcm data into buffer
    buffer = alutCreateBufferFromFile(sound[index]);

    // Create sound source (use buffer to fill source)
    alGenSources(1, &source);
    alSourcei(source, AL_BUFFER, buffer);

    // Play
    alSourcePlay(source);

    // Wait for the song to complete
    do {
        alGetSourcei(source, AL_SOURCE_STATE, &state);
    } while (state == AL_PLAYING);

    // Clean up sources and buffers
    alDeleteSources(1, &source);
    alDeleteBuffers(1, &buffer);

    // Exit everything
    alutExit();
}
Ejemplo n.º 19
0
/**
 * @brief Play a 44100Hz mono 16bit PCM sound
 */
void OpenAL::playMono16Sound(const QByteArray& data)
{
    QMutexLocker locker(&audioLock);

    if (!autoInitOutput())
        return;

    if (!alMainBuffer)
        alGenBuffers(1, &alMainBuffer);

    ALint state;
    alGetSourcei(alMainSource, AL_SOURCE_STATE, &state);
    if (state == AL_PLAYING) {
        alSourceStop(alMainSource);
        alSourcei(alMainSource, AL_BUFFER, AL_NONE);
    }

    alBufferData(alMainBuffer, AL_FORMAT_MONO16, data.constData(), data.size(), 44100);
    alSourcei(alMainSource, AL_BUFFER, static_cast<ALint>(alMainBuffer));
    alSourcePlay(alMainSource);

    int durationMs = data.size() * 1000 / 2 / 44100;
    playMono16Timer.start(durationMs + 50);
}
Ejemplo n.º 20
0
static void slider_changed(GtkRange *progressbar, struct arguments *argument) {
    if(fabs(gtk_adjustment_get_value(argument->adjust) - g_timer_elapsed(argument->elapsed, NULL) - argument->offset) > 0.005f) {
        argument->offset = gtk_adjustment_get_value(argument->adjust);
        alSourcei(source, AL_BUFFER, 0);
        alDeleteSources(1, &source);
        ALenum format;
        ALuint buffer;
        alSourcei(source, AL_BUFFER, 0);
        g_timer_start(argument->elapsed);
        alGenBuffers(1, &buffer);
        alGenSources(1, &source);
        format = AL_FORMAT_STEREO16;
        alBufferData(buffer, format, current_sample_array + channels * (int) ((gdouble) (nb_bytes_per_sample * sample_rate) * (gdouble) gtk_adjustment_get_value(argument->adjust)), (nSamples - (int) ( (gdouble) gtk_adjustment_get_value(argument->adjust) * (gdouble) sample_rate )) * sizeof(ALint), sample_rate);
        alSourcei(source, AL_BUFFER, buffer);
        alGetSourcei(source, AL_SOURCE_STATE, &status);
        alSourcePlay(source);
        g_source_remove(argument->tag);

        if(argument->continue_count != 0) {
            argument->tag = g_timeout_add_seconds(current_song.duration - (int)gtk_adjustment_get_value(argument->adjust), endless, argument);
        }
        argument->bartag = g_timeout_add_seconds(1, timer_progressbar, argument);
    }
}
Ejemplo n.º 21
0
static void unqueue_old_buffers(int stream) {
    audio_stream *s = g_streams[stream];
    ALint old_buffers = 0;
    g_mutex_lock(s->mutex);
    // locking here because unqueue_old_buffers can be run called from
    // both the video thread and the emulation thread (consider changing this,
    // perhaps even have a separate thread for periodically unqueuing).
    alGetSourcei(s->source, AL_BUFFERS_PROCESSED, &old_buffers);
    check_al_error("alGetSourcei (AL_BUFFERS_PROCESSED)");

    if (old_buffers > 0) {
        ALuint buffers[MAX_BUFFERS];
        old_buffers = MIN(old_buffers, MAX_BUFFERS);
        alSourceUnqueueBuffers(s->source, old_buffers, buffers);
        if (check_al_error("alSourceUnqueueBuffers") != AL_NO_ERROR) {
            fs_log("while trying to unqueue %d buffers\n");
        }
        for (int i = 0; i < old_buffers; i++) {
            g_queue_push_tail(s->queue, GUINT_TO_POINTER(buffers[i]));
        }
        s->buffers_queued -= old_buffers;
    }
    g_mutex_unlock(s->mutex);
}
Ejemplo n.º 22
0
	// 缓冲区复位以便于从头播放
	/////////////////////////////////////////////////////////////////////////////////
	void OALMusicBuffer::DoReset()
	{
		ALint queued_;
		alGetSourcei(source_, AL_BUFFERS_QUEUED, &queued_);
		if (queued_ > 0)
		{
			std::vector<ALuint> cur_queue(queued_);
			alSourceUnqueueBuffers(source_, queued_, &cur_queue[0]);
		}

		ALenum const format(Convert(format_));
		std::vector<uint8_t> data(READSIZE);

		dataSource_->Reset();

		ALsizei non_empty_buf = 0;
		// 每个缓冲区中装1 / PreSecond秒的数据
		for (auto const & buf : bufferQueue_)
		{
			data.resize(dataSource_->Read(&data[0], data.size()));
			if (data.empty())
			{
				break;
			}
			else
			{
				++ non_empty_buf;
				alBufferData(buf, format, &data[0],
					static_cast<ALuint>(data.size()), static_cast<ALuint>(freq_));
			}
		}

		alSourceQueueBuffers(source_, non_empty_buf, &bufferQueue_[0]);

		alSourceRewindv(1, &source_);
	}
//-----------------------------------------------------------
//ofxAA
vector<float>& ofSoundPlayerExtended::getCurrentBufferForChannel(int _size, int channel){
    
    if(int(currentBuffer.size()) != _size)
    {
        currentBuffer.resize(_size);
    }
   	currentBuffer.assign(currentBuffer.size(),0);
    
    int nCh = channel; //channels number starting from 0
    if (nCh >= channels){
        nCh = channels - 1;//limit to file nChannels
        ofLog(OF_LOG_WARNING,"ofSoundPlayerExtended: channel requested exceeds file channels");
    }
    
    int pos;
    for(int k = 0; k < int(sources.size())/channels; ++k)
    {
        alGetSourcei(sources[k*channels],AL_SAMPLE_OFFSET,&pos);
        //for(int i = 0; i < channels; ++i) //avoid channels sumup
        int i = nCh; //use only specified channel
        {
            for(int j = 0; j < _size; ++j)
            {
                if(pos+j<(int)buffer.size())
                {
                    currentBuffer[j] += float(buffer[(pos+j)*channels+i])/65534.0f;
                }
                else
                {
                    currentBuffer[j] = 0;
                }
            }
        }
    }
    return currentBuffer;
}
Ejemplo n.º 24
0
void dll_al_GetSourcei(ALuint source, ALenum param, ALint *value) { alGetSourcei(source, param, value); }
Ejemplo n.º 25
0
    //-----------------------------------------------------------------------------
    void MusicStream::_update(float deltatime)
    {
        if (mMusic != 0)
        {
            ALenum srcState;
            int    processed;
            size_t buffers[2];

            // Updates fading
            switch (mFade)
            {
                case MF_FADE_IN:
                    mFadeVolume += mFadeSpd*deltatime;

                    if (mFadeVolume >= 1.0f)
                    {
                        // Stop fading
                        mFadeVolume = 1.0f;
                        mFade = MF_NO_FADE;
                        mAudioMan->_fadeEnded(MF_FADE_IN);
                    }
                break;

                case MF_FADE_OUT:
                    mFadeVolume -= mFadeSpd*deltatime;

                    if (mFadeVolume <= 0.0f)
                    {
                        // Stop fading
                        mFadeVolume = 0.0f;
                        mFade = MF_NO_FADE;

                        mAudioMan->_fadeEnded(MF_FADE_OUT);

                        switch (mState)
                        {
                            case MSS_PAUSING:
                                alSourcePause(mMusicSrc);
                                mAudioMan->_alErrorCheck("MusicStream::_update()",
                                        "Failed pausing music source");
                            break;

                            case MSS_STOPPING:
                                alSourceStop(mMusicSrc);
                                mAudioMan->_alErrorCheck("MusicStream::_update()",
                                        "Failed stopping music source");
                            break;

                            default: break;
                        }
                    }
                break;

                default: break;
            }

            // Sets source volume
            alSourcef(mMusicSrc,AL_GAIN,mFadeVolume * mMaxVolume *
                    mAudioMan->getMasterMusicVolume());
            mAudioMan->_alErrorCheck("MusicStream::_update()",
                                    "Failed setting music source volume");

            // Refills processed buffer with more data from the stream
            alGetSourcei(mMusicSrc,AL_BUFFERS_PROCESSED,&processed);
            mAudioMan->_alErrorCheck("MusicStream::_update()",
                    "Failed getting number of processed buffers from music source");

            alSourceUnqueueBuffers(mMusicSrc,processed,buffers);
            mAudioMan->_alErrorCheck("MusicStream::_update()",
                    "Failed unqueuing processed buffers from music source");

            for (int i = 0;i < processed;++i)
            {
                if (mState == MSS_ENDED)
                {
                    mAudioMan->_streamEnded();
                    break;
                }

                // Gets more data from OGG/Vorbis stream and queue it back
                pullStream(buffers[i]);
                alSourceQueueBuffers(mMusicSrc,1,&buffers[i]);
                mAudioMan->_alErrorCheck("MusicStream::_update()",
                        "Failed queueing audio buffer in music source");
            }

            // Makes sure the music doesn't stuck stopped
            // It may happen when you drag the window for too long
            alGetSourcei(mMusicSrc,AL_SOURCE_STATE,&srcState);
            mAudioMan->_alErrorCheck("MusicStream::_update()",
                    "Failed getting music source state");

            if (srcState == AL_STOPPED)
            {
                if (mState != MSS_ENDED)
                {
                    alSourcePlay(mMusicSrc);
                    mAudioMan->_alErrorCheck("MusicStream::_update()",
                            "Failed playing music source");
                }
            }
        }

        _getCurrentPos();
    }
Ejemplo n.º 26
0
void Sound::Impl::PlaySound(const boost::filesystem::path& path, bool is_ui_sound/* = false*/) {
    if (!m_initialized || !GetOptionsDB().Get<bool>("UI.sound.enabled") || (is_ui_sound && UISoundsTemporarilyDisabled()))
        return;

    std::string filename = PathString(path);
    ALuint current_buffer;
    ALenum source_state;
    ALsizei ogg_freq;
    FILE *file = nullptr;
    int m_i;
    bool found_buffer = false;
    bool found_source = false;

#ifdef FREEORION_WIN32
    ov_callbacks callbacks = {

    (size_t (*)(void *, size_t, size_t, void *))  fread,

    (int (*)(void *, ogg_int64_t, int))           _fseek64_wrap,

    (int (*)(void *))                             fclose,

    (long (*)(void *))                            ftell

    };
#endif

    if (alcGetCurrentContext()) {
        /* First check if the sound data of the file we want to play is already buffered somewhere */
        std::map<std::string, ALuint>::iterator it = m_buffers.find(filename);
        if (it != m_buffers.end()) {
            current_buffer = it->second;
            found_buffer = true;
        } else {
            if ((file = fopen(filename.c_str(), "rb")) != nullptr) { // make sure we CAN open it
                OggVorbis_File ogg_file;
                vorbis_info *vorbis_info;
                ALenum ogg_format;
#ifdef FREEORION_WIN32
                if (!(ov_test_callbacks(file, &ogg_file, nullptr, 0, callbacks))) // check if it's a proper ogg
#else
                if (!(ov_test(file, &ogg_file, nullptr, 0))) // check if it's a proper ogg
#endif
                {
                    ov_test_open(&ogg_file); // it is, now fully open the file
                    /* now we need to take some info we will need later */
                    vorbis_info = ov_info(&ogg_file, -1);
                    if (vorbis_info->channels == 1)
                        ogg_format = AL_FORMAT_MONO16;
                    else
                        ogg_format = AL_FORMAT_STEREO16;
                    ogg_freq = vorbis_info->rate;
                    ogg_int64_t byte_size = ov_pcm_total(&ogg_file, -1) * vorbis_info->channels * 2;
                    if (byte_size <= 1024 * 1024 * 1024) {
                        /* fill up the buffers and queue them up for the first time */
                        ALuint sound_handle;
                        alGenBuffers(1, &sound_handle);

                        int loop = 0;

                        RefillBuffer(&ogg_file, ogg_format, ogg_freq, sound_handle, byte_size, loop);

                        current_buffer = sound_handle;
                        found_buffer = true;
                        m_buffers.insert(std::make_pair(filename, sound_handle));
                    }
                    else
                    {
                        ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " too big to buffer. Aborting\n";
                    }
                    ov_clear(&ogg_file);
                }
                else
                {
                    ErrorLogger() << "PlaySound: unable to open file " << filename.c_str() << " possibly not a .ogg vorbis file. Aborting\n";
                }
            }
        }
        if (found_buffer) {
            /* Now that we have the buffer, we need to find a source to send it to */
            for (m_i = 1; m_i < NUM_SOURCES; ++m_i) {   // as we're playing sounds we start at 1. 0 is reserved for music
                alGetSourcei(m_sources[m_i], AL_SOURCE_STATE, &source_state);
                if ((source_state != AL_PLAYING) && (source_state != AL_PAUSED)) {
                    found_source = true;
                    alSourcei(m_sources[m_i], AL_BUFFER, current_buffer);
                    alSourcePlay(m_sources[m_i]);
                    break; // so that the sound won't block all the sources
                }
            }
            if (!found_source)
                ErrorLogger() << "PlaySound: Could not find aviable source - playback aborted\n";
        }
        source_state = alGetError();
        if (source_state != AL_NONE)
            ErrorLogger() << "PlaySound: OpenAL ERROR: " << alGetString(source_state);
            /* it's important to check for errors, as some functions won't work properly if
             * they're called when there is a unchecked previous error. */
    }
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
bool SoundVoice::CheckPlaying()
{
	ALint state = 0;
	alGetSourcei(m_source, AL_SOURCE_STATE, &state);
	return state == AL_PLAYING || state == AL_PAUSED;
}
Ejemplo n.º 28
0
 void SoundChannel::QueueBuffers()
 {
     // See that we do have waiting sounds and they're ready to play
     if (!pending_sounds_.size())
         return;
     if ((*pending_sounds_.begin())->GetHandle() == 0)
         return;
     
     // Create source now if did not exist already
     if (!CreateSource())
     {
         state_ = Foundation::SoundServiceInterface::Stopped;
         pending_sounds_.clear();
         return;
     }
     
     bool queued = false;
     
     // Buffer pending sounds, move them to playing vector
     while (pending_sounds_.size())
     {
         SoundPtr sound = *pending_sounds_.begin();
         ALuint buffer = sound->GetHandle();
         // If no valid handle yet, cannot play this one, break out
         if (!buffer)
             return;
         
         alGetError();
         alSourceQueueBuffers(handle_, 1, &buffer);
         ALenum error = alGetError();
         
         if (error != AL_NONE)
         {
             // If queuing fails, we may have changed sound format. Stop, flush queue & retry
             alSourceStop(handle_);
             alSourcei(handle_, AL_BUFFER, 0);
             alSourceQueueBuffers(handle_, 1, &buffer);
             ALenum error = alGetError();
             if (error != AL_NONE)
                 OpenALAudioModule::LogError("Could not queue OpenAL sound buffer: " + ToString<int>(error));
             else
             {
                 playing_sounds_.push_back(sound);
                 queued = true;
             }
         }
         else
         {
             playing_sounds_.push_back(sound);
             queued = true;
         }
         
         pending_sounds_.pop_front();
     }
     
     // If at least one sound queued, start playback if not already playing
     if (queued)
     {
         ALint playing;
         alGetSourcei(handle_, AL_SOURCE_STATE, &playing);
         if (playing != AL_PLAYING)
             alSourcePlay(handle_);
         state_ = Foundation::SoundServiceInterface::Playing;
     }
 }
Ejemplo n.º 29
0
static gint
gst_openal_sink_write (GstAudioSink * audiosink, gpointer data, guint length)
{
  GstOpenALSink *sink = GST_OPENAL_SINK (audiosink);
  ALint processed, queued, state;
  ALCcontext *old;
  gulong rest_us;

  g_assert (length == sink->buffer_length);

  old = pushContext (sink->default_context);

  rest_us =
      (guint64) (sink->buffer_length / sink->bytes_per_sample) *
      G_USEC_PER_SEC / sink->rate / sink->channels;
  do {
    alGetSourcei (sink->default_source, AL_SOURCE_STATE, &state);
    alGetSourcei (sink->default_source, AL_BUFFERS_QUEUED, &queued);
    alGetSourcei (sink->default_source, AL_BUFFERS_PROCESSED, &processed);
    if (checkALError () != AL_NO_ERROR) {
      GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
          ("Source state error detected"));
      length = 0;
      goto out_nolock;
    }

    if (processed > 0 || queued < sink->buffer_count)
      break;
    if (state != AL_PLAYING)
      alSourcePlay (sink->default_source);
    g_usleep (rest_us);
  }
  while (1);

  GST_OPENAL_SINK_LOCK (sink);
  if (sink->write_reset != AL_FALSE) {
    sink->write_reset = AL_FALSE;
    length = 0;
    goto out;
  }

  queued -= processed;
  while (processed-- > 0) {
    ALuint bid;
    alSourceUnqueueBuffers (sink->default_source, 1, &bid);
  }
  if (state == AL_STOPPED) {
    /* "Restore" from underruns (not actually needed, but it keeps delay
     * calculations correct while rebuffering) */
    alSourceRewind (sink->default_source);
  }

  alBufferData (sink->buffers[sink->buffer_idx], sink->format,
      data, sink->buffer_length, sink->rate);
  alSourceQueueBuffers (sink->default_source, 1,
      &sink->buffers[sink->buffer_idx]);
  sink->buffer_idx = (sink->buffer_idx + 1) % sink->buffer_count;
  queued++;

  if (state != AL_PLAYING && queued == sink->buffer_count)
    alSourcePlay (sink->default_source);

  if (checkALError () != AL_NO_ERROR) {
    GST_ELEMENT_ERROR (sink, RESOURCE, WRITE, (NULL),
        ("Source queue error detected"));
    goto out;
  }

out:
  GST_OPENAL_SINK_UNLOCK (sink);
out_nolock:
  popContext (old, sink->default_context);
  return length;
}
Ejemplo n.º 30
0
// Creates and initializes an audio context.
int ai_context_create(struct cen64_ai_context *context) {
  uint8_t buf[8];
  unsigned i;

  context->cur_frequency = 31985;

  if ((context->dev = alcOpenDevice(NULL)) == NULL) {
    printf("Failed to open the OpenAL device.\n");
    return 1;
  }

  if ((context->ctx = alcCreateContext(context->dev, NULL)) == NULL) {
    printf("Failed to create an OpenAL context.\n");
    alcCloseDevice(context->dev);
    return 1;
  }

  alcMakeContextCurrent(context->ctx);

  // Context/device is setup, create some buffers and a source.
  alGenBuffers(sizeof(context->buffers) / sizeof(*context->buffers),
    context->buffers);

  if (alGetError() != AL_NO_ERROR) {
    alcMakeContextCurrent(NULL);
    alcDestroyContext(context->ctx);
    alcCloseDevice(context->dev);
  }

  alGenSources(1, &context->source);

  if (alGetError() != AL_NO_ERROR) {
    alDeleteBuffers(sizeof(context->buffers) / sizeof(*context->buffers),
      context->buffers);

    alcMakeContextCurrent(NULL);
    alcDestroyContext(context->ctx);
    alcCloseDevice(context->dev);
  }

  // Queue/prime buffers, clear them to prevent pops.
  // Playing a little test also allows us to verify
  // that we (probably) won't get weird OpenAL errors
  // later on if things work now.
  memset(buf, 0x0, sizeof(buf));

  for (i = 0; i < sizeof(context->buffers) / sizeof(*context->buffers); i++)
    alBufferData(context->buffers[i], AL_FORMAT_STEREO16,
      buf, sizeof(buf), context->cur_frequency);

  alSourceQueueBuffers(context->source,
    sizeof(context->buffers) / sizeof(*context->buffers),
    context->buffers);

  alSourcePlay(context->source);

  if (alGetError() != AL_NO_ERROR) {
    ai_context_destroy(context);
    return 1;
  }

  // Now wait for them to drain.
  while (1) {
    ALint val;

    alGetSourcei(context->source, AL_BUFFERS_PROCESSED, &val);

    if (val == (sizeof(context->buffers) / sizeof(*context->buffers)))
      break;
  }

  if (alGetError() != AL_NO_ERROR) {
    ai_context_destroy(context);
    return 1;
  }

  context->unqueued_buffers = 0;
  return 0;
}