Skip to content

Commit

Permalink
Added fast version of vtlTractToTube (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-krug authored Dec 21, 2022
1 parent 7b93fe6 commit d5f15b1
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 0 deletions.
24 changes: 24 additions & 0 deletions include/VocalTractLabApi/VocalTractLabApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,30 @@ C_EXPORT int vtlTractToTube(double* tractParams,
double* incisorPos_cm, double* tongueTipSideElevation, double* velumOpening_cm2);


// ****************************************************************************
// Provides the tube data (especially the area function) for the given vector
// of tractParams. This version does NOT store and restore the previous vocal
// tract state. That means it is at least twice as fast as vtlTractToTube.
// However, this breaks incremental synthesis. That means you should not call
// this method during synthesis via the methods vtlSynthesisAddTube or
// vtlSynthesisAddTract (otherwise the current tract state will be changed).
// It has no negative impact on all other synthesis methods.
//
// The vectors tubeLength_cm, tubeArea_cm2, and tubeArticulator,
// must each have as many elements as tube sections.
// The values incisorPos_cm, tongueTipSideElevation, and velumOpening_cm2 are
// one double value each.
//
// Function return value:
// 0: success.
// 1: The API has not been initialized.
// ****************************************************************************

C_EXPORT int vtlFastTractToTube(double* tractParams,
double* tubeLength_cm, double* tubeArea_cm2, int* tubeArticulator,
double* incisorPos_cm, double* tongueTipSideElevation, double* velumOpening_cm2);


// ****************************************************************************
// Enumerates the different options to model radiation of the sound wave
// from the mouth
Expand Down
80 changes: 80 additions & 0 deletions src/VocalTractLabApi/VocalTractLabApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,87 @@ int vtlTractToTube(double *tractParams,
// ****************************************************************

vocalTract->restoreControlParams();

return 0;
}


// ****************************************************************************
// Provides the tube data (especially the area function) for the given vector
// of tractParams. This version does NOT store and restore the previous vocal
// tract state. That means it is at least twice as fast as vtlTractToTube.
// However, this breaks incremental synthesis. That means you should not call
// this method during synthesis via the methods vtlSynthesisAddTube or
// vtlSynthesisAddTract (otherwise the current tract state will be changed).
// It has no negative impact on all other synthesis methods.
//
// The vectors tubeLength_cm, tubeArea_cm2, and tubeArticulator,
// must each have as many elements as tube sections.
// The values incisorPos_cm, tongueTipSideElevation, and velumOpening_cm2 are
// one double value each.
//
// Function return value:
// 0: success.
// 1: The API has not been initialized.
// ****************************************************************************

int vtlFastTractToTube(double *tractParams,
double *tubeLength_cm, double *tubeArea_cm2, int *tubeArticulator,
double *incisorPos_cm, double *tongueTipSideElevation, double *velumOpening_cm2)
{
if (!vtlApiInitialized)
{
printf("Error: The API has not been initialized.\n");
return 1;
}

// ****************************************************************
// Do not store the current control parameter values.
// ****************************************************************



// ****************************************************************
// Set the given vocal tract parameters.
// ****************************************************************

int i;
for (i = 0; i < VocalTract::NUM_PARAMS; i++)
{
vocalTract->param[i].x = tractParams[i];
}

// ****************************************************************
// Get the tube for the new vocal tract shape.
// ****************************************************************

Tube tube;
vocalTract->calculateAll();
vocalTract->getTube(&tube);

// ****************************************************************
// Copy the tube parameters to the user arrays.
// ****************************************************************

Tube::Section *ts = NULL;
for (i = 0; i < Tube::NUM_PHARYNX_MOUTH_SECTIONS; i++)
{
ts = &tube.pharynxMouthSection[i];

tubeLength_cm[i] = ts->length_cm;
tubeArea_cm2[i] = ts->area_cm2;
tubeArticulator[i] = ts->articulator;
}

*incisorPos_cm = tube.teethPosition_cm;
*tongueTipSideElevation = tube.tongueTipSideElevation;
*velumOpening_cm2 = tube.getVelumOpening_cm2();

// ****************************************************************
// Do not restore the previous control parameter values. This way
// calculateAll is only called once and the processing time is
// reduced by 50%.
// ****************************************************************

return 0;
}
Expand Down
1 change: 1 addition & 0 deletions src/VocalTractLabApi/VocalTractLabApi.def
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ vtlGetGlottisParams
vtlGetTractParams
vtlExportTractSvg
vtlTractToTube
vtlFastTractToTube
vtlGetDefaultTransferFunctionOptions
vtlGetTransferFunction
vtlInputTractToLimitedTract
Expand Down
26 changes: 26 additions & 0 deletions test/VtlApiTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,32 @@ TEST(ApiTest, TractToTube)
vtlClose();
}

TEST(ApiTest, FastTractToTube)
{
vtlInitialize(speakerFile);

int _, numTubeSections, numVocalTractParams;
double d_;
vtlGetConstants(&_, &numTubeSections, &numVocalTractParams, &_, &_, &d_);
const char* shapeName = "a";
std::vector<double> param(numVocalTractParams);
vtlGetTractParams(shapeName, &param[0]);

std::vector<double> tubeLength_cm(numTubeSections);
std::vector<double> tubeArea_cm2(numTubeSections);
std::vector<int> tubeArticulator(numTubeSections);
std::vector<double> incisorPos_cm(numTubeSections);
std::vector<double> tongueTipSideElevation(numTubeSections);
std::vector<double> velumOpening_cm2(numTubeSections);

int ret = vtlFastTractToTube(&param[0], &tubeLength_cm[0], &tubeArea_cm2[0], &tubeArticulator[0],
&incisorPos_cm[0], &tongueTipSideElevation[0], &velumOpening_cm2[0]);

EXPECT_EQ(ret, 0);

vtlClose();
}

TEST(ApiTest, DefaultTransferFunctionOptions)
{
vtlInitialize(speakerFile);
Expand Down

0 comments on commit d5f15b1

Please sign in to comment.