Filewatcher File Search
FTP Search
  
Directory 
  
Content Search 
   
pkg://gkrellmss_2.6.orig.tar.gz:31522/gkrellmss-2.6.orig/src/oscope.c  downloads

/* GKrellMSS - GKrellM Sound Scope
|  Copyright (C) 2002-2004 Bill Wilson
|
|  Author:  Bill Wilson    bill@gkrellm.net
|
|  This program is free software which I release under the GNU General Public
|  License. You may redistribute and/or modify this program under the terms
|  of that 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.
| 
|  To get a copy of the GNU General Puplic License, write to the Free Software
|  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "gkrellmss.h"

static Oscope	*oscope;



static void
trigger_delay(gint channel)
	{
	SoundSample	*ss = gkrellmss->buffer;
	gfloat		flimit;
	gint		y0, i, n, limit, trigger, delay;
	
	trigger = (gint) (oscope->vert_trigger * oscope->vert_max);
	delay = -2;
	flimit = oscope->samples_per_point;
	limit = flimit;
	for (i = 0; i < gkrellmss->buf_count - limit; )
		{
		for (y0 = 0, n = 0; n < limit; ++n)
			{
			if (channel == CHANNEL_L)
				y0 += ss[i].left;
			else if (channel == CHANNEL_R)
				y0 += ss[i].right;
			else if (channel == CHANNEL_LR)
				y0 += (ss[i].left + ss[i].right) / 2;
			}
		y0 = y0 / limit;
		if (y0 < trigger)
			delay = -1;
		if (y0 >= trigger && delay == -1)
			{
			delay = i;
			break;
			}
		flimit += oscope->samples_per_point;
		i = flimit;
		}
	gkrellmss->buf_index = (delay < 0) ? 0 : delay;
	}


static void
draw_oscope_line_trace(gint channel)
	{
	GkrellmChart	*chart	= gkrellmss->chart;
	SoundSample		*ss = gkrellmss->buffer;
	gfloat			flimit;
	gint			x, x0, y0, y1, i, limit, n;

	gdk_gc_set_foreground(gkrellmss->gc, gkrellm_in_color());

	y1 = oscope->y_append;
	x0 = oscope->x_append;
	oscope->x_append = 0;
	oscope->y_append = 0;
	flimit = gkrellmss->buf_index + oscope->samples_per_point;
	for (i = gkrellmss->buf_index, x = x0; x < chart->w;
				x += oscope->dx_per_point)
		{
		limit = flimit;
		if (limit >= gkrellmss->buf_count - 1)
			{
			oscope->y_append = y1;
			oscope->x_append = x;
			break;
			}
		for (n = 0, y0 = 0; i < limit; ++i, ++n)
			{
			if (channel == CHANNEL_L)
				y0 += ss[i].left;
			else if (channel == CHANNEL_R)
				y0 += ss[i].right;
			else if (channel == CHANNEL_LR)
				y0 += (ss[i].left + ss[i].right) / 2;
			}
		y0 /= n;
		y0 = (chart->h / 2) * -y0 / oscope->vert_max;
		y0 += chart->h / 2;
		if (x > 0)
			{
			gdk_draw_line(chart->pixmap, gkrellmss->gc,
					x - oscope->dx_per_point, y1, x, y0);
			}
		y1 = y0;
		flimit += oscope->samples_per_point;
		}
	gkrellmss->buf_index = 0;
	gkrellmss->buf_count = 0;
	}

static void
draw_oscope_bar_trace(gint channel)
	{
	GkrellmChart	*chart	= gkrellmss->chart;
	SoundSample		*ss = gkrellmss->buffer;
	gfloat			flimit;
	gint			x, x0, y, y0, y1, i, limit, n;
	gint			y0_prev, y1_prev;

	gdk_gc_set_foreground(gkrellmss->gc, gkrellm_in_color());

	y = y0 = y1 = 0;
	y0_prev = y1_prev = oscope->y_append;
	x0 = oscope->x_append;
	oscope->x_append = 0;
	oscope->y_append = 0;
	flimit = gkrellmss->buf_index + oscope->samples_per_point;
	for (i = gkrellmss->buf_index, x = x0; x < chart->w;
				x += oscope->dx_per_point)
		{
		limit = flimit;
		if (limit >= gkrellmss->buf_count - 1)
			{
			oscope->y_append = (y1_prev + y0_prev) / 2;
			oscope->x_append = x;
			break;
			}
		for (n = 0; i < limit; ++i, ++n)
			{
			if (channel == CHANNEL_L)
				y = ss[i].left;
			else if (channel == CHANNEL_R)
				y = ss[i].right;
			else if (channel == CHANNEL_LR)
				y = (ss[i].left + ss[i].right) / 2;
			else
				break;
			if (n == 0)
				y0 = y1 = y;
			else
				{
				if (y < y0)
					y0 = y;
				if (y > y1)
					y1 = y;
				}
			if (x > 0)
				{
				if (y0 > y1_prev)
					y0 = y1_prev;
				if (y1 < y0_prev)
					y1 = y0_prev;
				}
			}
		y0_prev = y0;
		y1_prev = y1;

		y0 = (chart->h / 2) * -y0 / oscope->vert_max;
		y1 = (chart->h / 2) * -y1 / oscope->vert_max;
		y0 += chart->h / 2;
		y1 += chart->h / 2;
		gdk_draw_line(chart->pixmap, gkrellmss->gc, x, y1, x, y0);
		flimit += oscope->samples_per_point;
		}
	gkrellmss->buf_index = 0;
	gkrellmss->buf_count = 0;
	}

static void
draw_oscope_grid(void)
	{
	GdkImage		*grid_image;
	GdkGC			*gc;
	GdkColor		color;
	GkrellmChart	*chart	= gkrellmss->chart;
	gint			w, h, x, dx;

	/* Draw grid lines on bg_src_pixmap so gkrellm_clear_chart_pixmap()
	|  will include grid lines.
	*/
	gkrellm_clean_bg_src_pixmap(chart);
	gkrellm_draw_chart_grid_line(chart, chart->bg_src_pixmap, chart->h / 4);
	gkrellm_draw_chart_grid_line(chart, chart->bg_src_pixmap, chart->h / 2);
	gkrellm_draw_chart_grid_line(chart, chart->bg_src_pixmap, 3 * chart->h/4);

	/* There is no vertical grid image, so I make a vertical grid line using
	|  pixel values from the horizontal grid image at desired x positions.
	*/
	gdk_drawable_get_size(chart->bg_grid_pixmap, &w, &h);
	grid_image = gdk_image_get(chart->bg_grid_pixmap, 0, 0, w, h);
	gc = gkrellm_draw_GC(3);
	dx = chart->w / HORIZONTAL_DIVS;
	for (x = dx; x < HORIZONTAL_DIVS * dx; x += dx)
		{
		color.pixel = gdk_image_get_pixel(grid_image, x, 0);
		gdk_gc_set_foreground(gc, &color);
		gdk_draw_line(chart->bg_src_pixmap, gc, x - 1, 0, x - 1, chart->h - 1);
		if (h > 1)
			{
			color.pixel = gdk_image_get_pixel(grid_image, x, 1);
			gdk_gc_set_foreground(gc, &color);
			gdk_draw_line(chart->bg_src_pixmap, gc, x, 0, x, chart->h - 1);
			}
		}
	gdk_image_destroy(grid_image);
	}

