view sv/filter/TimeStretchFilter.cpp @ 223:c413e82a4812

reorganise RealTimeFilter for Equalizer integration
author lbajardsilogic
date Mon, 11 Feb 2008 15:17:54 +0000
parents a89ab7dfbf4c
children 3200ed3fc957
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*	Sound Access	
		EASAIER client application.	
		Silogic 2007. Laure Bajard. 
	
	Integration of the filter provided by:
	Dublin Institute of Technology - Audio Research Group 2007
	www.audioresearchgroup.com
	Author: Dan Barry

	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.  See the file    
	COPYING included with this distribution for more information.
*/

#include <math.h>
#include <iostream>

#include "TimeStretchFilter.h"

#include  "FFTReal.h"
#include  "DSP.h"

#include "system/System.h"
#include "main/MainWindow.h"

float hopfactor = 1;


TimeStretchFilter::TimeStretchFilter() : PropertyContainer(),
	m_transcheck(true),
	m_peakcheck(false),
	m_interpfactor(1),
	m_tmaxfactor(2),
	m_pmaxfactor(2)
{
	setObjectName("Pitch-Time Stretching");

	connect(this, SIGNAL(playSpeedChanged(float)),
		MainWindow::instance(), SLOT(playSpeedChanged(float)));

	hopfactor = 1;
}

TimeStretchFilter::~TimeStretchFilter()
{
	hopfactor = 1;

	emit playSpeedChanged(1);
}

TimeStretchFilter::PropertyList TimeStretchFilter::getProperties() const
{
	PropertyList list;
    list.push_back("Time");
	list.push_back("Pitch");
	//list.push_back("Bypass");
	list.push_back("Transdetect");
	list.push_back("Peaklock");
	list.push_back("Equalizer");
    return list;
}

QString TimeStretchFilter::getPropertyLabel(const PropertyName &name) const
{
    if (name == "Time") return tr("Time");
	if (name == "Pitch") return tr("Pitch");
	//if (name == "Bypass") return tr("Bypass Processing");
	if (name == "Transdetect") return tr("Transient Detection");
	if (name == "Peaklock") return tr("Peak Locking");
    if (name == "Equalizer") return tr("Equalizer");
    return "";
}

TimeStretchFilter::PropertyType TimeStretchFilter::getPropertyType(const PropertyName &name) const
{
	if (name == "Time") return RangeProperty;
	if (name == "Pitch") return RangeProperty;
	//if (name == "Bypass") return ToggleProperty;
	if (name == "Transdetect") return ToggleProperty;
	if (name == "Peaklock") return ToggleProperty;
    if (name == "Equalizer") return PlotProperty;
    return InvalidProperty;
}

int TimeStretchFilter::getPropertyRangeAndValue(const PropertyName &name,
                                    int *min, int *max, int *deflt) const
{
    //!!! factor this colour handling stuff out into a colour manager class
	int val = 0;

    if (name == "Time") {
		if (min) *min = -100;
		if (max) *max = 100;
		if (deflt) *deflt = 0;
		if (hopfactor > 1)
			val = (hopfactor-1)/(m_tmaxfactor-1)*100.0;
		else if (hopfactor < 1)
			val = (1/hopfactor - 1)*(1-m_tmaxfactor)*100.0;
		else if (hopfactor == 1)
			val = 0;
	}

	if (name == "Pitch") {
		if (min) *min = -100;
		if (max) *max = 100;
		if (deflt) *deflt = 0;
		if (m_interpfactor > 1)
			val = (m_interpfactor-1)/(m_pmaxfactor-1)*100.0;
		else if (m_interpfactor < 1)
			val = (1/m_interpfactor - 1)*(1-m_pmaxfactor)*100.0;
		else if (m_interpfactor == 1)
			val = 0;
	}

	/*if (name == "Bypass") {
        if (deflt) *deflt = 0;
		val = (m_enabled ? 0 : 1);
    }*/

	if (name == "Transdetect") {
        if (deflt) *deflt = 0;
		val = (m_transcheck ? 1 : 0);
    }

	if (name == "Peaklock") {
        if (deflt) *deflt = 0;
		val = (m_peakcheck ? 1 : 0);
    }
#ifdef DEBUG_FILTERS
	std::cerr << "TimeStretchFilter::getPropertyRangeAndValue = " << val << std::endl;
#endif
    return val;
}

QString TimeStretchFilter::getPropertyValueLabel(const PropertyName &name,
				    int value) const
{
    if (name == "Time") {
		if (value == -100) 
			return tr("Slow");
		if (value == 100)
			return tr("Fast");
	}
    return tr("<unknown>");
}

void TimeStretchFilter::setProperty(const PropertyName &name, int value)
{
    if (name == "Time") {
		if (value > 0){
			hopfactor=1.0+((m_tmaxfactor-1)*(((float)value)/100.0));
		}
		if (value < 0){
			hopfactor=1.0/(1.0+((m_tmaxfactor-1)*(-((float)value)/100.0)));
		}
		if(value == 0){
			hopfactor=1;
		}
		if (isEnabled())
			emit playSpeedChanged(hopfactor);

	} else if (name == "Pitch") {
		if (value > 0){
			m_interpfactor=1.0+((m_pmaxfactor-1)*(((float)value)/100.0));
		}
		if (value < 0){
			m_interpfactor=1.0/(1.0+((m_pmaxfactor-1)*(-((float)value)/100.0)));
		}
		if(value == 0){
			m_interpfactor=1;
		}
	} /*else if (name == "Bypass"){
		if (value > 0)
		{
			m_enabled = false;
		} else 
		{
			m_enabled = true;
			if (isEnabled())
				emit playSpeedChanged(hopfactor);
		}
	} */else if (name == "Transdetect"){
		m_transcheck = (value > 0) ? true : false;
	} else if (name == "Peaklock"){
		m_peakcheck = (value > 0) ? true : false;
	}
#ifdef DEBUG_FILTERS
	std::cerr << "TimeStretchFilter::hopfactor = " << hopfactor << std::endl;
	std::cerr << "TimeStretchFilter::m_interpfactor = " << m_interpfactor << std::endl;
	std::cerr << "TimeStretchFilter::m_hop = " << m_hop << std::endl;
	std::cerr << "TimeStretchFilter::skip = " << getRequiredSkipSamples() << std::endl;
#endif

}

void TimeStretchFilter::setFilterEnabled(bool b){
	m_enabled=b;
	
	if (m_enabled)
		emit playSpeedChanged(hopfactor);
	else 
		emit playSpeedChanged(1);

	emit filterEnabled(m_enabled);
}

void TimeStretchFilter::setFilterEnabled(int b){
	m_enabled=b;
	
	if (m_enabled)
		emit playSpeedChanged(hopfactor);
	else 
		emit playSpeedChanged(1);

	emit filterEnabled(m_enabled);
}