next VocTract.h
up C/C++ Code for VoicTract Class
previous VoicTract.h


VoicTract.cpp

/******************************************************************************
 * Institution: Stanford University
 * Project: Sonification
 * Author: Ryan Cassidy (05157787)
 * Date: Summer 2003
 ******************************************************************************/
/*! \class VoicTract
 *  \brief STK class to implement modified Cook tract model.
 * 
 * VERSION CONTROL INFORMATION:
 * 
 * $RCSfile: VoicTract.cpp,v $
 *
 * $Author: rjc $
 *
 * $Date: 2003/10/05 05:33:49 $
 *
 * $Locker: rjc $
 *
 * $Log: VoicTract.cpp,v $
 * Revision 1.2  2003/10/05 05:33:49  rjc
 * Fxns to set radii and length now take pointers to const things.
 * Other const-correctness stuff.
 *
 * Revision 1.1  2003/09/29 21:48:09  rjc
 * Initial revision
 *
 * 
 ******************************************************************************/

#include "VoicTract.h"

#include "Instrmnt.h"
#include "Stk.h"
#include "SKINI.msg"

#include <string>

using namespace std;

VoicTract::VoicTract(int num_tract_sections /* = DEFAULT_NUM_SECTIONS */)
  : 
  Instrmnt(),
  _tract(num_tract_sections),
  _resource_path(""),
  _voiced((_resource_path + "glots/default.raw").c_str(), true),
  _last_output(0.0)
{
//  this->setPhoneme("eee");

  _voiced.normalize();
  _voiced.setGainRate((MY_FLOAT) 0.0005);
  _voiced.setGainTarget((MY_FLOAT) 0.0);
  _voiced.setSweepRate(1.0);
  this->setFreq(250);
  _voiced.tick();
  _voiced.setSweepRate(0.001);

  _noise_env.setRate((MY_FLOAT) 0.001);
  _noise_env.setTarget((MY_FLOAT) 0.0);

  _vib_filt.setPole(0.9999);
  _perf_vib_amt = 0.03;

  this->noteOn(400.0, 0.0);
}

VoicTract::~VoicTract()
{
}

void VoicTract::setVibratoAmt(MY_FLOAT vibratoAmt)
{
  _perf_vib_amt = vibratoAmt;
}

void VoicTract::setRndVibAmt(MY_FLOAT vibratoAmt)
{
  _voiced.setRandomGain(vibratoAmt);
}

void VoicTract::setVoiced(MY_FLOAT vGain)
{
  _voiced.setGainTarget(vGain);
}

void VoicTract::setUnVoiced(MY_FLOAT nGain)
{
  _noise_env.setTarget(nGain);
}

void VoicTract::setVoicedUnVoiced(MY_FLOAT vGain, MY_FLOAT nGain)
{
  this->setVoiced(vGain);
  this->setUnVoiced(nGain);
}

void VoicTract::setPitchSweepRate(MY_FLOAT rate)
{
  _voiced.setSweepRate(rate);
}

void VoicTract::speak()
{
  _voiced.noteOn();
}

void VoicTract::quiet()
{
  _voiced.noteOff();
  _noise_env.setTarget((MY_FLOAT) 0.0);
}

void VoicTract::setFreq(MY_FLOAT frequency)
{
  _voiced.setFrequency(frequency);
  _freq = frequency;
}

void VoicTract::noteOn(MY_FLOAT freq, MY_FLOAT amp)
{
  _voiced.setGainTarget(amp);
  this->setFreq(freq);
}

void VoicTract::noteOff(MY_FLOAT amp)
{
  _voiced.noteOff();
  _noise_env.setTarget(0.0);
}

MY_FLOAT VoicTract::tick()
{
  _voiced.setVibratoGain(_vib_filt.tick(_perf_vib_amt));

//  _tract.setNoiseGain(_noise_env.tick());
  MY_FLOAT vc = _voiced.tick();

  _last_output = _tract.tick(vc) * 0.1;
  
  return _last_output;
}

#define NORM_7 ((MY_FLOAT) 0.0078125)
void VoicTract::controlChange(int number, MY_FLOAT value)
{
  MY_FLOAT temp;
  int tempi;

#if defined(_STK_DEBUG_)        
  printf("VoicTract : ControlChange: Number=%i Value=%f\n",number,value);
#endif    
  if (number == __SK_Breath_)
  {
    this->setVoiced((MY_FLOAT) 1.0 - (value *(MY_FLOAT) NORM_7));
    this->setUnVoiced((MY_FLOAT) 0.01 * value * (MY_FLOAT) NORM_7);
  }
  else if (number == __SK_FootControl_)
  {
  }
  else if (number == __SK_ModFrequency_)
    _voiced.setVibratoRate(value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 12.0);  /* 0 to 12 Hz */
  else if (number == __SK_ModWheel_)
    _perf_vib_amt = value * (MY_FLOAT) NORM_7 * (MY_FLOAT) 0.2;
  else if (number == __SK_AfterTouch_Cont_)   {
    this->setVoiced(value*NORM_7);
  }
  else
  {
    printf("VoicTract : Undefined Control Number!!\n");
  }  
}

/******************************************************************************
 * Functions to get and set radii of vocal tract sections.
 ******************************************************************************/
void VoicTract::setTractRadii(const MY_FLOAT *radii, int num_sections)
{
  _tract.setRadii(radii, num_sections);
}

const MY_FLOAT *VoicTract::getTractRadii() const
{
  return _tract.getRadii();
}

void VoicTract::setTractSectionRadius(int sec_index, MY_FLOAT radius)
{
  _tract.setSectionRadius(sec_index, radius);
}
/******************************************************************************/


/******************************************************************************
 * Functions to get and set lengths of vocal tract sections.
 ******************************************************************************/
void VoicTract::setTractLengths(const MY_FLOAT *lengths, int num_sections)
{
  _tract.setLengths(lengths, num_sections);
}

const MY_FLOAT *VoicTract::getTractLengths() const
{
  return _tract.getLengths();
}

void VoicTract::setTractSectionLength(int sec_index, MY_FLOAT length)
{
  _tract.setSectionLength(sec_index, length);
}


int VoicTract::numTractSections() const
{
  return _tract.getNumSections();
}
/******************************************************************************/


next VocTract.h
up C/C++ Code for VoicTract Class
previous VoicTract.h

``Audio Speech Research Note'', Ryan J. Cassidy, published electronically by author, July 2003.
Download PDF version (audio_speech.pdf)
Download compressed PostScript version (audio_speech.ps.gz)

Copyright © 2003-11-28 by Ryan J. Cassidy.
Please email errata, comments, and suggestions to Ryan J. Cassidy <ryanc@ieee.org>
Stanford University