⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sound.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / 3D rendering module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include "render3d_nodes.h"typedef struct{	GF_SoundInterface snd_ifce;	SFVec3f pos;} Sound2DStack;/*sound2D wraper - spacialization is not supported yet*/static void RenderSound2D(GF_Node *node, void *rs, Bool is_destroy){	RenderEffect3D *eff = (RenderEffect3D*) rs;	M_Sound2D *snd = (M_Sound2D *)node;	Sound2DStack *st = (Sound2DStack *)gf_node_get_private(node);		if (is_destroy) {		free(st);		return;	}	if (!snd->source) return;	/*this implies no DEF/USE for real location...*/	st->pos.x = snd->location.x;	st->pos.y = snd->location.y;	st->pos.z = 0;	gf_mx_apply_vec(&eff->model_matrix, &st->pos);	eff->sound_holder = &st->snd_ifce;	gf_node_render((GF_Node *) snd->source, eff);	eff->sound_holder = NULL;	/*never cull Sound2d*/	eff->trav_flags |= TF_DONT_CULL;}static Bool SND2D_GetChannelVolume(GF_Node *node, Fixed *vol){	Fixed volume = ((M_Sound2D *)node)->intensity;	vol[0] = vol[1] = vol[2] = vol[3] = vol[4] = vol[5] = volume;	return (volume==FIX_ONE) ? 0 : 1;}static u8 SND2D_GetPriority(GF_Node *node){	return 255;}void R3D_InitSound2D(Render3D *sr, GF_Node *node){	Sound2DStack *snd;	GF_SAFEALLOC(snd, Sound2DStack);	snd->snd_ifce.GetPriority = SND2D_GetPriority;	snd->snd_ifce.GetChannelVolume = SND2D_GetChannelVolume;	snd->snd_ifce.owner = node;	gf_node_set_private(node, snd);	gf_node_set_callback_function(node, RenderSound2D);}static Fixed snd_compute_gain(Fixed min_b, Fixed min_f, Fixed max_b, Fixed max_f, SFVec3f pos){		Fixed sqpos_x, sqpos_z;	Fixed y_pos, x_pos, dist_ellip, viewp_dist, dist_from_foci_min, dist_from_foci_max, d_min, d_max, sqb_min, sqb_max;	Fixed a_in = (min_f+min_b)/2;	Fixed b_in = gf_sqrt(gf_mulfix(min_b, min_f));	Fixed alpha_min = (min_f-min_b)/2;	Fixed dist_foci_min = (min_f-min_b);	Fixed a_out = (max_f+max_b)/2;	//first ellipse axis	Fixed b_out = gf_sqrt(gf_mulfix(max_b, max_f));	Fixed alpha_max = (max_f-max_b)/2; //origo from focus	Fixed dist_foci_max = (max_f-max_b);	Fixed x_min = 0;	Fixed x_max = 0;	Fixed y_min = 0;	Fixed y_max = 0;	Fixed k = (ABS(pos.z) >= FIX_EPSILON) ? gf_divfix(pos.x, pos.z) : 0;	sqpos_x = gf_mulfix(pos.x, pos.x);	sqpos_z = gf_mulfix(pos.z, pos.z);	dist_from_foci_min = gf_sqrt(sqpos_z + sqpos_x) + gf_sqrt( gf_mulfix(pos.z - dist_foci_min, pos.z - dist_foci_min) + sqpos_x);	dist_from_foci_max = gf_sqrt(sqpos_z + sqpos_x) + gf_sqrt( gf_mulfix(pos.z - dist_foci_max, pos.z - dist_foci_max) + sqpos_x);		d_min = min_f+min_b;	d_max = max_f+max_b;	if(dist_from_foci_max > d_max) return 0;	else if (dist_from_foci_min <= d_min) return FIX_ONE;	sqb_min = gf_mulfix(b_in, b_in);	sqb_max = gf_mulfix(b_out, b_out);	if (ABS(pos.z) > FIX_ONE/10000) {		s32 sign = (pos.z>0) ? 1 : -1;		Fixed a_in_k_sq, a_out_k_sq;		a_in_k_sq = gf_mulfix(a_in, k);		a_in_k_sq = gf_mulfix(a_in_k_sq, a_in_k_sq);		x_min = gf_mulfix(alpha_min, sqb_min) + sign*gf_mulfix( gf_mulfix(a_in, b_in), gf_sqrt(a_in_k_sq + sqb_min - gf_mulfix( gf_mulfix(alpha_min, k), gf_mulfix(alpha_min, k))));		x_min = gf_divfix(x_min, sqb_min + a_in_k_sq);		y_min = gf_mulfix(k, x_min);		a_out_k_sq = gf_mulfix(a_out, k);		a_out_k_sq = gf_mulfix(a_out_k_sq, a_out_k_sq);		x_max = gf_mulfix(alpha_max, sqb_max) + sign*gf_mulfix( gf_mulfix(a_out, b_out), gf_sqrt( a_out_k_sq + sqb_max - gf_mulfix( gf_mulfix(alpha_max, k), gf_mulfix(alpha_max, k))));		x_max = gf_divfix(x_max, sqb_max + a_out_k_sq);		y_max = gf_mulfix(k, x_max);	} else {		x_min = x_max = 0;		y_min = gf_mulfix(b_in, gf_sqrt(FIX_ONE - gf_mulfix( gf_divfix(alpha_min,a_in), gf_divfix(alpha_min,a_in)) ) );		y_max = gf_mulfix(b_out, gf_sqrt(FIX_ONE - gf_mulfix( gf_divfix(alpha_max,a_out), gf_divfix(alpha_max,a_out)) ) );	}	y_pos = gf_sqrt(sqpos_x) - y_min;	x_pos = pos.z - x_min;	x_max -= x_min;	y_max -= y_min;	dist_ellip = gf_sqrt( gf_mulfix(y_max, y_max) + gf_mulfix(x_max, x_max));	viewp_dist = gf_sqrt( gf_mulfix(y_pos, y_pos) + gf_mulfix(x_pos, x_pos));	viewp_dist = gf_divfix(viewp_dist, dist_ellip);	return FLT2FIX ( (Float) pow(10.0,- FIX2FLT(viewp_dist)));}typedef struct{	GF_SoundInterface snd_ifce;	GF_Matrix mx;	SFVec3f last_pos;	Bool identity;	/*local system*/	Fixed intensity;	Fixed lgain, rgain;} SoundStack;static void RenderSound(GF_Node *node, void *rs, Bool is_destroy){	RenderEffect3D *eff = (RenderEffect3D*) rs;	M_Sound *snd = (M_Sound *)node;	SoundStack *st = (SoundStack *)gf_node_get_private(node);	if (is_destroy) {		free(st);		return;	}	if (!snd->source) return;	eff->sound_holder = &st->snd_ifce;	/*forward in case we're switched off*/	if (eff->trav_flags & GF_SR_TRAV_SWITCHED_OFF) {		gf_node_render((GF_Node *) snd->source, eff);	}	else if (eff->traversing_mode==TRAVERSE_GET_BOUNDS) {		/*we can't cull sound since*/		eff->trav_flags |= TF_DONT_CULL;	} else if (eff->traversing_mode==TRAVERSE_SORT) {		GF_Matrix mx;		SFVec3f usr, snd_dir, pos;		Fixed mag, ang;		/*this implies no DEF/USE for real location...*/		gf_mx_copy(st->mx, eff->model_matrix);		gf_mx_copy(mx, eff->model_matrix);		gf_mx_inverse(&mx);		snd_dir = snd->direction;		gf_vec_norm(&snd_dir);		/*get user location*/		usr = eff->camera->position;		gf_mx_apply_vec(&mx, &usr);		/*recenter to ellipse focal*/		gf_vec_diff(usr, usr, snd->location);		mag = gf_vec_len(usr);		if (!mag) mag = FIX_ONE/10;		ang = gf_divfix(gf_vec_dot(snd_dir, usr), mag);			usr.z = gf_mulfix(ang, mag);		usr.x = gf_sqrt(gf_mulfix(mag, mag) - gf_mulfix(usr.z, usr.z));		usr.y = 0;		if (!gf_vec_equal(usr, st->last_pos)) {			st->intensity = snd_compute_gain(snd->minBack, snd->minFront, snd->maxBack, snd->maxFront, usr);			st->intensity = gf_mulfix(st->intensity, snd->intensity);			st->last_pos = usr;		}		st->identity = (st->intensity==FIX_ONE) ? 1 : 0;		if (snd->spatialize) {			Fixed ang, sign;			SFVec3f cross;			pos = snd->location;			gf_mx_apply_vec(&eff->model_matrix, &pos);			gf_vec_diff(pos, pos, eff->camera->position);			gf_vec_diff(usr, eff->camera->target, eff->camera->position);			gf_vec_norm(&pos);			gf_vec_norm(&usr);			ang = gf_acos(gf_vec_dot(usr, pos));			/*get orientation*/			cross = gf_vec_cross(usr, pos);			sign = gf_vec_dot(cross, eff->camera->up);			if (sign>0) ang *= -1;			ang = (FIX_ONE + gf_sin(ang)) / 2;			st->lgain = (FIX_ONE - gf_mulfix(ang, ang));			st->rgain = FIX_ONE - gf_mulfix(FIX_ONE - ang, FIX_ONE - ang);			/*renorm between 0 and 1*/			st->lgain = gf_mulfix(st->lgain, 4*st->intensity/3);			st->rgain = gf_mulfix(st->rgain, 4*st->intensity/3);			if (st->identity && ((st->lgain!=FIX_ONE) || (st->rgain!=FIX_ONE))) st->identity = 0;		} else {			st->lgain = st->rgain = FIX_ONE;		}		gf_node_render((GF_Node *) snd->source, eff);	}	eff->sound_holder = NULL;}static Bool SND_GetChannelVolume(GF_Node *node, Fixed *vol){	M_Sound *snd = (M_Sound *)node;	SoundStack *st = (SoundStack *)gf_node_get_private(node);	vol[2] = vol[3] = vol[4] = vol[5] = st->intensity;	if (snd->spatialize) {		vol[0] = st->lgain;		vol[1] = st->rgain;	} else {		vol[0] = vol[1] = st->intensity;	}	return !st->identity;}static u8 SND_GetPriority(GF_Node *node){	return (u8) ((M_Sound *)node)->priority*255;}void R3D_InitSound(Render3D *sr, GF_Node *node){	SoundStack *snd;	GF_SAFEALLOC(snd, SoundStack);	snd->snd_ifce.GetChannelVolume = SND_GetChannelVolume;	snd->snd_ifce.GetPriority = SND_GetPriority;	snd->snd_ifce.owner = node;	gf_node_set_private(node, snd);	gf_node_set_callback_function(node, RenderSound);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -