int SD_GetChannelForDigi(int which) { int channel; if(DigiChannel[which] != -1) return DigiChannel[which]; channel = Mix_GroupAvailable(1); if(channel == -1) channel = Mix_GroupOldest(1); if(channel == -1) /* All sounds stopped in the meantime? */ return Mix_GroupAvailable(1); return channel; }
/** * Sets the button as the pressed button if it's part of a group. * @param action Pointer to an action. * @param state State that the action handlers belong to. */ void TextButton::mousePress(Action *action, State *state) { if (action->getDetails()->button.button == SDL_BUTTON_LEFT && _group != 0) { TextButton *old = *_group; *_group = this; if (old != 0) old->draw(); draw(); } if (isButtonHandled(action->getDetails()->button.button)) { if (soundPress != 0 && _group == 0 && action->getDetails()->button.button != SDL_BUTTON_WHEELUP && action->getDetails()->button.button != SDL_BUTTON_WHEELDOWN) { soundPress->play(Mix_GroupAvailable(0)); } if (_comboBox) { _comboBox->toggle(); } draw(); //_redraw = true; } InteractiveSurface::mousePress(action, state); }
/** * Plays the window popup animation. */ void Window::popup() { if (AreSame(_popupStep, 0.0)) { int sound = SDL_GetTicks() % 3; // this is a hack to avoid calling RNG::generate(0, 2) and skewing our seed. if (soundPopup[sound] != 0) { soundPopup[sound]->play(Mix_GroupAvailable(0)); } } if (_popupStep < 1.0) { _popupStep += POPUP_SPEED; } else { if (_screen) { _state->toggleScreen(); } _state->showAll(); _popupStep = 1.0; _timer->stop(); } _redraw = true; }
/** * @brief Plays a sound in a group. * * @param group Group to play sound in. * @param sound Sound to play. * @param once Whether to play only once. * @return 0 on success. */ int sound_mix_playGroup( int group, alSound *s, int once ) { int ret, channel; /* Get the channel. */ channel = Mix_GroupAvailable(group); if (channel == -1) { channel = Mix_GroupOldest(group); if (channel == -1) { WARN("Group '%d' has no free channels!", group); return -1; } } /* Play the sound. */ ret = Mix_PlayChannel( channel, s->u.mix.buf, (once == 0) ? -1 : 0 ); if (ret < 0) { WARN("Unable to play sound %s for group %d: %s", s->name, group, Mix_GetError()); return -1; } else Mix_Volume( channel, sound_mixVolume ); return 0; }
/** Start a compressed sound channel */ static glui32 play_compressed(schanid_t chan, char *ext) { SDL_LockAudio(); chan->status = CHANNEL_SOUND; chan->buffered = 1; chan->sdl_channel = Mix_GroupAvailable(FREE); Mix_GroupChannel(chan->sdl_channel, BUSY); SDL_UnlockAudio(); chan->decode = Sound_NewSample(chan->sdl_rwops, ext, output, 65536); Uint32 soundbytes = Sound_Decode(chan->decode); Sound_Sample *sample = chan->decode; chan->sample = Mix_QuickLoad_RAW(sample->buffer, soundbytes); if (chan->sdl_channel < 0) gli_strict_warning("No available sound channels"); if (chan->sdl_channel >= 0 && chan->sample) { SDL_LockAudio(); sound_channels[chan->sdl_channel] = chan; SDL_UnlockAudio(); Mix_Volume(chan->sdl_channel, chan->volume); Mix_ChannelFinished(&sound_completion_callback); if (Mix_PlayChannel(chan->sdl_channel, chan->sample, 0) >= 0) return 1; } gli_strict_warning("play sound failed"); gli_strict_warning(Mix_GetError()); SDL_LockAudio(); cleanup_channel(chan); SDL_UnlockAudio(); return 0; }
/** Start a sound channel */ static glui32 play_sound(schanid_t chan) { SDL_LockAudio(); chan->status = CHANNEL_SOUND; chan->buffered = 0; chan->sdl_channel = Mix_GroupAvailable(FREE); Mix_GroupChannel(chan->sdl_channel, BUSY); SDL_UnlockAudio(); chan->sample = Mix_LoadWAV_RW(chan->sdl_rwops, FALSE); if (chan->sdl_channel < 0) { gli_strict_warning("No available sound channels"); } if (chan->sdl_channel >= 0 && chan->sample) { SDL_LockAudio(); sound_channels[chan->sdl_channel] = chan; SDL_UnlockAudio(); Mix_Volume(chan->sdl_channel, chan->volume); Mix_ChannelFinished(&sound_completion_callback); if (Mix_PlayChannel(chan->sdl_channel, chan->sample, chan->loop-1) >= 0) return 1; } gli_strict_warning("play sound failed"); gli_strict_warning(Mix_GetError()); SDL_LockAudio(); cleanup_channel(chan); SDL_UnlockAudio(); return 0; }
/* Play the sound, fading in, repeating, and stopping as specified. * fade_in and stop_after are in milliseconds! */ static int _rg_sound_play( RG_Sound *sound, int fade_in, int repeats, int stop_after ) { /* Open audio if it's not already. Return -1 if it failed. */ if( ensure_open_audio() != 0 ) { return -1; } /* If it's already playing on a channel, stop it first. */ if( _rg_sound_channel_check(sound) ) { Mix_HaltChannel( sound->channel ); } /* Find first available channel */ sound->channel = Mix_GroupAvailable(-1); if( sound->channel == -1 ) { /* No channels were available, so make one more than there are now. * (Mix_AllocateChannels(-1) returns the current number of channels) */ Mix_AllocateChannels( Mix_AllocateChannels(-1) + 1 ); /* Try again. */ sound->channel = Mix_GroupAvailable(-1); } /* Set its volume before we play */ Mix_Volume( sound->channel, (int)(MIX_MAX_VOLUME * sound->volume) ); if( fade_in <= 0 ) { /* Play sound without fading in */ return Mix_PlayChannelTimed( sound->channel, sound->wrap->chunk, repeats, stop_after ); } else { /* Play sound with fading in */ return Mix_FadeInChannelTimed( sound->channel, sound->wrap->chunk, repeats, fade_in, stop_after ); } }
int SDLAudio::CHANinGROUP(std::string name) { /** Check to see if we've created it */ SListIterator<SGZChanGroup*> GroupListITR = GroupList.GetIterator(); if (name.compare("all")==0) { return Mix_GroupAvailable(-1); } for( GroupListITR.Start(); GroupListITR.Valid(); GroupListITR.Forth() ) if((GroupListITR.Item()->Name.compare(name))==0) { return Mix_GroupAvailable(GroupListITR.Item()->groupNum); } SGZLogger.warn("AudioMAN: Group \"%s\" doesn't exist!\n", name.c_str()); return 0; }
/**\brief Retrieves the first available channel. */ int Audio::GetFreeChannel( void ){ /**\todo Optimization: We could consider dynamically allocating.*/ // Find first available channel int foundchan = Mix_GroupAvailable( -1 ); if ( foundchan != -1 ) return foundchan; // No channels available, halt oldest used one assert( this->lastplayed.size() != 0 ); Mix_HaltChannel( this->lastplayed.front() ); return this->lastplayed.front(); }
int SD_PlayDigitized(const SoundData &which,int leftpos,int rightpos,SoundChannel chan) { if (!DigiMode) return 0; // If this sound has been played too recently, don't play it again. // (Fix for extremely loud sounds when one plays over itself too much.) uint32_t currentTick = SDL_GetTicks(); if (currentTick - SoundInfo.GetLastPlayTick(which) < MIN_TICKS_BETWEEN_DIGI_REPEATS) return 0; SoundInfo.SetLastPlayTick(which, currentTick); int channel = chan; if(chan == SD_GENERIC) { channel = Mix_GroupAvailable(1); if(channel == -1) channel = Mix_GroupOldest(1); if(channel == -1) // All sounds stopped in the meantime? channel = Mix_GroupAvailable(1); } SD_SetPosition(channel, leftpos,rightpos); DigiPlaying = true; Mix_Chunk *sample = reinterpret_cast<Mix_Chunk*> (which.GetData(SoundData::DIGITAL)); if(sample == NULL) return 0; Mix_Volume(channel, static_cast<int> (ceil(128.0*MULTIPLY_VOLUME(SoundVolume)))); if(Mix_PlayChannel(channel, sample, 0) == -1) { printf("Unable to play sound: %s\n", Mix_GetError()); return 0; } // Return channel + 1 because zero is a valid channel. return channel + 1; }
static int lua_Mix_GroupAvailable(State & state){ Stack * stack = state.stack; int tag = -1; if (stack->is<LUA_TNUMBER>(1)){ tag = stack->to<int>(1); } int result = Mix_GroupAvailable(tag); if (result >= 0){ stack->push<int>(result); }else{ stack->push<bool>(false); } return 1; }
/** * Plays a UI sound for volume preview. * @param action Pointer to an action. */ void OptionsAudioState::slrUiVolumeRelease(Action *) { TextButton::soundPress->play(Mix_GroupAvailable(0)); }
void play_sound_internal(const std::string& files, channel_group group, unsigned int repeats, unsigned int distance, int id, int loop_ticks, int fadein_ticks) { if(files.empty() || distance >= DISTANCE_SILENT || !mix_ok) { return; } audio_lock lock; // find a free channel in the desired group int channel = Mix_GroupAvailable(group); if(channel == -1) { LOG_AUDIO << "All channels dedicated to sound group(" << group << ") are busy, skipping.\n"; return; } Mix_Chunk *chunk; std::string file = pick_one(files); try { chunk = load_chunk(file, group); assert(chunk); } catch(const chunk_load_exception&) { return; } /* * This check prevents SDL_Mixer from blowing up on Windows when UI sound is played * in response to toggling the checkbox which disables sound. */ if(group != SOUND_UI) { Mix_SetDistance(channel, distance); } int res; if(loop_ticks > 0) { if(fadein_ticks > 0) { res = Mix_FadeInChannelTimed(channel, chunk, -1, fadein_ticks, loop_ticks); } else { res = Mix_PlayChannel(channel, chunk, -1); } if(res >= 0) { Mix_ExpireChannel(channel, loop_ticks); } } else { if(fadein_ticks > 0) { res = Mix_FadeInChannel(channel, chunk, repeats, fadein_ticks); } else { res = Mix_PlayChannel(channel, chunk, repeats); } } if(res < 0) { ERR_AUDIO << "error playing sound effect: " << Mix_GetError() << std::endl; //still keep it in the sound cache, in case we want to try again later return; } channel_ids[channel] = id; //reserve the channel's chunk from being freed, since it is playing channel_chunks[res] = chunk; }
/** * Plays a UI sound for volume preview. * @param action Pointer to an action. */ void OptionsAudioState::slrUiVolumeRelease(Action *) { _game->getResourcePack()->getSound("GEO.CAT", 0)->play(Mix_GroupAvailable(0)); }