Пример #1
0
static void flash_8 (FlashPrivate *priv, float rate, VisVideo *dest, VisVideo *src1, VisVideo *src2)
{
    if (rate < 0.5)
        visual_mem_copy (visual_video_get_pixels (dest), visual_video_get_pixels (src1), visual_video_get_size (src1));
    else
        visual_mem_copy (visual_video_get_pixels (dest), visual_video_get_pixels (src2), visual_video_get_size (src2));
}
Пример #2
0
static void act_bumpscope_render (VisPluginData *plugin, VisVideo *video, VisAudio *audio)
{
	BumpscopePrivate *priv = visual_plugin_get_private (plugin);
	priv->video = video;

	visual_audio_get_sample_mixed_simple (audio, priv->pcmbuf, 2,
			VISUAL_AUDIO_CHANNEL_LEFT,
			VISUAL_AUDIO_CHANNEL_RIGHT);

	__bumpscope_render_pcm (priv, visual_buffer_get_data (priv->pcmbuf));

	visual_mem_copy (visual_video_get_pixels (video), priv->rgb_buf2, visual_video_get_size (video));

	priv->colorupdate++;

	/* Let's not overload the color selector */
	if (priv->colorupdate > 1)
		priv->colorupdate = 0;

	if (priv->colorchanged == TRUE && priv->colorupdate == 0) {
		/* I couldn't hold myself */
		visual_param_set_value_color (
			visual_param_list_get (
				visual_plugin_get_params (plugin), "color"), &priv->color);
	}
}
Пример #3
0
static void have_data (GstElement *sink, GstBuffer *buffer, gpointer data)
{
	VisVideo *video = data;
	uint32_t *dest = visual_video_get_pixels (video);
	uint32_t *src = (uint32_t *) GST_BUFFER_DATA (buffer);

	visual_mem_copy (dest, src, GST_BUFFER_SIZE (buffer));
}
Пример #4
0
/**
 * Copies the colors from one VisPalette to another.
 *
 * @param dest Pointer to the destination VisPalette.
 * @param src Pointer to the source VisPalette from which colors are copied into the destination VisPalette.
 *
 * @return VISUAL_OK on succes, -VISUAL_ERROR_PALETTE_NULL or -VISUAL_ERROR_PALETTE_SIZE on failure.
 */
int visual_palette_copy (VisPalette *dest, VisPalette *src)
{
	visual_log_return_val_if_fail (dest != NULL, -VISUAL_ERROR_PALETTE_NULL);
	visual_log_return_val_if_fail (src != NULL, -VISUAL_ERROR_PALETTE_NULL);
	visual_log_return_val_if_fail (dest->ncolors == src->ncolors, -VISUAL_ERROR_PALETTE_SIZE);

	visual_mem_copy (dest->colors, src->colors, sizeof (VisColor) * dest->ncolors);

	return VISUAL_OK;
}
Пример #5
0
  void VideoTransform::mirror_y (Video& dst, Video const& src)
  {
      int y;

      for (y = 0; y < dst.m_impl->height; y++) {
          visual_mem_copy (dst.m_impl->pixel_rows[y],
                           src.m_impl->pixel_rows[dst.m_impl->height - 1 - y],
                           dst.m_impl->width * dst.m_impl->bpp);
      }
  }
Пример #6
0
static GoomHashEntry *entry_new(const char *key, HashValue value) {

  int len = strlen(key);
	GoomHashEntry *entry = (GoomHashEntry*)malloc(sizeof(GoomHashEntry));

	entry->key = (char *)malloc(len+1);
	visual_mem_copy(entry->key,key,len+1);
	entry->value = value;
	entry->lower = NULL;
	entry->upper = NULL;

	return entry;
}
Пример #7
0
/**
 * upload data to libvisual
 *
 * @param plugin plugin that should upload data.
 * @param where to upload data.
 *
 * @return 0 on success.
 */