static void
draw_oscope_label_decals(void)
	{
	gchar	buf[32];

	if (oscope->usec_per_div >= 1000)
		sprintf(buf, "%d msec", oscope->usec_per_div / 1000);
	else
		sprintf(buf, "%d usec", oscope->usec_per_div);
	gkrellm_draw_decal_text(NULL, gkrellmss->label0_decal, buf, -1);
	}

static void
draw_oscope_labels(void)
	{
	GkrellmChart	*chart	= gkrellmss->chart;

	if (gkrellmss->show_tip)
		return;
	if (gkrellmss->stream_open && gkrellmss->extra_info)
		{
		draw_oscope_label_decals();
		gkrellm_draw_decal_on_chart(chart, gkrellmss->label0_decal, 2,
					chart->h - gkrellmss->label0_decal->h);
		}
	}


void
gkrellmss_oscope_horizontal_scaling(void)
	{
	GkrellmChart	*chart	= gkrellmss->chart;

	oscope->t_sample = 1 / (gfloat) SAMPLE_RATE;
	oscope->dx_per_point = 0;
	do
		{
		++oscope->dx_per_point;
		oscope->t_trace = (gfloat) oscope->usec_per_div * 1e-6;
		oscope->t_trace *= HORIZONTAL_DIVS;
		oscope->samples_per_point = oscope->t_trace / oscope->t_sample
					/ (gfloat) chart->w * (gfloat) oscope->dx_per_point;
		}
	while (oscope->samples_per_point < 1);
	}

void
gkrellmss_oscope_trace(gint channel)
	{
	if (oscope->dx_per_point > 1)
		draw_oscope_line_trace(channel);
	else
		draw_oscope_bar_trace(channel);
	}

void
gkrellmss_draw_oscope(gboolean force_reset, gboolean draw_grid)
	{
	GkrellmChart	*chart	= gkrellmss->chart;
	gint			y;

	if (draw_grid)
		draw_oscope_grid();
	if (!gkrellmss->streaming)
		{
		if (!oscope->reset || force_reset)
			{
			y = chart->h / 2;
			gkrellm_clear_chart_pixmap(chart);
			gdk_gc_set_foreground(gkrellmss->gc, gkrellm_in_color());
			gdk_draw_line(chart->pixmap, gkrellmss->gc, 0, y, chart->w - 1, y);
			draw_oscope_labels();
			}
		gkrellmss->buf_count = 0;
		gkrellmss->buf_index = 0;
		oscope->x_append = oscope->y_append = 0;
		oscope->reset = TRUE;
		return;
		}
	else if (!oscope->x_append && gkrellmss->buf_count)
		{
		gkrellm_clear_chart_pixmap(chart);	/* Draws the grid */
		trigger_delay(CHANNEL_LR);
		gkrellmss_oscope_trace(CHANNEL_LR);
		draw_oscope_labels();
		oscope->reset = FALSE;
		}
	}

Oscope *
gkrellmss_init_oscope(void)
	{
	oscope = g_new0(Oscope, 1);
	oscope->usec_per_div = 2000;
	oscope->vert_max = (gint) (gkrellmss->vert_sensitivity * 32767.0);
	return oscope;
	}
Results 1 - 1
Help - FTP Sites List - Software Dir.
Searching half a billion files worldwide
© 1997-2009 MARUHN Internet Solutions