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

📄 visualization.c

📁 xmms-1.2.10.tar.gz学习使用的就下吧
💻 C
字号:
/*  XMMS - Cross-platform multimedia player *  Copyright (C) 1998-2001  Peter Alm, Mikael Alm, Olle Hallnas,                             Thomas Nilsson and 4Front Technologies *  Copyright (C) 1999-2001  Haavard Kvaalen * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program 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 General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "xmms.h"#include "fft.h"struct VisPluginData *vp_data;extern Vis *active_vis;extern SVis *mainwin_svis;GList *get_vis_list(void){	return vp_data->vis_list;}GList *get_vis_enabled_list(void){	return vp_data->enabled_list;}void vis_disable_plugin(VisPlugin *vp){	gint i = g_list_index(vp_data->vis_list,vp);	enable_vis_plugin(i, FALSE);	prefswin_vplugins_rescan();}void vis_about(int i){	GList *node = g_list_nth(vp_data->vis_list, i);	if (node && node->data && ((VisPlugin *) node->data)->about)		((VisPlugin *) node->data)->about();}void vis_configure(int i){	GList *node = g_list_nth(vp_data->vis_list, i);	if (node && node->data && ((VisPlugin *) node->data)->configure)		((VisPlugin *) node->data)->configure();}void vis_playback_start(void){	GList *node = vp_data->enabled_list;	VisPlugin *vp;		if(vp_data->playback_started)		return;		while(node)	{		vp = node->data;		if(vp->playback_start)			vp->playback_start();		node = g_list_next(node);	}	vp_data->playback_started = TRUE;}void vis_playback_stop(void){	GList *node = vp_data->enabled_list;	VisPlugin *vp;		if(!vp_data->playback_started)		return;		while(node)	{		vp = node->data;		if(vp->playback_stop)			vp->playback_stop();		node = g_list_next(node);	}	vp_data->playback_started = FALSE;}void enable_vis_plugin(int i, gboolean enable){	GList *node = g_list_nth(vp_data->vis_list, i);	VisPlugin *vp;	if (!node || !(node->data))		return;	vp = (VisPlugin *) node->data;	if (enable && !g_list_find(vp_data->enabled_list, vp))	{		vp_data->enabled_list = g_list_append(vp_data->enabled_list, vp);		if (vp->init)			vp->init();		if(get_input_playing() && vp->playback_start)			vp->playback_start();	}	else if (!enable && g_list_find(vp_data->enabled_list, vp))	{		vp_data->enabled_list = g_list_remove(vp_data->enabled_list, vp);		if(get_input_playing() && vp->playback_stop)			vp->playback_stop();		if (vp->cleanup)			vp->cleanup();	}}gboolean vis_enabled(int i){	return (g_list_find(vp_data->enabled_list, (VisPlugin *) g_list_nth(vp_data->vis_list, i)->data) ? TRUE : FALSE);}gchar *vis_stringify_enabled_list(void){	gchar *enalist = NULL, *temp, *temp2;	GList *node = vp_data->enabled_list;	if (g_list_length(node))	{		enalist = g_strdup(g_basename(((VisPlugin *) node->data)->filename));		node = node->next;		while (node)		{			temp = enalist;			temp2 = g_strdup(g_basename(((VisPlugin *) node->data)->filename));			enalist = g_strconcat(temp, ",", temp2, NULL);			g_free(temp);			g_free(temp2);			node = node->next;		}	}	return enalist;}void vis_enable_from_stringified_list(gchar * list){	gchar **plugins, *base;	GList *node;	gint i;	VisPlugin *vp;	if (!list || !strcmp(list, ""))		return;	plugins = g_strsplit(list, ",", 0);	for(i = 0; plugins[i]; i++)	{		node = vp_data->vis_list; 		while (node)		{			base = g_basename(((VisPlugin *) node->data)->filename);			if (!strcmp(plugins[i], base))			{				vp = node->data;				vp_data->enabled_list = g_list_append(vp_data->enabled_list, (VisPlugin *) vp);				if(vp->init)					vp->init();				if(get_input_playing() && vp->playback_start)					vp->playback_start();			}			node = node->next;		}	}	g_strfreev(plugins);}static void calc_stereo_pcm(gint16 dest[2][512], gint16 src[2][512], gint nch){	memcpy(dest[0], src[0], 512 * sizeof(gint16));	if(nch == 1)		memcpy(dest[1], src[0], 512 * sizeof(gint16));	else		memcpy(dest[1], src[1], 512 * sizeof(gint16));}static void calc_mono_pcm(gint16 dest[2][512], gint16 src[2][512], gint nch){	gint i;	gint16 *d, *sl, *sr;		if(nch == 1)		memcpy(dest[0], src[0], 512 * sizeof(gint16));	else	{		d = dest[0];		sl = src[0];		sr = src[1];		for(i = 0; i < 512; i++)		{			*(d++) = (*(sl++) + *(sr++)) >> 1;		}	}}static void calc_freq(gint16 *dest, gint16 *src){	static fft_state *state = NULL;	gfloat tmp_out[257];	gint i;		if(!state)		state = fft_init();	fft_perform(src,tmp_out,state);		for(i = 0; i < 256; i++)		dest[i] = ((gint)sqrt(tmp_out[i + 1])) >> 8;}static void calc_mono_freq(gint16 dest[2][256], gint16 src[2][512], gint nch){	gint i;	gint16 *d, *sl, *sr, tmp[512];		if(nch == 1)		calc_freq(dest[0], src[0]);	else	{		d = tmp;		sl = src[0];		sr = src[1];		for(i = 0; i < 512; i++)		{			*(d++) = (*(sl++) + *(sr++)) >> 1;		}		calc_freq(dest[0], tmp);	}}static void calc_stereo_freq(gint16 dest[2][256], gint16 src[2][512], gint nch){	calc_freq(dest[0], src[0]);	if(nch == 2)		calc_freq(dest[1], src[1]);	else		memcpy(dest[1], dest[0], 256 * sizeof(gint16));}	void vis_send_data(gint16 pcm_data[2][512], int nch, int length){	GList *node = vp_data->enabled_list;	VisPlugin *vp;	gint16 mono_freq[2][256], stereo_freq[2][256];	gboolean mono_freq_calced = FALSE, stereo_freq_calced = FALSE;	gint16 mono_pcm[2][512], stereo_pcm[2][512];	gboolean mono_pcm_calced = FALSE, stereo_pcm_calced = FALSE;	gint8 intern_vis_data[512];	gint i;	if (!pcm_data || nch < 1)	{		if (cfg.vis_type != VIS_OFF)		{			if (cfg.player_shaded && cfg.player_visible)				svis_timeout_func(mainwin_svis, NULL);			else				vis_timeout_func(active_vis, NULL);		}		return;	}	while (node)	{		vp = node->data;		if (vp->num_pcm_chs_wanted > 0 && vp->render_pcm)		{			if (vp->num_pcm_chs_wanted == 1)			{				if (!mono_pcm_calced)				{					calc_mono_pcm(mono_pcm, pcm_data, nch);					mono_pcm_calced = TRUE;				}				vp->render_pcm(mono_pcm);			}			else			{				if (!stereo_pcm_calced)				{					calc_stereo_pcm(stereo_pcm, pcm_data, nch);					stereo_pcm_calced = TRUE;				}				vp->render_pcm(stereo_pcm);			}		}		if (vp->num_freq_chs_wanted > 0 && vp->render_freq)		{			if (vp->num_freq_chs_wanted == 1)			{				if (!mono_freq_calced)				{					calc_mono_freq(mono_freq, pcm_data, nch);					mono_freq_calced = TRUE;				}				vp->render_freq(mono_freq);			}			else			{				if (!stereo_freq_calced)				{					calc_stereo_freq(stereo_freq, pcm_data, nch);					stereo_freq_calced = TRUE;				}				vp->render_freq(stereo_freq);			}		}		node = g_list_next(node);	}	if (cfg.vis_type == VIS_OFF)		return;	if (cfg.vis_type == VIS_ANALYZER)	{		if (cfg.player_shaded && cfg.player_visible)		{			/* VU */			gint vu ,val;			if (!stereo_pcm_calced)				calc_stereo_pcm(stereo_pcm, pcm_data, nch);			vu = 0;			for (i = 0; i < 512; i++)			{				val = abs(stereo_pcm[0][i]);				if (val > vu)					vu = val;			}			intern_vis_data[0] = (vu * 37) >> 15;			if (intern_vis_data[0] > 37)				intern_vis_data[0] = 37;			if (nch == 2)			{				vu = 0;				for (i = 0; i < 512; i++)				{					val = abs(stereo_pcm[1][i]);					if (val > vu)						vu = val;				}				intern_vis_data[1] = (vu * 37) >> 15;				if (intern_vis_data[1] > 37)					intern_vis_data[1] = 37;			}			else				intern_vis_data[1] = intern_vis_data[0];		}		else		{			/* Spectrum analyzer */			/* 76 values */			const int long_xscale[] =			{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,			 19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,			 35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,			 52,53,54,55,56,57,58,61,66,71,76,81,87,93,100,107,			 114,122,131,140,150,161,172,184,255};			/* 20 values */			const int short_xscale[] =			        {0,1,2,3,4,5,6,7,8,11,15,20,27,			         36,47,62,82,107,141,184,255};			const double y_scale = 3.60673760222; /* 20.0 / log(256) */			const int *xscale;			gint j, y, max;			if (!mono_freq_calced)				calc_mono_freq(mono_freq, pcm_data, nch);			memset(intern_vis_data, 0, 75);			if (cfg.analyzer_type == ANALYZER_BARS)			{				max = 19;				xscale = short_xscale;			}			else			{				max = 75;				xscale = long_xscale;			}			for (i = 0; i < max; i++)			{				for (j = xscale[i], y = 0; j < xscale[i + 1]; j++)				{					if (mono_freq[0][j] > y)						y = mono_freq[0][j];				}				y >>= 7;				if (y != 0)				{					intern_vis_data[i] = log(y) * y_scale;					if (intern_vis_data[i] > 15)						intern_vis_data[i] = 15;				}				else					intern_vis_data[i] = 0;			}		}	}	else  /* (cfg.vis_type == VIS_SCOPE) */	{		/* Osciloscope */		gint pos, step;		if (!mono_pcm_calced)			calc_mono_pcm(mono_pcm, pcm_data, nch);		step = (length << 8) / 74;		for (i = 0, pos = 0; i < 75; i++, pos += step)		{			intern_vis_data[i] = ((mono_pcm[0][pos >> 8]) >> 11) + 6;			if (intern_vis_data[i] > 12)				intern_vis_data[i] = 12;			if (intern_vis_data[i] < 0)				intern_vis_data[i] = 0;		}	}	if (cfg.player_shaded && cfg.player_visible)		svis_timeout_func(mainwin_svis, intern_vis_data);	else		vis_timeout_func(active_vis, intern_vis_data);}

⌨️ 快捷键说明

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