static int inp_mplayer_upload( VisPluginData *plugin, VisAudio *audio )
{
	mplayer_priv_t *priv = NULL;

	visual_return_val_if_fail( audio != NULL, -1 );
	visual_return_val_if_fail( plugin != NULL, -1 );
	priv = visual_object_get_private (VISUAL_OBJECT (plugin));
	visual_return_val_if_fail( priv != NULL, -1 );
	visual_return_val_if_fail( priv->mmap_area != NULL, -1 );

	visual_mem_copy( audio->plugpcm,
			((uint8_t *)priv->mmap_area) + sizeof( mplayer_data_t ),
			2048 );

	return 0;
}
Пример #8
0
/**
 * Adds a VisParamEntry to a VisParamContainer, storing default values in the process.
 *
 * @param paramcontainer A pointer to the VisParamContainer in which the VisParamEntry is added.
 * @param param A pointer to the VisParamEntry that is added to the VisParamContainer.
 *
 * @return VISUAL_OK on succes, -VISUAL_ERROR_PARAM_CONTAINER_NULL, -VISUAL_ERROR_PARAM_NULL or
 *    error values returned by visual_list_add () on failure.
 */
int visual_param_container_add_with_defaults (VisParamContainer *paramcontainer, VisParamEntry *param)
{
    visual_log_return_val_if_fail (paramcontainer != NULL, -VISUAL_ERROR_PARAM_CONTAINER_NULL);
    visual_log_return_val_if_fail (param != NULL, -VISUAL_ERROR_PARAM_NULL);

    param->parent = paramcontainer;

    visual_mem_copy(&param->defaultnum, &param->numeric, sizeof(param->defaultnum));

    if(param->type == VISUAL_PARAM_ENTRY_TYPE_STRING)
        param->defaultstring = strdup(param->string);

/*
    if(param->type == VISUAL_PARAM_ENTRY_TYPE_COLOR)
        visual_color_copy(&param->defaultcolor, &param->color);
*/

    /* On container add, we always set changed once, so vars can be synchronised in the plugin
     * it's event loop */
    visual_param_entry_changed (param);

    return visual_list_add (&paramcontainer->entries, param);
}
Пример #9
0
void evaluate_sound(gint16 data[2][512], SoundInfo *info) {

	int i;
	float difaccel;
	float prevspeed;

	/* find the max */
	int incvar = 0;
	for (i = 0; i < 512; i+=2) {
		if (incvar < data[0][i])
			incvar = data[0][i];
	}

	if (incvar > info->allTimesMax)
		info->allTimesMax = incvar;

	/* volume sonore */
	info->volume = (float)incvar / (float)info->allTimesMax;
	visual_mem_copy(info->samples[0], data[0], 512 * sizeof(short));
	visual_mem_copy(info->samples[1], data[1], 512 * sizeof(short));

	difaccel = info->accelvar;
	info->accelvar = info->volume; /* accel entre 0 et 1 */

	/* transformations sur la vitesse du son */
	if (info->speedvar > 1.0f)
		info->speedvar = 1.0f;

	if (info->speedvar < 0.1f)
		info->accelvar *= (1.0f - (float)info->speedvar);
	else if (info->speedvar < 0.3f)
		info->accelvar *= (0.9f - (float)(info->speedvar-0.1f)/2.0f);
	else
		info->accelvar *= (0.8f - (float)(info->speedvar-0.3f)/4.0f);

	/* adoucissement de l'acceleration */
	info->accelvar *= ACCEL_MULT;
	if (info->accelvar < 0)
		info->accelvar = 0;

	difaccel = info->accelvar - difaccel;
	if (difaccel < 0)
		difaccel = - difaccel;

	/* mise a jour de la vitesse */
  prevspeed = info->speedvar;
	info->speedvar = (info->speedvar + difaccel * 0.5f) / 2;
	info->speedvar *= SPEED_MULT;
  info->speedvar = (info->speedvar + 3.0f * prevspeed) / 4.0f;
	if (info->speedvar < 0)
		info->speedvar = 0;
	if (info->speedvar > 1)
		info->speedvar = 1;

	/* temps du goom */
	info->timeSinceLastGoom++;
	info->timeSinceLastBigGoom++;
	info->cycle++;

	/* detection des nouveaux gooms */
	if ((info->speedvar > (float)IVAL(info->biggoom_speed_limit_p)/100.0f)
			&& (info->accelvar > info->bigGoomLimit)
			&& (info->timeSinceLastBigGoom > BIG_GOOM_DURATION)) {
		info->timeSinceLastBigGoom = 0;
	}

	if (info->accelvar > info->goom_limit) {
		/* TODO: tester && (info->timeSinceLastGoom > 20)) { */
		info->totalgoom ++;
		info->timeSinceLastGoom = 0;
		info->goomPower = info->accelvar - info->goom_limit;    
	}

	if (info->accelvar > info->prov_max)
		info->prov_max = info->accelvar;

	if (info->goom_limit>1)
		info->goom_limit=1;

	/* toute les 2 secondes : vérifier si le taux de goom est correct
	 * et le modifier sinon.. */
	if (info->cycle % 64 == 0) {
		if (info->speedvar<0.01f)
			info->goom_limit *= 0.91;
		if (info->totalgoom > 4) {
			info->goom_limit+=0.02;
		}
		if (info->totalgoom > 7) {
			info->goom_limit*=1.03f;
			info->goom_limit+=0.03;
		}
		if (info->totalgoom > 16) {
			info->goom_limit*=1.05f;
			info->goom_limit+=0.04;
		}
		if (info->totalgoom == 0) {
			info->goom_limit = info->prov_max - 0.02;
		}
		if ((info->totalgoom == 1) && (info->goom_limit > 0.02))
			info->goom_limit-=0.01;
		info->totalgoom = 0;
		info->bigGoomLimit = info->goom_limit * (1.0f + (float)IVAL(info->biggoom_factor_p)/500.0f);
		info->prov_max = 0;
	}

	/* mise a jour des parametres pour la GUI */
	FVAL(info->volume_p) = info->volume;
	info->volume_p.change_listener(&info->volume_p);
	FVAL(info->speed_p) = info->speedvar * 4;
	info->speed_p.change_listener(&info->speed_p);
	FVAL(info->accel_p) = info->accelvar;
	info->accel_p.change_listener(&info->accel_p);

	FVAL(info->goom_limit_p) = info->goom_limit;
	info->goom_limit_p.change_listener(&info->goom_limit_p);
        FVAL(info->goom_power_p) = info->goomPower;
        info->goom_power_p.change_listener(&info->goom_power_p);
	FVAL(info->last_goom_p) = 1.0-((float)info->timeSinceLastGoom/20.0f);
	info->last_goom_p.change_listener(&info->last_goom_p);
	FVAL(info->last_biggoom_p) = 1.0-((float)info->timeSinceLastBigGoom/40.0f);
	info->last_biggoom_p.change_listener(&info->last_biggoom_p);

	/* bigGoomLimit ==goomLimit*9/8+7 ? */
	}
