/** ** Fill audio thread. */ static int FillThread(void *) { while (Audio.Running == true) { SDL_LockMutex(Audio.Lock); #ifdef USE_WIN32 // This is kind of a hackfix, without this on windows audio can get sluggish if (SDL_CondWaitTimeout(Audio.Cond, Audio.Lock, 1000) == 0) { #else if (SDL_CondWaitTimeout(Audio.Cond, Audio.Lock, 100) == 0) { #endif MixIntoBuffer(Audio.Buffer, Audio.Format.samples * Audio.Format.channels); } SDL_UnlockMutex(Audio.Lock); } SDL_LockMutex(Audio.Lock); // Mustn't call SDL_CloseAudio here, it'll be called again from SDL_Quit SDL_DestroyCond(Audio.Cond); SDL_DestroyMutex(Audio.Lock); return 0; } /*---------------------------------------------------------------------------- -- Effects ----------------------------------------------------------------------------*/ /** ** Check if this sound is already playing */ bool SampleIsPlaying(CSample *sample) { for (int i = 0; i < MaxChannels; ++i) { if (Channels[i].Sample == sample && Channels[i].Playing) { return true; } } return false; } bool UnitSoundIsPlaying(Origin *origin) { for (int i = 0; i < MaxChannels; ++i) { if (origin && Channels[i].Unit && origin->Id && Channels[i].Unit->Id && origin->Id == Channels[i].Unit->Id && Channels[i].Playing) { return true; } } return false; } /** ** A channel is finished playing */ static void ChannelFinished(int channel) { if (Channels[channel].FinishedCallback) { Channels[channel].FinishedCallback(channel); } delete Channels[channel].Unit; Channels[channel].Unit = NULL; Channels[channel].Playing = false; Channels[channel].Point = NextFreeChannel; NextFreeChannel = channel; } /** ** Put a sound request in the next free channel. */ static int FillChannel(CSample *sample, unsigned char volume, char stereo, Origin *origin) { Assert(NextFreeChannel < MaxChannels); int old_free = NextFreeChannel; int next_free = Channels[NextFreeChannel].Point; Channels[NextFreeChannel].Volume = volume; Channels[NextFreeChannel].Point = 0; Channels[NextFreeChannel].Playing = true; Channels[NextFreeChannel].Sample = sample; Channels[NextFreeChannel].Stereo = stereo; Channels[NextFreeChannel].FinishedCallback = NULL; if (origin && origin->Base) { Origin *source = new Origin; source->Base = origin->Base; source->Id = origin->Id; Channels[NextFreeChannel].Unit = source; } NextFreeChannel = next_free; return old_free; }
void RageSoundDriver::Mix( float *pBuf, int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame ) { memset( pBuf, 0, iFrames*channels*sizeof(float) ); MixIntoBuffer( iFrames, iFrameNumber, iCurrentFrame ).read( pBuf ); }
void RageSoundDriver::MixDeinterlaced( float **pBufs, int channels, int iFrames, int64_t iFrameNumber, int64_t iCurrentFrame ) { for (int i = 0; i < channels; ++i ) memset( pBufs[i], 0, iFrames*sizeof(float) ); MixIntoBuffer( iFrames, iFrameNumber, iCurrentFrame ).read_deinterlace( pBufs, channels ); }
/** ** Fill audio thread. */ static int FillThread(void *) { while (Audio.Running == true) { int status = SDL_LockMutex(Audio.Lock); #ifdef USE_WIN32 if (SDL_CondWaitTimeout(Audio.Cond, Audio.Lock, 1000) == 0) { #else if (SDL_CondWaitTimeout(Audio.Cond, Audio.Lock, 100) == 0) { #endif MixIntoBuffer(Audio.Buffer, Audio.Format.samples * Audio.Format.channels); } SDL_UnlockMutex(Audio.Lock); #ifdef USE_OAML if (enableOAML && oaml) oaml->Update(); #endif } return 0; } /*---------------------------------------------------------------------------- -- Effects ----------------------------------------------------------------------------*/ /** ** Check if this sound is already playing */ bool SampleIsPlaying(CSample *sample) { for (int i = 0; i < MaxChannels; ++i) { if (Channels[i].Sample == sample && Channels[i].Playing) { return true; } } return false; } bool UnitSoundIsPlaying(Origin *origin) { for (int i = 0; i < MaxChannels; ++i) { //Wyrmgus start // if (origin && Channels[i].Unit && origin->Id && Channels[i].Unit->Id // && origin->Id == Channels[i].Unit->Id && Channels[i].Playing) { if ( origin && Channels[i].Playing && Channels[i].Voice != -1 && Channels[i].Voice != VoiceHit && Channels[i].Voice != VoiceMiss && Channels[i].Voice != VoiceStep && Channels[i].Unit && origin->Id && Channels[i].Unit->Id && origin->Id == Channels[i].Unit->Id ) { //Wyrmgus end return true; } } return false; } /** ** A channel is finished playing */ static void ChannelFinished(int channel) { if (Channels[channel].FinishedCallback) { Channels[channel].FinishedCallback(channel); } //Wyrmgus start // delete Channels[channel].Unit; if (Channels[channel].Unit) { delete Channels[channel].Unit; } //Wyrmgus end Channels[channel].Unit = NULL; //Wyrmgus start Channels[channel].Voice = -1; //Wyrmgus end Channels[channel].Playing = false; Channels[channel].Point = NextFreeChannel; NextFreeChannel = channel; } /** ** Put a sound request in the next free channel. */ static int FillChannel(CSample *sample, unsigned char volume, char stereo, Origin *origin) { Assert(NextFreeChannel < MaxChannels); int old_free = NextFreeChannel; int next_free = Channels[NextFreeChannel].Point; Channels[NextFreeChannel].Volume = volume; Channels[NextFreeChannel].Point = 0; //Wyrmgus start Channels[NextFreeChannel].Voice = -1; //Wyrmgus end Channels[NextFreeChannel].Playing = true; Channels[NextFreeChannel].Sample = sample; Channels[NextFreeChannel].Stereo = stereo; Channels[NextFreeChannel].FinishedCallback = NULL; //Wyrmgus start Channels[NextFreeChannel].Unit = NULL; //Wyrmgus end if (origin && origin->Base) { Origin *source = new Origin; source->Base = origin->Base; source->Id = origin->Id; Channels[NextFreeChannel].Unit = source; } NextFreeChannel = next_free; return old_free; }