/////////////////////////////////////////////////////////////////////////////
// Name:       
// Purpose:  
// Author:      Cesar Mauri Loba (cesar at crea-si dot com)
// Modified by: 
// Created:     
// Copyright:   (C) 2010 Cesar Mauri Loba - CREA Software Systems
// 
//  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 3 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, see <http://www.gnu.org/licenses/>.
/////////////////////////////////////////////////////////////////////////////

#include "vumeter.h"
#include <assert.h>
#include <math.h>

// Converts sound envelope in dB (range 0,112) to VU meter scale (0,100)
// TODO: refactor to build a VU meter control
float Envelope2VUMeter(float env)
{
	float val, result;
	
	// VU meter like 

	// Input env's range is 0..112 dB, where 100dB is envelope RMS=1.
	// see [env~] object in pure data for further details

	// modify envelope to get negative values when maximum is not reached
	// and positive values for a signal over maximum
	env-= 100;

	// 66% of gauge (from 0 to 75) is for negative db
	if (env>= 0)
	{
		// Positive part

		// compute log. result is in the range [0, 2.5)
		val= log (1.0f + env);
		
		// map log result to gauge
		result= 66.0f + (34.0f / 2.5f) * val;
	}
	else
	{
		// Negative part		
		val= log (1.0f - env);	// range [0, 4,62)
		result= 66.0f - (66.0f / 4.62f) * val;
	}

	// ensure right gauge range
	assert (result>= 0);
	if (result> 100.0f) result= 100.0f;

	return result;
}

float Envelope2Meter(float env)
{
	float v= env-40.0f;
	if (v< 0.0f) v= 0.0f;

	return v * 100.0f / 60.0f;
}