Пример #10
0
int pipeline_container_run (LVAVSPipelineContainer *container, VisVideo *video, VisAudio *audio)
{
    int i, s = 0;
    VisListEntry *le = NULL;
    LVAVSPipelineElement *element;
    VisBuffer pcmbuf1;
    VisBuffer pcmbuf2;
    VisBuffer spmbuf1;
    VisBuffer spmbuf2;
    VisBuffer tmp;
    int *fbout;
    int *framebuffer;
    LVAVSPipeline *pipeline = LVAVS_PIPELINE_ELEMENT(container)->pipeline;
    int w = video->width, h = video->height;

    if(video->width != pipeline->dummy_vid->width || video->height != pipeline->dummy_vid->height || video->depth != pipeline->dummy_vid->depth) {

        if(pipeline->dummy_vid)
            visual_object_unref(VISUAL_OBJECT(pipeline->dummy_vid));

        if(pipeline->last_vid)
            visual_object_unref(VISUAL_OBJECT(pipeline->last_vid));
    
        pipeline->dummy_vid = visual_video_scale_depth_new(video, video->width, video->height, video->depth, VISUAL_VIDEO_COMPOSITE_TYPE_SRC);

        pipeline->last_vid = visual_video_scale_depth_new(video, video->width, video->height, video->depth, VISUAL_VIDEO_COMPOSITE_TYPE_SRC);
        
        for(i = 0; i < 16; i++) {
            VisVideo *vid = pipeline->buffers[i];
            if(vid)
                visual_object_unref(VISUAL_OBJECT(vid));
            vid = visual_video_scale_depth_new(video, video->width, video->height, video->depth, VISUAL_VIDEO_COMPOSITE_TYPE_NONE);
            pipeline->buffers[i] = vid;
        }
    }

    visual_video_blit_overlay(video, pipeline->last_vid, 0, 0, 0.5);
      
    fbout = visual_video_get_pixels(video);
    framebuffer = visual_video_get_pixels(pipeline->dummy_vid);

    int is_preinit = pipeline->isBeat;//(pipeline->isBeat&0x80000000);

/*    if(pipeline->isBeat && beat_render)
    fake_enabled = beat_render_frames;
*/
    s = render_now(container, video, audio, s);

    if(!is_preinit)
    {
        int x = video->width * video->height;
        int *tfb=framebuffer;
        int *o = fbout;
        int use_blendin=blendin(pipeline->blendmode);
        if(use_blendin == 10 && pipeline->use_inblendval >= 255)
            use_blendin=1;

        switch (use_blendin)
        {
            case 1:
                visual_mem_copy(o, tfb, w*h*sizeof(int));
            break;
            case 2:
                mmx_avgblend_block(o,tfb,x);
            break;
            case 3:
                while(x--)
                {
                    *o=BLEND_MAX(*o, *tfb++);
                    o++;
                }
            break;
            case 4:
            //mmx_addblend_block(pipeline->blendtable, o, tfb, x);
            break;
            case 5:
                while(x--)
                {
                    *o=BLEND_SUB(*o,*tfb++);
                    o++;
                }
            break;
            case 6:
                while(x--)
                {
                    *o=BLEND_SUB(*tfb++, *o);
                    o++;
                }
            break;
            case 7:
            {
                int y=h/2;
                while(x-- > 0)
                {
                    visual_mem_copy(o,tfb,w*sizeof(int));
                    tfb+=w*2;
                    o+=w*2;
                }
            break;
            }
            case 8:
            {
                int r = 0;
                int y = h;
                while(y-- > 0)
                {
                    int *out, *in;
                    int x=w/2;
                    out=o+r;
                    in=tfb+r;
                    r^=1;
                    while(x-- > 0)
                    {
                        *out=*in;
                        out+=2;
                        in+=2;
                    }
                    o+=w;
                    tfb+=w;
                }
            break;
            }
            case 9:
                while(x--)
                {
                    *o=*o^*tfb++;
                    o++;
                }
            break;
            case 10:
                mmx_adjblend_block(pipeline->blendtable,o,tfb,o,x,pipeline->use_inblendval);
            break;
            case 11:
                mmx_mulblend_block(pipeline->blendtable, o,tfb,x);
            break;
            case 13:
                while(x--)
                {
                    *o=BLEND_MIN(*o,*tfb++);
                    o++;
                }
            break;
            case 12:
    /*
                                    {
                                            int *buf=(int*)getGlobalBuffer(w,h,bufferin,0);
                                            if (!buf) break;
                                            while (x--)
                                            {
                                                    *o=BLEND_ADJ(*tfb++,*o, depthof(*buf, ininvert));
                                                    o++;
                                                    buf++;
                                            }
                                    }
    */
            break;
            default:
            break;
        }
    }
    int x;
    int line_blend_mode_save=pipeline->blendmode;
    //if(!is_preinit) pipeline->blendmode = 0;

    s = render_now(container, video, audio, s);
    //if(!is_preinit) pipeline->blendmode = line_blend_mode_save;

    if(!is_preinit)
    {
        if(s) visual_mem_copy(framebuffer, fbout, w*h*sizeof(int));

        int *tfb=s?fbout:framebuffer;
        int *o=framebuffer;
        x=w*h;
        int use_blendout=blendout(pipeline->blendmode);
        int use_outblendval = 100;
        if(use_blendout == 10 && use_outblendval >= 255)
            use_blendout=1;
        switch(use_blendout)
        {
            case 1:
                visual_mem_copy(o,tfb,x*sizeof(int));
            break;
            case 2:
                mmx_avgblend_block(o,tfb,x);
            break;
            case 3:
                while(x--)
                {
                    *o=BLEND_MAX(*o, *tfb++);
                    o++;
                }
            break;
            case 4:
                mmx_addblend_block(o, tfb, x);
            break;
            case 5:
                while(x--)
                {
                    *o = BLEND_SUB(*o, *tfb++);
                    o++;
                }
            break;
            case 6:
                while(x--)
                {
                    *o=BLEND_SUB(*tfb++, *o);
                    o++;
                }
            break;
            case 7:
            {
                int y=h/2;
                while(y-- > 0)
                {
                    visual_mem_copy(o, tfb, w*sizeof(int));
                    tfb+=w*2;
                    o+=w*2;
                }
            }
            break;
            case 8:
            {
                int r = 0;
                int y = h;
                while(y-- > 0)
                {
                    int *out, *in;
                    int x=w/2;
                    out=o+r;
                    in=tfb+r;
                    r^=1;
                    while(x-- > 0)
                    {
                        *out=*in;
                        out+=2;
                        in+=2;
                    }
                    o+=w;
                    tfb+=2;
                }
            }
            case 9:
                while(x--)
                {
                    *o=*o^*tfb++;
                    o++;
                }
            break;
            case 10:
                mmx_adjblend_block(pipeline->blendtable,o, tfb, o, x, use_outblendval);
            break;
            case 11:
                mmx_mulblend_block(pipeline->blendtable, o, tfb, x);
            break;
            case 13:
                while(x--)
                {
                    *o=BLEND_MIN(*o, *tfb++);
                    o++;
                }
            break;
            case 12:
            {
                //uint32_t *buf = buffer[bufferout]
            }
            break;
            default:
            break;
        }
    } 

    // Save state for next frame.
    visual_video_blit_overlay(pipeline->last_vid, video, 0, 0, 0);
    return VISUAL_OK;
}
Пример #11
0
int visual_bin_switch_actor (VisBin *bin, VisActor *actor)
{
	VisVideo *privvid;

	visual_log_return_val_if_fail (bin != NULL, -1);
	visual_log_return_val_if_fail (actor != NULL, -1);

	/* Set the new actor */
	bin->actmorph = actor;

	visual_log (VISUAL_LOG_DEBUG, "entering...");
	
	/* Free the private video */
	if (bin->privvid != NULL) {
		visual_object_unref (VISUAL_OBJECT (bin->privvid));
		
		bin->privvid = NULL;
	}

	visual_log (VISUAL_LOG_INFO, _("depth of the main actor: %d"), bin->actor->video->depth);

	/* Starting the morph, but first check if we don't have anything todo with openGL */
	if (bin->morphstyle == VISUAL_SWITCH_STYLE_MORPH &&
			bin->actor->video->depth != VISUAL_VIDEO_DEPTH_GL &&
			bin->actmorph->video->depth != VISUAL_VIDEO_DEPTH_GL &&
			bin->depthfromGL != TRUE) {

		if (bin->morph != NULL && bin->morph->plugin != NULL) {
			visual_morph_set_rate (bin->morph, 0);
		
			visual_morph_set_video (bin->morph, bin->actvideo);

			if (bin->morphautomatic == TRUE)
				visual_morph_set_mode (bin->morph, bin->morphmode);
			else
				visual_morph_set_mode (bin->morph, VISUAL_MORPH_MODE_SET);
			
			visual_morph_set_time (bin->morph, &bin->morphtime);
			visual_morph_set_steps (bin->morph, bin->morphsteps);
		}

		bin->morphrate = 0;
		bin->morphstepsdone = 0;

		visual_log (VISUAL_LOG_DEBUG, "phase 1");
		/* Allocate a private video for the main actor, so the morph
		 * can draw to the framebuffer */
		privvid = visual_video_new ();

		visual_log (VISUAL_LOG_DEBUG, "actvideo->depth %d actmorph->video->depth %d",
				bin->actvideo->depth, bin->actmorph->video->depth);

		visual_log (VISUAL_LOG_DEBUG, "phase 2");
		visual_video_clone (privvid, bin->actvideo);
		visual_log (VISUAL_LOG_DEBUG, "phase 3 pitch privvid %d actvideo %d", privvid->pitch, bin->actvideo->pitch);

		visual_video_allocate_buffer (privvid);

		visual_log (VISUAL_LOG_DEBUG, "phase 4");
		/* Initial privvid initialize */
	
		visual_log (VISUAL_LOG_DEBUG, "actmorph->video->depth %d %p", bin->actmorph->video->depth,
				visual_video_get_pixels (bin->actvideo));
		
		if (visual_video_get_pixels (bin->actvideo) != NULL && visual_video_get_pixels (privvid) != NULL)
			visual_mem_copy (visual_video_get_pixels (privvid), visual_video_get_pixels (bin->actvideo),
					visual_video_get_size (privvid));
		else if (visual_video_get_pixels (privvid) != NULL)
			visual_mem_set (visual_video_get_pixels (privvid), 0, visual_video_get_size (privvid));

		visual_actor_set_video (bin->actor, privvid);
		bin->privvid = privvid;
	} else {
		visual_log (VISUAL_LOG_DEBUG, "Pointer actvideo->pixels %p", visual_video_get_pixels (bin->actvideo));
		if (bin->actor->video->depth != VISUAL_VIDEO_DEPTH_GL &&
				visual_video_get_pixels (bin->actvideo) != NULL) {
			visual_mem_set (visual_video_get_pixels (bin->actvideo), 0, visual_video_get_size (bin->actvideo));
		}
	}

	visual_log (VISUAL_LOG_DEBUG, "Leaving, actor->video->depth: %d actmorph->video->depth: %d",
			bin->actor->video->depth, bin->actmorph->video->depth);

	bin->morphing = TRUE;

	return 0;
}
Пример #12
0
int visual_audio_analyze (VisAudio *audio)
{
	short pcm[3][1024];

#if 0
	float temp_out[256];
	float temp_audio[2][512];
	double scale;
	int i, j, y;
#endif

	visual_return_val_if_fail (audio != NULL, -VISUAL_ERROR_AUDIO_NULL);

	/* Load the pcm data */
#if 0
	for (i = 0; i < 512; i++) {
		audio->pcm[0][i] = audio->plugpcm[0][i];
		audio->pcm[1][i] = audio->plugpcm[1][i];
		audio->pcm[2][i] = (audio->plugpcm[0][i] + audio->plugpcm[1][i]) >> 1;
	}
#endif
	/* -------------------------------- audio pool testing */
	{
/*		VisBuffer *buffer = visual_buffer_new_allocate (sizeof (int16_t) * 512, visual_buffer_destroyer_free);
		VisTime timestamp;
		VisAudioSample *sample;

		visual_mem_copy (visual_buffer_get_data (buffer), audio->plugpcm[2], sizeof (int16_t) * 512);

		visual_time_get (&timestamp);

		sample = visual_audio_sample_new (buffer, &timestamp,
				VISUAL_AUDIO_SAMPLE_RATE_44100,
				VISUAL_AUDIO_SAMPLE_FORMAT_S8);

		visual_audio_samplepool_add (audio->samplepool, sample, "front");
*/
		VisAudioSamplePoolChannel *channel;
		VisBuffer buffer;

		visual_audio_samplepool_flush_old (audio->samplepool);

		channel = visual_audio_samplepool_get_channel (audio->samplepool, VISUAL_AUDIO_CHANNEL_LEFT);

		if (channel != 0) {
			visual_buffer_init (&buffer, pcm[0], 1024, NULL);

//			printf ("--channel debug: %s: %d\n", channel->channelid, visual_ringbuffer_get_size (channel->samples));
			visual_ringbuffer_get_data (channel->samples, &buffer, 1024);

			visual_object_unref (VISUAL_OBJECT (&buffer));
		}

		channel = visual_audio_samplepool_get_channel (audio->samplepool, VISUAL_AUDIO_CHANNEL_RIGHT);

		if (channel != 0) {
			visual_buffer_init (&buffer, pcm[1], 1024, NULL);

//			printf ("--channel debug: %s: %d\n", channel->channelid, visual_ringbuffer_get_size (channel->samples));
			visual_ringbuffer_get_data (channel->samples, &buffer, 1024);

			visual_object_unref (VISUAL_OBJECT (&buffer));
		}

	}
	/* /-------------------------------- audio pool testing */

//	for (i = 0; i < 512; i++) {
//		audio->pcm[2][i] = (audio->pcm[0][i] + audio->pcm[1][i]) >> 1;
//	}

#if 0
	/* Convert int16_t audio to float audio, (won't be needed when the rest of the new audio
	 * core lands). */
	for (i = 0; i < 512; i++) {
		temp_audio[0][i] = audio->pcm[0][i];
		temp_audio[1][i] = audio->pcm[1][i];
	}
	/* Fourier analyze the pcm data */
	visual_fourier_perform (audio->fourier, temp_audio[0], temp_out);

	for (i = 0; i < 256; i++)
		audio->freq[0][i] = temp_out[i] * 50;

	visual_fourier_perform (audio->fourier, temp_audio[1], temp_out);

	for (i = 0; i < 256; i++)
		audio->freq[1][i] = temp_out[i] * 50;

	/* Average channel */
	for (i = 0; i < 256; i++)
		audio->freq[2][i] = (audio->freq[0][i] + audio->freq[1][i]) >> 1;

	/* Normalized frequency analyzer */
	/** @todo FIXME Not sure if this is totally correct */
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 256; j++) {
			/* (Height / log (256)) */
			scale = 256 / log (256);

			y = audio->freq[i][j];
			y = log (y) * scale;

			if (y < 0)
				y = 0;

			audio->freqnorm[i][j] = y;
		}
	}

#endif
#if 0
	/* BPM stuff, used for the audio energy only right now */
	for (i = 1023; i > 0; i--) {
		visual_mem_copy (&audio->bpmhistory[i], &audio->bpmhistory[i - 1], 6 * sizeof (short int));
		visual_mem_copy (&audio->bpmdata[i], &audio->bpmdata[i - 1], 6 * sizeof (short int));
	}

	/* Calculate the audio energy */
	audio->energy = 0;

	for (i = 0; i < 6; i++)	{
		audio->bpmhistory[0][i] = audio_band_total (audio, i * 2, (i * 2) + 3);
		audio->bpmenergy[i] = audio_band_energy (audio, i, 10);

		audio->bpmdata[0][i] = audio->bpmhistory[0][i] - audio->bpmenergy[i];

		audio->energy += audio_band_energy(audio, i, 50);
	}

	audio->energy >>= 7;

	if (audio->energy > 100)
		audio->energy = 100;
#endif

	return VISUAL_OK;
}