/* Speaker.c
 *
 * Copyright (C) 1992-2007 Paul Boersma
 *
 * 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.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * pb 2002/07/16 GPL
 * pb 2007/10/01 can write as encoding
 * pb 2007/10/09 wchar
 */

#include "Speaker.h"

#include "oo_DESTROY.h"
#include "Speaker_def.h"
#include "oo_COPY.h"
#include "Speaker_def.h"
#include "oo_EQUAL.h"
#include "Speaker_def.h"
#include "oo_CAN_WRITE_AS_ENCODING.h"
#include "Speaker_def.h"
#include "oo_WRITE_TEXT.h"
#include "Speaker_def.h"
#include "oo_READ_TEXT.h"
#include "Speaker_def.h"
#include "oo_WRITE_BINARY.h"
#include "Speaker_def.h"
#include "oo_READ_BINARY.h"
#include "Speaker_def.h"
#include "oo_DESCRIPTION.h"
#include "Speaker_def.h"

class_methods (Speaker, Data) {
	class_method_local (Speaker, destroy)
	class_method_local (Speaker, description)
	class_method_local (Speaker, copy)
	class_method_local (Speaker, equal)
	class_method_local (Speaker, canWriteAsEncoding)
	class_method_local (Speaker, writeText)
	class_method_local (Speaker, readText)
	class_method_local (Speaker, writeBinary)
	class_method_local (Speaker, readBinary)
	class_methods_end
}

Speaker Speaker_create (wchar *kindOfSpeaker, int numberOfVocalCordMasses)
{
	Speaker me = Thing_new (Speaker);

	/* Supralaryngeal dimensions are taken from P. Mermelstein (1973):		*/
	/*    "Articulatory model for the study of speech production",		*/
	/*    Journal of the Acoustical Society of America 53,1070 - 1082.		*/
	/* That was a male speaker, so we need scaling for other speakers:		*/

	double scaling;
	if (! me) return NULL;
	if (wcsequ (kindOfSpeaker, L"Male")) my relativeSize = 1.1;
	else if (wcsequ (kindOfSpeaker, L"Child")) my relativeSize = 0.7;
	else my relativeSize = 1.0;
	scaling = my relativeSize;

	/* Laryngeal system. Data for male speaker from Ishizaka and Flanagan.	*/

	if (wcsequ (kindOfSpeaker, L"Female")) {
		my lowerCord.thickness = 1.4e-3;   /* dx, in metres */
		my upperCord.thickness = 0.7e-3;
		my cord.length = 10e-3;
		my lowerCord.mass = 0.02e-3;   /* kilograms */
		my upperCord.mass = 0.01e-3;
		my lowerCord.k1 = 10;   /* Newtons per metre */
		my upperCord.k1 = 4;
	} else if (wcsequ (kindOfSpeaker, L"Male")) {
		my lowerCord.thickness = 2.0e-3;   /* dx, in metres */
		my upperCord.thickness = 1.0e-3;
		my cord.length = 18e-3;
		my lowerCord.mass = 0.1e-3;   /* kilograms */
		my upperCord.mass = 0.05e-3;
		my lowerCord.k1 = 12;   /* Newtons per metre */
		my upperCord.k1 = 4;
	} else /* "Child" */ {
		my lowerCord.thickness = 0.7e-3;   /* dx, in metres */
		my upperCord.thickness = 0.3e-3;
		my cord.length = 6e-3;
		my lowerCord.mass = 0.003e-3;   /* kilograms */
		my upperCord.mass = 0.002e-3;
		my lowerCord.k1 = 6;   /* Newtons per metre */
		my upperCord.k1 = 2;
	}
	my cord.numberOfMasses = numberOfVocalCordMasses;
	if (numberOfVocalCordMasses == 1) {
		my lowerCord.thickness += my upperCord.thickness;
		my lowerCord.mass += my upperCord.mass;
		my lowerCord.k1 += my upperCord.k1;
	}

	/* Supralaryngeal system. Data from Mermelstein. */

	my velum.x = -0.031 * scaling;
	my velum.y = 0.023 * scaling;
	my velum.a = atan2 (my velum.y, my velum.x);
	my palate.radius = sqrt (my velum.x * my velum.x + my velum.y * my velum.y);
	my tip.length = 0.034 * scaling;
	my neutralBodyDistance = 0.086 * scaling;
	my alveoli.x = 0.024 * scaling;
	my alveoli.y = 0.0302 * scaling;
	my alveoli.a = atan2 (my alveoli.y, my alveoli.x);
	my teethCavity.dx1 = -0.009 * scaling;
	my teethCavity.dx2 = -0.004 * scaling;
	my teethCavity.dy = -0.011 * scaling;
	my lowerTeeth.a = -0.30;   /* radians */
	my lowerTeeth.r = 0.113 * scaling;   /* metres */
	my upperTeeth.x = 0.036 * scaling;
	my upperTeeth.y = 0.026 * scaling;
	my lowerLip.dx = 0.010 * scaling;
	my lowerLip.dy = -0.004 * scaling;
	my upperLip.dx = 0.010 * scaling;
	my upperLip.dy = 0.004 * scaling;

	my nose.Dx = 0.007 * scaling;
	my nose.Dz = 0.014 * scaling;
	my nose.weq [0] = 0.018 * scaling;
	my nose.weq [1] = 0.016 * scaling;
	my nose.weq [2] = 0.014 * scaling;
	my nose.weq [3] = 0.020 * scaling;
	my nose.weq [4] = 0.023 * scaling;
	my nose.weq [5] = 0.020 * scaling;
	my nose.weq [6] = 0.035 * scaling;
	my nose.weq [7] = 0.035 * scaling;
	my nose.weq [8] = 0.030 * scaling;
	my nose.weq [9] = 0.022 * scaling;
	my nose.weq [10] = 0.016 * scaling;
	my nose.weq [11] = 0.010 * scaling;
	my nose.weq [12] = 0.012 * scaling;
	my nose.weq [13] = 0.013 * scaling;

	return me;
}

/* End of file Speaker.c */
