static mrb_value mrb_sdl2_mixer_set_position(mrb_state *mrb, mrb_value self) { mrb_int channel, angle, distance; mrb_get_args(mrb, "iii", &channel, &angle, &distance); return mrb_fixnum_value(Mix_SetPosition((int)channel, (Sint16)angle, (Uint8)distance)); }
/* * S_SpatializeChannel * * Set distance and stereo panning for the specified channel. */ void S_SpatializeChannel(s_channel_t *ch) { entity_state_t *ent; vec3_t delta; int c; float dist, dot, angle; c = (int) ((ptrdiff_t) (ch - s_env.channels)); if (ch->ent_num != -1) { // update the channel origin ent = &cl.entities[ch->ent_num].current; VectorCopy(ent->origin, ch->org); } VectorSubtract(ch->org, r_view.origin, delta); dist = VectorNormalize(delta) * SOUND_DISTANCE_SCALE * ch->atten; if (dist > 255.0) // clamp to max dist = 255.0; if (dist > 1.0) { // resolve stereo panning dot = DotProduct(r_view.right, delta); angle = acos(dot) * 180.0 / M_PI - 90.0; angle = (int) (360.0 - angle) % 360; } else angle = 0.0; Mix_SetPosition(c, (int) angle, (int) dist); }
/** * @brief Updates the position of a voice. * * @param v Voice to update. * @param x New X position for the voice. * @param y New Y position for the voice. * @return 0 on success. */ static int sound_mix_updatePosVoice( alVoice *v, double x, double y ) { double angle, dist; double px, py; double d; int idist; /* Get relative position. */ px = x - sound_pos[0]; py = y - sound_pos[1]; /* Exact calculations. */ angle = sound_pos[2] - ANGLE(px,py)/M_PI*180.; dist = MOD(px,py); /* Need to make sure distance doesn't overflow. */ d = CLAMP( 0., 1., (dist - 50.) / 2500. ); d = 255. * sqrt(d); idist = MIN( (int)d, 255); /* Panning also gets modulated at low distance. */ if (idist < 10) angle *= d/10.; /* Try to play the song. */ if (Mix_SetPosition( v->u.mix.channel, (Sint16)angle, (Uint8)idist) < 0) { WARN("Unable to set sound position: %s", Mix_GetError()); return -1; } return 0; }
void Sounds::play_distant_sound(int key, int angle, int dist) { if (!Mix_SetPosition(1, angle, dist)) { std::cout << "Error MIX_SetPosition" << std::endl; } this->play_sound(key); }
d_define_method(track, set_position)(struct s_object *self, short angle, unsigned char distance) { d_using(track); track_attributes->angle = angle; track_attributes->distance = distance; if ((track_attributes->channel != d_track_auto_channel) && (Mix_Playing(track_attributes->channel))) Mix_SetPosition(track_attributes->channel, angle, distance); return self; }
void SDLSoundManager::on_channel_finished(int channel) { PlaybackMapIterator pit = playback.find(channel); if (pit == playback.end()) return; pit->second.finished = true; Mix_SetPosition(channel, 0, 0); }
static void SoundPlayAtPosition( SoundDevice *device, Mix_Chunk *data, int distance, int bearing, const bool isMuffled) { if (data == NULL) { return; } // If distance is very close, don't place any panning on it if (distance < DISTANCE_CLOSE) bearing = 0; if (isMuffled) { distance += OUT_OF_SIGHT_DISTANCE_PLUS; } distance /= 2; // Don't play anything if it's too distant // This means we don't waste sound channels if (distance > 255) { return; } if (!device->isInitialised) { return; } LOG(LM_SOUND, LL_TRACE, "distance(%d) bearing(%d)", distance, bearing); int channel; for (;;) { channel = Mix_PlayChannel(-1, data, 0); if (channel >= 0 || device->channels > 128) { break; } // Check if we cannot play the sound; allocate more channels device->channels *= 2; if (Mix_AllocateChannels(device->channels) != device->channels) { printf("Couldn't allocate channels!\n"); return; } // When allocating new channels, need to reset their volume Mix_Volume(-1, ConfigGetInt(&gConfig, "Sound.SoundVolume")); } Mix_SetPosition(channel, (Sint16)bearing, (Uint8)distance); if (isMuffled) { if (!Mix_RegisterEffect(channel, MuffleEffect, NULL, NULL)) { fprintf(stderr, "Mix_RegisterEffect: %s\n", Mix_GetError()); } } }
void SDLSoundManager::play(SoundManager::SoundID sid, std::string channel, FPoint pos, bool loop) { SoundMapIterator it; VirtualChannelMapIterator vcit = channels.end(); if (!sid || !AUDIO || !SOUND_VOLUME) return; it = sounds.find(sid); if (it == sounds.end()) return; /* create playback object and start playback of sound chunk */ Playback p; p.sid = sid; p.location = pos; p.virtual_channel = channel; p.loop = loop; p.finished = false; if (p.virtual_channel != GLOBAL_VIRTUAL_CHANNEL) { /* if playback exists, stop it befor playin next sound */ vcit = channels.find(p.virtual_channel); if (vcit != channels.end()) Mix_HaltChannel(vcit->second); vcit = channels.insert(std::pair<std::string, int>(p.virtual_channel, -1)).first; } // Let playback own a reference to prevent unloading playbacked sound. if (!loop) it->second->refCnt++; Mix_ChannelFinished(&channel_finished); int c = Mix_PlayChannel(-1, it->second->chunk, (loop ? -1 : 0)); if (c == -1) logError("SoundManager: Failed to play sound, no more channels available."); // precalculate mixing volume if sound has a location Uint8 d = 0; if (p.location.x != 0 || p.location.y != 0) { float v = 255.0f * (calcDist(lastPos, p.location) / (SOUND_FALLOFF)); clamp(v, 0.f, 255.f); d = Uint8(v); } Mix_SetPosition(c, 0, d); if (vcit != channels.end()) vcit->second = c; playback.insert(std::pair<int, Playback>(c, p)); }
void SoundSystem::setPosition (int sample, int angle, int dist) { if (!audio) return; switch (sample) { case SOUND_EXPLOSION1: #ifdef HAVE_SDL_MIXER Mix_SetPosition (2, angle, dist); #endif break; } }
/** * @brief Updates all active channels for the current frame. */ void S_MixChannels(void) { Mix_Volume(-1, Clamp(s_volume->value, 0.0, 1.0) * MIX_MAX_VOLUME); s_channel_t *ch = s_env.channels; for (int32_t i = 0; i < MAX_CHANNELS; i++, ch++) { if (ch->free) { memset(ch, 0, sizeof(*ch)); } } s_env.num_active_channels = 0; ch = s_env.channels; for (int32_t i = 0; i < MAX_CHANNELS; i++, ch++) { if (ch->sample) { if (ch->start_time) { if (ch->play.flags & S_PLAY_FRAME) { if (ch->frame != cl.frame.frame_num) { Mix_FadeOutChannel(i, 250); continue; } } } if (S_SpatializeChannel(ch)) { Mix_SetPosition(i, ch->angle, ch->dist); if (!ch->start_time) { ch->start_time = quetoo.ticks; if (ch->play.flags & S_PLAY_LOOP) { Mix_PlayChannel(i, ch->sample->chunk, -1); } else { Mix_PlayChannel(i, ch->sample->chunk, 0); } } s_env.num_active_channels++; } else { if (ch->start_time) { Mix_HaltChannel(i); } else { S_FreeChannel(i); } } } } }
/** * Plays the contained sound effect. * @param channel Use specified channel, -1 to use any channel */ void Sound::play(int channel, int angle, int distance) const { if (!Options::mute && _sound != 0) { int chan = Mix_PlayChannel(channel, _sound, 0); if (chan == -1) { Log(LOG_WARNING) << Mix_GetError(); } else if (Options::StereoSound) { if(!Mix_SetPosition(chan, angle, distance)) { Log(LOG_WARNING) << Mix_GetError(); } } } }
int sound_play_at_looped(sound* s, vec3 pos, vec3 cam_pos, vec3 cam_dir, int loops) { int c = sound_play_looped(s, loops); const float HEARING = 5; float distance = vec3_dist(pos, cam_pos); Uint8 dist_val = (Uint8)clamp(distance * HEARING, 0, 255); const float DEGREES = 57.2957795; vec3 to_position = vec3_normalize(vec3_sub(pos, cam_pos)); vec3 to_forward = vec3_normalize(cam_dir); float angle = acos(vec3_dot(to_position, to_forward)); Sint16 angle_val = DEGREES * angle; Mix_SetPosition(c, angle_val, dist_val); return c; }
static int lua_Mix_SetPosition(State & state){ Stack * stack = state.stack; int channel = MIX_CHANNEL_POST; Sint16 angle = 0; Uint8 distance = 0; if (stack->is<LUA_TNUMBER>(1)){ channel = stack->to<int>(1); } if (stack->is<LUA_TNUMBER>(2)){ angle = static_cast<Uint16>(stack->to<int>(2)); } if (stack->is<LUA_TNUMBER>(3)){ distance = static_cast<Uint8>(stack->to<int>(3)); } int result = Mix_SetPosition(channel, angle, distance); stack->push<bool>(result != 0); return 1; }
static void do_position_update(void) { static Sint16 distance = 1; static Sint8 distincr = 1; static Uint16 angle = 0; static Sint8 angleincr = 1; static int positionok = 1; static Uint32 next_position_update = 0; if ((positionok) && (SDL_GetTicks() >= next_position_update)) { positionok = Mix_SetPosition(0, angle, distance); if (!positionok) { fprintf(stderr, "Mix_SetPosition(0, %d, %d) failed!\n", (int) angle, (int) distance); fprintf(stderr, "Reason: [%s].\n", Mix_GetError()); } if (angle == 0) { printf("Due north; now rotating clockwise...\n"); angleincr = 1; } else if (angle == 360) { printf("Due north; now rotating counter-clockwise...\n"); angleincr = -1; } distance += distincr; if (distance < 0) { distance = 0; distincr = 3; printf("Distance is very, very near. Stepping away by threes...\n"); } else if (distance > 255) { distance = 255; distincr = -3; printf("Distance is very, very far. Stepping towards by threes...\n"); } angle += angleincr; next_position_update = SDL_GetTicks() + 30; } }
void CSDLSoundMgr:: playSound(CSDLSound *sound) { if (! audioEnabled_) return; #if 0 // set channel 0 to settings volume Mix_Volume(0, myConfig->readConfigInt("SoundVolume")*10); #endif #if 0 //set 3d position for player int position = 180; int distance = 10; // set 3d effect if (! Mix_SetPosition(0, position, distance)) { std::cerr << "Error: Mix_SetPosition: %s\n", Mix_GetError()); // no position effect, is it ok? }
/** * @brief Set distance and stereo panning for the specified channel. * @param[in] ch The channel to perform the spatialization for. */ void S_SpatializeChannel (const s_channel_t* ch) { vec3_t delta; float dist, angle; const int c = (int)((ptrdiff_t)(ch - s_env.channels)); VectorSubtract(ch->org, cl.cam.camorg, delta); dist = VectorNormalize(delta) * snd_distance_scale->value * ch->atten; if (dist > 255.0) /* clamp to max */ dist = 255.0; if (dist > 50.0) { /* resolve stereo panning */ const float dot = DotProduct(s_env.right, delta); angle = (int)(450.0 - acos(dot) * todeg) % 360; } else angle = 0; Mix_SetPosition(c, (int)angle, (int)dist); }
void sfx::play_variant_sound_pitch( const std::string &id, const std::string &variant, int volume, int angle, float pitch ) { if( !check_sound( volume ) ) { return; } const sound_effect *eff = find_random_effect( id, variant ); if( eff == nullptr ) { return; } const sound_effect &selected_sound_effect = *eff; Mix_Chunk *effect_to_play = get_sfx_resource( selected_sound_effect.resource_id ); Mix_Chunk *shifted_effect = do_pitch_shift( effect_to_play, pitch ); Mix_VolumeChunk( shifted_effect, selected_sound_effect.volume * get_option<int>( "SOUND_EFFECT_VOLUME" ) * volume / ( 100 * 100 ) ); int channel = Mix_PlayChannel( -1, shifted_effect, 0 ); Mix_RegisterEffect( channel, empty_effect, cleanup_when_channel_finished, shifted_effect ); Mix_SetPosition( channel, angle, 1 ); }
void CMixer::Update(const float dt, const uint32_t ticks) { OBJITER iter; CObj* obj; bool success; for(iter=m_world->ObjBegin();iter!=m_world->ObjEnd();iter++) { obj = (*iter).second; if(obj->GetSound() && !obj->GetSoundState()->is_playing) { success = obj->GetSound()->Play(obj->GetSoundState()); CObj* localplayer = m_world->GetLocalObj(); if(success && localplayer) { // Distance to sound source const vec3_t diff = localplayer->GetOrigin() - obj->GetOrigin(); const float dist = std::min(diff.Abs(), SOUND_MAX_DIST); int volume = (int)(dist*255/SOUND_MAX_DIST); if(volume > 255) volume = 255; uint16_t angle; // 0-360 deg. for Mix_SetPosition vec3_t playerlook; // player is looking in this direction float fAlpha; // riwi to sound source float fBeta; // riwi look dir m_world->GetLocalController()->GetDir(&playerlook, NULL, NULL); fAlpha = atan2(diff.x, -diff.z); fBeta = atan2(playerlook.x, -playerlook.z); angle = (uint16_t)((fAlpha - fBeta)*180/lynxmath::PI); Mix_SetPosition(obj->GetSoundState()->cur_channel, angle, (uint8_t)volume); } } } }
void playwave_3d (AudioSample sample, int x, int y) { #if HAVE_LIBSDL_MIXER int dist,angle; int nearest; if (!audio_available || !game_settings.sounds || sample==WAV_NONE || samples[sample]==NULL) return; nearest = hearme (x, y); if (nearest < 0) return; if (players[nearest].ship) { x = x - players[nearest].ship->physics.x; y = y - players[nearest].ship->physics.y; } else { x = x - players[nearest].pilot.walker.physics.x; y = y - players[nearest].pilot.walker.physics.y; } dist = (0.5 + (hypot (x, y) / HEARINGRANGE)) * 180; angle = atan2 (x, y) * (180.0 / M_PI); Mix_SetPosition (Mix_PlayChannel (-1, samples[sample], 0), angle, dist); #endif }
void SDLSoundManager::logic(FPoint c) { PlaybackMapIterator it = playback.begin(); if (it == playback.end()) return; lastPos = c; std::vector<int> cleanup; while(it != playback.end()) { /* if sound is finished add it to cleanup and continue with next */ if (it->second.finished) { cleanup.push_back(it->first); ++it; continue; } /* dont process playback sounds without location */ if (it->second.location.x == 0 && it->second.location.y == 0) { ++it; continue; } /* control mixing playback depending on distance */ float v = calcDist(c, it->second.location) / (SOUND_FALLOFF); if (it->second.loop) { if (v < 1.0 && it->second.paused) { Mix_Resume(it->first); it->second.paused = false; } else if (v > 1.0 && !it->second.paused) { Mix_Pause(it->first); it->second.paused = true; ++it; continue; } } /* update sound mix with new distance/location to hero */ clamp(v, 0.0, 1.0); Uint8 dist = Uint8(255.0 * v); Mix_SetPosition(it->first, 0, dist); ++it; } /* clenaup finished soundplayback */ while (!cleanup.empty()) { it = playback.find(cleanup.back()); unload(it->second.sid); /* find and erase virtual channel for playback if exists */ VirtualChannelMapIterator vcit = channels.find(it->second.virtual_channel); if (vcit != channels.end()) channels.erase(vcit); playback.erase(it); cleanup.pop_back(); } }
void CSoundEffect::SetPositionEffect(int angle, int dist) { Mix_SetPosition(Channel, angle, dist); }
bool SDLAudio::SetPosition(int channel, int angle, int distance) { Mix_SetPosition(channel, angle, distance); return true; }
static void update_channel_effect(CCHANNEL *_object) { if (Mix_SetPosition(THIS->channel, THIS->angle, THIS->distance) == 0) GB.Error("Unable to set effect: &1", Mix_GetError()); }