예제 #1
0
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));
}
예제 #2
0
파일: s_mix.c 프로젝트: darkshade9/aq2w
/*
 * 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);
}
예제 #3
0
파일: sound_sdlmix.c 프로젝트: Arakash/naev
/**
 * @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;
}
예제 #4
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);
}
예제 #5
0
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);
}
예제 #7
0
파일: sounds.c 프로젝트: NSYXin/cdogs-sdl
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));
}
예제 #9
0
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;
  }
}
예제 #10
0
/**
 * @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);
				}
			}
		}
	}
}
예제 #11
0
파일: Sound.cpp 프로젝트: AMDmi3/OpenXcom
/**
 * 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();
			}
		}
	}
}
예제 #12
0
파일: sound.c 프로젝트: Drooids/Corange
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;
}
예제 #13
0
	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;
	}
예제 #14
0
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;
	}
}
예제 #15
0
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?
  }
예제 #16
0
파일: s_mix.cpp 프로젝트: ArkyRomania/ufoai
/**
 * @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);
}
예제 #17
0
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 );
}
예제 #18
0
파일: Mixer.cpp 프로젝트: jnz/Lynx
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);
            }
        }
    }
}
예제 #19
0
파일: audio.c 프로젝트: callaa/luola
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();
	}
}
예제 #21
0
void CSoundEffect::SetPositionEffect(int angle, int dist)
{
	Mix_SetPosition(Channel, angle, dist);
}
예제 #22
0
bool SDLAudio::SetPosition(int channel, int angle, int distance)
{
    Mix_SetPosition(channel, angle, distance);
    return true;
}
예제 #23
0
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());
}