devsound/devsoundrefplugin/src/sounddevice/ToneGenerator.cpp
author hgs
Wed, 13 Oct 2010 12:08:48 +0100
changeset 3 28bdc4aca325
parent 0 79dd3e2336a0
permissions -rw-r--r--
2010wk42_01
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     1
// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     2
// All rights reserved.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     7
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     8
// Initial Contributors:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    10
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    11
// Contributors:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    12
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    13
// Description:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    14
// This file contains an implementation of the ToneGenerator interface
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    15
// that converts all tone generation requests in to sampled audio 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    16
// data to be played through the normal local sampled audio interface
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    17
// 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    18
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    19
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    20
#include "ToneGenerator.h"
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    21
#include <e32math.h>
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    22
#include <mda/common/resource.h>
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    23
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    24
/******************************************************************************
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    25
*	Tone Generators
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    26
*
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    27
*	The following classes are used to generate simple frequency/duration tones,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    28
*	DTMF, and SymbianOS tone sequences in a WINS environment.  The below code
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    29
*	should only be considered for WINS.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    30
******************************************************************************/
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    31
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    32
// this defines the maximum possible amplitude allowed for TSineGen::SetFrequency()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    33
const TInt KMaxAmplitude = 0x8000;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    34
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    35
// default number of samples for trailing silence following a Tone
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    36
const TInt KDefaultTrailingSilenceSamples = 20;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    37
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    38
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    39
// Sine tone generator
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    40
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    41
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    42
const TInt16 TSineGen::SineTable[KMaxSineTable] =
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    43
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    44
		 0,   804,  1607,  2410,  3211,  4011,  4807,  5601,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    45
	  6392,  7179,  7961,  8739,  9511, 10278, 11038, 11792,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    46
	 12539, 13278, 14009, 14732, 15446, 16150, 16845, 17530,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    47
	 18204, 18867, 19519, 20159, 20787, 21402, 22004, 22594,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    48
	 23169, 23731, 24278, 24811, 25329, 25831, 26318, 26789,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    49
	 27244, 27683, 28105, 28510, 28897, 29268, 29621, 29955,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    50
	 30272, 30571, 30851, 31113, 31356, 31580, 31785, 31970,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    51
	 32137, 32284, 32412, 32520, 32609, 32678, 32727, 32757,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    52
	 32767, 32757, 32727, 32678, 32609, 32520, 32412, 32284,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    53
	 32137, 31970, 31785, 31580, 31356, 31113, 30851, 30571,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    54
	 30272, 29955, 29621, 29268, 28897, 28510, 28105, 27683,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    55
	 27244, 26789, 26318, 25831, 25329, 24811, 24278, 23731,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    56
	 23169, 22594, 22004, 21402, 20787, 20159, 19519, 18867,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    57
	 18204, 17530, 16845, 16150, 15446, 14732, 14009, 13278,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    58
	 12539, 11792, 11038, 10278,  9511,  8739,  7961,  7179,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    59
	  6392,  5601,  4807,  4011,  3211,  2410,  1607,   804,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    60
		 0,  -804, -1607, -2410, -3211, -4011, -4807, -5601,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    61
	 -6392, -7179, -7961, -8739, -9511,-10278,-11038,-11792,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    62
	-12539,-13278,-14009,-14732,-15446,-16150,-16845,-17530,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    63
	-18204,-18867,-19519,-20159,-20787,-21402,-22004,-22594,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    64
	-23169,-23731,-24278,-24811,-25329,-25831,-26318,-26789,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    65
	-27244,-27683,-28105,-28510,-28897,-29268,-29621,-29955,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    66
	-30272,-30571,-30851,-31113,-31356,-31580,-31785,-31970,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    67
	-32137,-32284,-32412,-32520,-32609,-32678,-32727,-32757,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    68
	-32767,-32757,-32727,-32678,-32609,-32520,-32412,-32284,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    69
	-32137,-31970,-31785,-31580,-31356,-31113,-30851,-30571,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    70
	-30272,-29955,-29621,-29268,-28897,-28510,-28105,-27683,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    71
	-27244,-26789,-26318,-25831,-25329,-24811,-24278,-23731,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    72
	-23169,-22594,-22004,-21402,-20787,-20159,-19519,-18867,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    73
	-18204,-17530,-16845,-16150,-15446,-14732,-14009,-13278,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    74
	-12539,-11792,-11038,-10278, -9511, -8739, -7961, -7179,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    75
	 -6392, -5601, -4807, -4011, -3211, -2410, -1607,  -804,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    76
	};
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    77
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    78
const TInt16 TSineGen::IncTable[KMaxSineTable] =
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    79
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    80
			804,  803,  803,  801,  800,  796,  794,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    81
	  791,  787,  782,  778,  772,  767,  760,  754,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    82
	  747,  739,  731,  723,  714,  704,  695,  685,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    83
	  674,  663,  652,  640,  628,  615,  602,  590,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    84
	  575,  562,  547,  533,  518,  502,  487,  471,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    85
	  455,  439,  422,  405,  387,  371,  353,  334,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    86
	  317,  299,  280,  262,  243,  224,  205,  185,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    87
	  167,  147,  128,  108,   89,   69,   49,   30,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    88
	   10,  -10,  -30,  -49,  -69,  -89, -108, -128,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    89
	 -147, -167, -185, -205, -224, -243, -262, -280,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    90
	 -299, -317, -334, -353, -371, -387, -405, -422,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    91
	 -439, -455, -471, -487, -502, -518, -533, -547,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    92
	 -562, -575, -590, -602, -615, -628, -640, -652,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    93
	 -663, -674, -685, -695, -704, -714, -723, -731,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    94
	 -739, -747, -754, -760, -767, -772, -778, -782,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    95
	 -787, -791, -794, -796, -800, -801, -803, -803,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    96
	 -804, -804, -803, -803, -801, -800, -796, -794,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    97
	 -791, -787, -782, -778, -772, -767, -760, -754,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    98
	 -747, -739, -731, -723, -714, -704, -695, -685,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
    99
	 -674, -663, -652, -640, -628, -615, -602, -590,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   100
	 -575, -562, -547, -533, -518, -502, -487, -471,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   101
	 -455, -439, -422, -405, -387, -371, -353, -334,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   102
	 -317, -299, -280, -262, -243, -224, -205, -185,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   103
	 -167, -147, -128, -108,  -89,  -69,  -49,  -30,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   104
	  -10,   10,   30,   49,   69,   89,  108,  128,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   105
	  147,  167,  185,  205,  224,  243,  262,  280,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   106
	  299,  317,  334,  353,  371,  387,  405,  422,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   107
	  439,  455,  471,  487,  502,  518,  533,  547,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   108
	  562,  575,  590,  602,  615,  628,  640,  652,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   109
	  663,  674,  685,  695,  704,  714,  723,  731,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   110
	  739,  747,  754,  760,  767,  772,  778,  782,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   111
	  787,  791,  794,  796,  800,  801,  803,  803,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   112
	  804
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   113
	};
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   114
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   115
void TSineGen::SetFrequency(TInt aFrequency,TInt aAmplitude)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   116
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   117
// Given the frequency set iStep.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   118
// Reset iPosition to the equivalent of 0 degrees.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   119
// In the special case of aFrequency==4KHz set iPosition to 90 degrees.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   120
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   121
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   122
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   123
	if (aAmplitude>(1<<15))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   124
		iAmplitude=(1<<15);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   125
	else if (aAmplitude<-(1<<15))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   126
		iAmplitude=-(1<<15);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   127
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   128
		iAmplitude=aAmplitude;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   129
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   130
// There are 256 entries in the sine table to traverse 360 degrees.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   131
// The codec requires samples at a rate of 8000 per second.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   132
// Thus for a 1Hz tone the step will be 256/8000 or 4/125.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   133
// Now we need need the integer part of the result to end up in
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   134
// the MSB so we need to multiply by 2^24. This gives the formula
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   135
// step = (f*4*2^24)/125 or (f*2^26)/125.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   136
// Our highest frequency is 4KHz so that the term (f*2^26) exceeds
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   137
// a 32 bit result by 4000/2^6 (2^6 is the number of significant bits
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   138
// left after a multiply by 2^26). i.e. 6 bits. We overcome this by
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   139
// having 6 bits less in the fraction, so the new formula becomes
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   140
// ((f*2^20)/125)*2^6. This still gives us 20 significant bits in the
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   141
// fraction.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   142
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   143
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   144
	iStep=(((TUint)aFrequency<<20)/125)<<6;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   145
	iPosition=(aFrequency==4000 ? 0x40000000 : 0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   146
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   147
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   148
TInt TSineGen::NextSample()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   149
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   150
// Generate the next sample using linear interpolation
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   151
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   152
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   153
	TUint pos=iPosition>>24;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   154
	TInt amp=((IncTable[pos]*((iPosition&0x00ffffff)>>20)));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   155
	amp>>=4;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   156
	amp+=SineTable[pos];
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   157
	amp=(amp*iAmplitude)>>15;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   158
	iPosition+=iStep;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   159
	return(amp);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   160
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   161
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   162
void TSineWave::Generate(TInt16* aDest,TInt aCount)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   163
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   164
// Called when more samples need to be generated.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   165
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   166
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   167
	while (aCount--)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   168
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   169
		*aDest++=STATIC_CAST(TInt16,iGen1.NextSample()+iGen2.NextSample());
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   170
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   171
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   172
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   173
void TSineWave::SetFrequency(TInt aFrequency,TInt aAmplitude)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   174
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   175
// Set to generate a single frequency
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   176
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   177
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   178
	SetFrequency(aFrequency,aAmplitude,0,0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   179
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   180
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   181
void TSineWave::SetFrequency(TInt aFrequency1,TInt aAmplitude1,TInt aFrequency2,TInt aAmplitude2)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   182
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   183
// Set to generate two frequencies
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   184
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   185
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   186
	iGen1.SetFrequency(aFrequency1,aAmplitude1);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   187
	iGen2.SetFrequency(aFrequency2,aAmplitude2);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   188
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   189
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   190
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   191
// TMdaToneGenerator
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   192
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   193
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   194
void TMdaToneGenerator::Configure(TInt aRate, TInt aChannels, TInt aRepeats, TInt aSilence, TInt aRampUp)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   195
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   196
// Set up this tone generator to generate data at the desired sample rate
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   197
// and number of channels (typically mono/stereo)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   198
// 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   199
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   200
	iRate = aRate;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   201
	iChannels = aChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   202
	iSamplesLeft = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   203
	iIncompleteVolume = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   204
	iRampUpRemainder = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   205
	iRampUp = ETrue; // Default ramping to on as it is normally useful
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   206
	iRampDown = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   207
	iIncompleteRampDown = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   208
	iIncompleteRampUp = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   209
	iRepeats = aRepeats;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   210
	iSilenceBetweenRepeats = aSilence;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   211
	iRampUpCount = aRampUp;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   212
	iRampUpLeft = aRampUp;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   213
	iAfterRepeatSilence = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   214
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   215
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   216
LOCAL_C void RampVolume(TInt16* aData,TInt aCount,TInt aStartVol,TInt aEndVol)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   217
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   218
// Simple function to ramp down the volume of some samples 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   219
// Typically used to prevent "clicking" artifacts at the beginning/end of tones
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   220
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   221
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   222
	TInt step = (aEndVol - aStartVol)/aCount;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   223
	while (aCount--)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   224
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   225
		TInt data = TInt(*aData) * aStartVol;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   226
		*aData++ = TInt16(data>>15);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   227
		aStartVol += step;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   228
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   229
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   230
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   231
TInt TMdaToneGenerator::FillBuffer(TDes8& aBuffer)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   232
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   233
// Fill the supplied buffer with tone data
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   234
// Sets the buffer length to zero if there is no more data to play
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   235
// The buffer must have a max length of at least one sample * channels
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   236
// e.g. 2 bytes mono, 4 bytes stereo
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   237
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   238
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   239
	const TInt KRampUpSamples = 50;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   240
	const TInt KRampDownSamples = 50;	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   241
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   242
	ASSERT(aBuffer.MaxLength()>= (iChannels<<1));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   243
	aBuffer.SetMax();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   244
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   245
	TBool silence;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   246
	TInt samples = 0; // 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   247
	TInt used = 0; // Data used
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   248
	TInt avail = aBuffer.Length(); // Data filled
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   249
	TInt count = 0; // Data to be converted
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   250
	TBool rampUp = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   251
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   252
	TMdaPtr8 fill;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   253
	fill.Set(aBuffer); // Pointer to data left to be filled
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   254
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   255
	// 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   256
	// The rest of this function will loop around continually until the buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   257
	// is filled or there is no more data to play
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   258
	//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   259
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   260
Restart:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   261
	silence = EFalse; // Reset
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   262
	if (iSamplesLeft == 0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   263
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   264
		if (iTrailingSilence == 0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   265
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   266
			TInt error = GetNextTone();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   267
			if (error)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   268
				return error;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   269
			
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   270
			rampUp = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   271
			if ((iSamplesLeft==0)&&(iTrailingSilence==0))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   272
				{ 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   273
				if ((iSilenceBetweenRepeats)&&(!iAfterRepeatSilence))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   274
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   275
					iTrailingSilence = iSilenceBetweenRepeats;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   276
					iAfterRepeatSilence = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   277
					goto Restart;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   278
					}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   279
				else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   280
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   281
					if ((iRepeats>0)||(iRepeats==KMdaRepeatForever))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   282
						{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   283
						iAfterRepeatSilence = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   284
						if (iRepeats>0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   285
							iRepeats--;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   286
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   287
						Reset();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   288
						goto Restart;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   289
						}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   290
					}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   291
				// No more to play
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   292
				goto Finished;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   293
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   294
			goto Restart;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   295
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   296
		else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   297
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   298
			silence = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   299
			samples = iTrailingSilence;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   300
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   301
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   302
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   303
		samples = iSamplesLeft;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   304
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   305
	count = Min(samples,avail>>1);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   306
	fill.SetLength(count<<1);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   307
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   308
	if (!silence)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   309
		{ // Generate wave
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   310
		iSineWave.Generate(REINTERPRET_CAST(TInt16*,&fill[0]),count);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   311
		
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   312
		if (iRampUp)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   313
			{ 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   314
			// Ramp up volume at beginning of tone
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   315
			if (rampUp)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   316
				{ // Fade in first few samples
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   317
				if(count < KRampUpSamples)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   318
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   319
					// Partial rampup due to being at the end of the buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   320
					TInt fadeInLength = Min(KRampUpSamples,(fill.Length()>>1));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   321
					iIncompleteVolume = (count*((1<<15)/KRampUpSamples));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   322
					RampVolume(CONST_CAST(TInt16*,REINTERPRET_CAST(const TInt16*,(&fill[0]))),fadeInLength,0,iIncompleteVolume);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   323
					iRampUpRemainder = fadeInLength;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   324
					iIncompleteRampUp = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   325
					}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   326
				else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   327
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   328
					// Normal rampup
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   329
					TInt fadeInLength = Min(Min(KRampUpSamples,iSamplesLeft),(fill.Length()>>1));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   330
					RampVolume(CONST_CAST(TInt16*,REINTERPRET_CAST(const TInt16*,(&fill[0]))),fadeInLength,0,1<<15);	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   331
					iIncompleteRampUp = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   332
					}				
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   333
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   334
			else if (iIncompleteRampUp)	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   335
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   336
				// Completing partial rampup at the start of a new buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   337
				TInt fadeInLength = Min(Min((KRampUpSamples-iRampUpRemainder),iSamplesLeft),(fill.Length()>>1));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   338
				RampVolume(CONST_CAST(TInt16*,REINTERPRET_CAST(const TInt16*,(&fill[0]))),fadeInLength,iIncompleteVolume,1<<15);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   339
				iIncompleteRampUp = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   340
				}								
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   341
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   342
		if (iRampDown)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   343
			{ // Ramp down volume at end of tone
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   344
			if ((iSamplesLeft-count) < KRampDownSamples)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   345
				{ 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   346
				if(iSamplesLeft-count == 0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   347
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   348
					// Fade out last few samples
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   349
					TInt startVolume = 1<<15;;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   350
					TInt fadeOutLength = Min(Min(KRampDownSamples,iSamplesLeft),(fill.Length()>>1));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   351
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   352
					if(iIncompleteRampDown)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   353
						{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   354
						// Completing partial rampdown at the start of a new buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   355
						startVolume -= iIncompleteVolume;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   356
						iIncompleteRampDown = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   357
						}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   358
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   359
					RampVolume(CONST_CAST(TInt16*,REINTERPRET_CAST(const TInt16*,(&(fill.Right(fadeOutLength<<1))[0]))),fadeOutLength,startVolume,0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   360
					}					
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   361
				else if(iSamplesLeft-count > 0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   362
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   363
					// Partial rampdown due to being at the end of the buffer
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   364
					TInt rampDifference = (KRampDownSamples-(iSamplesLeft-count));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   365
					TInt fadeOutLength = Min(Min(rampDifference,iSamplesLeft),(fill.Length()>>1));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   366
					iIncompleteVolume = ((rampDifference*(1<<15))/KRampDownSamples);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   367
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   368
					RampVolume(CONST_CAST(TInt16*,REINTERPRET_CAST(const TInt16*,(&(fill.Right(fadeOutLength<<1))[0]))),fadeOutLength,1<<15,(1<<15)-iIncompleteVolume);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   369
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   370
					iIncompleteRampDown = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   371
					}  					
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   372
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   373
			}					
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   374
		iSamplesLeft -= count;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   375
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   376
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   377
		{ // Generate silence
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   378
		fill.FillZ(count<<1);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   379
		iTrailingSilence -= count;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   380
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   381
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   382
	used += count<<1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   383
	avail -= count<<1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   384
	fill.Shift(count<<1);	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   385
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   386
	if (avail>(iChannels<<1))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   387
		goto Restart;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   388
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   389
Finished:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   390
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   391
	aBuffer.SetLength(used);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   392
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   393
	// Do any ramp up that is required
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   394
	if (iRampUpLeft>0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   395
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   396
		TInt words = iRampUpLeft * iChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   397
		words = Min(words,used>>1);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   398
		if (words>0) // In case buffer has zero length...
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   399
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   400
			TInt left = iRampUpLeft * iChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   401
			TInt rampup = iRampUpCount * iChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   402
			iRampUpLeft -= words/iChannels;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   403
			TInt16* sample = REINTERPRET_CAST(TInt16*,&aBuffer[0]);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   404
			while (words--)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   405
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   406
				TInt32 sampleValue =   static_cast<TInt32>((*sample)*(rampup-(left--)));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   407
				*sample++ = static_cast<TInt16>(sampleValue/rampup);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   408
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   409
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   410
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   411
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   412
	return KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   413
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   414
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   415
TInt TMdaToneGenerator::DurationToSamples(const TTimeIntervalMicroSeconds& aDuration)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   416
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   417
// Convert the given duration to a sample count using the current settings
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   418
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   419
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   420
	const TInt64 KTInt64OneMilion = 1000000;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   421
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   422
	// Calculate duration as samples
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   423
	TInt64 microSeconds(aDuration.Int64());  // MSVC doesn't like "aDuration.Int64()" in line below
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   424
	TInt64 dur = ((TInt64(iRate) * TInt64(iChannels) * microSeconds) / KTInt64OneMilion);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   425
	if (I64HIGH(dur)>0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   426
		return KMaxTInt; // Ridiculous!
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   427
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   428
		return I64LOW(dur);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   429
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   430
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   431
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   432
// TMdaSimpleToneGenerator
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   433
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   434
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   435
void TMdaSimpleToneGenerator::Reset()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   436
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   437
	iPlayed = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   438
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   439
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   440
void TMdaSimpleToneGenerator::SetFrequencyAndDuration(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   441
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   442
// Store the frequency and duration of the specified sine tone
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   443
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   444
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   445
	iFrequency = aFrequency;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   446
	iDuration = aDuration;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   447
	iPlayed = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   448
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   449
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   450
TInt TMdaSimpleToneGenerator::GetNextTone()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   451
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   452
// Simple implementation - just sets the supplied frequency and duration
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   453
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   454
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   455
	// This class only plays one tone for the specified duration
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   456
	if (!iPlayed)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   457
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   458
		iSamplesLeft = I64LOW((iDuration.Int64() * TInt64(iRate))/1000000);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   459
		iSineWave.SetFrequency(iFrequency,1<<14);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   460
		iPlayed = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   461
		iTrailingSilence = 20; // Just to stop clicking
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   462
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   463
	return KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   464
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   465
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   466
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   467
// TMdaDualToneGenerator
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   468
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   469
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   470
void TMdaDualToneGenerator::Reset()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   471
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   472
	iPlayed = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   473
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   474
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   475
void TMdaDualToneGenerator::SetFrequencyAndDuration(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   476
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   477
	// Store the frequencies and duration of the specified dual tone
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   478
	iFrequencyOne = aFrequencyOne;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   479
	iFrequencyTwo = aFrequencyTwo;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   480
	iDuration = aDuration;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   481
	iPlayed = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   482
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   483
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   484
// 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   485
// This is called by TMdaToneGenerator::FillBuffer() 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   486
// to calculate the number of samples (iSamplesLeft) that will be needed 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   487
// for the tone to be played and to initialize the sine wave generator.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   488
// If the tone has already been played, then leaves iSamplesLeft 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   489
// unmodified (should be zero) to indicate that it has finished.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   490
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   491
TInt TMdaDualToneGenerator::GetNextTone()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   492
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   493
	// This class only plays one tone for the specified duration
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   494
	if (!iPlayed)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   495
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   496
		iSamplesLeft = I64LOW((iDuration.Int64() * TInt64(iRate))/KOneMillionMicroSeconds);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   497
		iSineWave.SetFrequency(iFrequencyOne, KMaxAmplitude/2, iFrequencyTwo, KMaxAmplitude/2);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   498
		iPlayed = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   499
		iTrailingSilence = KDefaultTrailingSilenceSamples; // Just to stop clicking
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   500
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   501
	return KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   502
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   503
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   504
// TMdaDTMFGenerator
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   505
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   506
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   507
const TInt KRecalculateToneLengths = KMinTInt;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   508
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   509
void TMdaDTMFGenerator::Reset()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   510
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   511
	iChar = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   512
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   513
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   514
void TMdaDTMFGenerator::SetToneDurations(const TTimeIntervalMicroSeconds32 aOn,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   515
							const TTimeIntervalMicroSeconds32 aOff,
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   516
							const TTimeIntervalMicroSeconds32 aPause)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   517
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   518
// Setup the DTMF tone durations
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   519
// aOn can be == -1 indicating should play first tone indefinately
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   520
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   521
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   522
	ASSERT(aOn.Int() >=-1);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   523
	ASSERT(aOff.Int()>=0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   524
	ASSERT(aPause.Int()>=0);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   525
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   526
	iOn = aOn;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   527
	iOff = aOff;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   528
	iPause = aPause;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   529
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   530
	iOnSamples = KRecalculateToneLengths; // Must recalculate these later
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   531
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   532
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   533
void TMdaDTMFGenerator::SetString(const TDesC& aDTMFString)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   534
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   535
// Store the DTMF string to be played
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   536
// No need to validate it as it will already have been checked 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   537
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   538
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   539
	iChar = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   540
	iDTMFString = &aDTMFString;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   541
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   542
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   543
const TUint8 KDtmfVolumeTable[4][4]=
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   544
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   545
// Relative strengths to assign to different DTMF tones
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   546
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   547
// This is only important if DTMFs are being played through a speaker
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   548
// and need to be machine-recognisable. This table compensates for frequency
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   549
// drop-off in the speaker and can boost the relative volume of some 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   550
// frequencies so they are still within tolerance.
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   551
// 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   552
// The values normally need to be determined using a frequency analyser on 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   553
// the hardware
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   554
// 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   555
// Each column == same low frequency (697, 770, 852, 941 Hz)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   556
// Each row == same high frequency (1209, 1336, 1477, 1633 Hz)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   557
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   558
// The value are interpreted as ratios:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   559
//		0  == 100% low
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   560
//		7f == 50% low, 50% high
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   561
//		ff == 100% high
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   562
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   563
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   564
	{38,27,29,37},
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   565
	{46,36,36,46},
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   566
	{62,47,49,58},
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   567
	{70,56,60,68}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   568
	};
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   569
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   570
const TUint8 KDtmfTone697=0x0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   571
const TUint8 KDtmfTone770=0x1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   572
const TUint8 KDtmfTone852=0x2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   573
const TUint8 KDtmfTone941=0x3;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   574
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   575
const TUint8 KDtmfTone1209=0x00;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   576
const TUint8 KDtmfTone1336=0x10;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   577
const TUint8 KDtmfTone1477=0x20;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   578
const TUint8 KDtmfTone1633=0x30;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   579
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   580
const TUint8 KDtmfToneTable[16]=
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   581
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   582
	KDtmfTone941|KDtmfTone1336,//0
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   583
	KDtmfTone697|KDtmfTone1209,//1
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   584
	KDtmfTone697|KDtmfTone1336,//2
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   585
	KDtmfTone697|KDtmfTone1477,//3
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   586
	KDtmfTone770|KDtmfTone1209,//4
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   587
	KDtmfTone770|KDtmfTone1336,//5
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   588
	KDtmfTone770|KDtmfTone1477,//6
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   589
	KDtmfTone852|KDtmfTone1209,//7
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   590
	KDtmfTone852|KDtmfTone1336,//8
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   591
	KDtmfTone852|KDtmfTone1477,//9
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   592
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   593
	KDtmfTone697|KDtmfTone1633,//A
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   594
	KDtmfTone770|KDtmfTone1633,//B
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   595
	KDtmfTone852|KDtmfTone1633,//C
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   596
	KDtmfTone941|KDtmfTone1633,//D
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   597
	KDtmfTone941|KDtmfTone1209,//E or *
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   598
	KDtmfTone941|KDtmfTone1477,//F or #
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   599
	};
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   600
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   601
TInt TMdaDTMFGenerator::GetNextTone()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   602
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   603
// Setup frequency/duration/silence settings for next DTMF tone
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   604
// Supported characters are 0-9 A-F * # , and any kind of white space
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   605
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   606
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   607
	TBool onlyPlayFirstTone = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   608
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   609
	if (iOnSamples == KRecalculateToneLengths)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   610
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   611
		// Must recalculate tone durations as samples
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   612
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   613
		// Handle special case where tone on duration negative
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   614
		// - meaning play first character indefinately
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   615
		if (iOn.Int()>=0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   616
			iOnSamples = DurationToSamples(TInt64(iOn.Int()));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   617
		else 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   618
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   619
			onlyPlayFirstTone = ETrue;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   620
			iOnSamples = -1; 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   621
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   622
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   623
		iOffSamples = DurationToSamples(TInt64(iOff.Int()));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   624
		iPauseSamples = DurationToSamples(TInt64(iPause.Int()));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   625
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   626
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   627
	ASSERT(iDTMFString);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   628
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   629
	if (iChar==iDTMFString->Length())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   630
		return KErrNone; // Finished. Nothing to do
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   631
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   632
	TInt highFrequency = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   633
	TInt highVolume = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   634
	TInt lowFrequency = 0; 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   635
	TInt lowVolume =0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   636
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   637
Retry:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   638
   	TChar c((*iDTMFString)[iChar++]);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   639
   	if ((TUint)c=='#' || (TUint)c=='*' || c.IsHexDigit())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   640
   		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   641
    	TInt tableIndex;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   642
		switch ((TUint)c)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   643
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   644
		case '*':
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   645
			tableIndex=14;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   646
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   647
		case '#':
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   648
			tableIndex=15;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   649
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   650
		default:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   651
			if (c.IsDigit())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   652
    			tableIndex=(TUint)c-'0';
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   653
			else //letter
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   654
		   		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   655
				c.UpperCase();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   656
    			tableIndex=(TUint)c-'A'+10;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   657
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   658
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   659
		TInt high=KDtmfToneTable[tableIndex]&0xf0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   660
		TInt low=KDtmfToneTable[tableIndex]&0x0f;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   661
		switch(high)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   662
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   663
		case KDtmfTone1209:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   664
			highFrequency=1209;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   665
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   666
		case KDtmfTone1336:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   667
			highFrequency=1336;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   668
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   669
		case KDtmfTone1477:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   670
			highFrequency=1477;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   671
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   672
		default://KDtmfTone1633:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   673
			highFrequency=1633;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   674
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   675
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   676
		switch(low)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   677
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   678
		case KDtmfTone697:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   679
			lowFrequency=697;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   680
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   681
		case KDtmfTone770:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   682
			lowFrequency=770;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   683
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   684
		case KDtmfTone852:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   685
			lowFrequency=852;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   686
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   687
		default://KDtmfTone941:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   688
			lowFrequency=941;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   689
			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   690
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   691
		high>>=4;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   692
		const TUint8* dtmfVolumes=&KDtmfVolumeTable[0][0];
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   693
		TInt volume=dtmfVolumes[((low)<<2)+(high)]<<7;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   694
		highVolume = volume;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   695
		lowVolume = (1<<15)-volume;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   696
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   697
		iTrailingSilence = iOffSamples;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   698
		iSamplesLeft = iOnSamples;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   699
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   700
   	else if ((TUint)c==',')
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   701
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   702
  		iTrailingSilence = iPauseSamples;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   703
 		iSamplesLeft = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   704
    	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   705
	else if (c.IsSpace())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   706
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   707
		if (iChar < iDTMFString->Length())
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   708
			goto Retry;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   709
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   710
	else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   711
		return KErrCorrupt;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   712
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   713
	if (iOnSamples < 0) // Play only first character for ever
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   714
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   715
		iTrailingSilence = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   716
		iSamplesLeft = iRate * iChannels; // One second of samples
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   717
		iChar = 0; // Reset so this character is played again next time
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   718
		iRampDown = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   719
		if (!onlyPlayFirstTone)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   720
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   721
			iRampUp = EFalse;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   722
			// This is not the first time around so we should not
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   723
			// reset the tone generator - it will already have the
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   724
			// correct settings and setting them again would cause
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   725
			// an audible discontinuity
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   726
			return KErrNone; 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   727
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   728
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   729
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   730
	iSineWave.SetFrequency(highFrequency,highVolume,lowFrequency,lowVolume);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   731
	return KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   732
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   733
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   734
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   735
// TMdaSequenceGenerator
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   736
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   737
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   738
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   739
// Sequence constants
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   740
// 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   741
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   742
//const TInt KMaxFixedSequenceStack=KMaxSequenceStack;//Max nesting level of FixedSequences * 2 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   743
#ifdef _DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   744
const TInt16 KFixedSequenceSignatureOne='S'+('Q'<<8); 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   745
const TInt16 KFixedSequenceSignatureTwo='N'+('C'<<8);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   746
#endif // _DEBUG
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   747
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   748
const TInt KFixedSequenceFunctionReturn=-1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   749
const TInt KFixedSequenceFunctionStartLoop=-2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   750
const TInt KFixedSequenceFunctionEndLoop=-3;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   751
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   752
void TMdaSequenceGenerator::Reset()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   753
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   754
	iInstructionPtr = REINTERPRET_CAST(const TInt16*,&((*iSequenceData)[0]));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   755
	iInstructionPtr += 2; // Skip signature
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   756
	iStackIndex = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   757
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   758
	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   759
void TMdaSequenceGenerator::SetSequenceData(const TDesC8& aSequenceData)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   760
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   761
// Store the sequence data to be played
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   762
// No need to validate it as it will already have been checked 
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   763
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   764
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   765
	iSequenceData = &aSequenceData;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   766
	iInstructionPtr = REINTERPRET_CAST(const TInt16*,&aSequenceData[0]);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   767
	iLastInstruction = iInstructionPtr + (iSequenceData->Length()>>1) - 1;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   768
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   769
	// These are asserts because this should not be called if signature not present
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   770
	ASSERT(*iInstructionPtr == KFixedSequenceSignatureOne);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   771
	ASSERT(*(iInstructionPtr+1) == KFixedSequenceSignatureTwo);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   772
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   773
	iInstructionPtr += 2; // Skip signature
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   774
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   775
	iStackIndex = 0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   776
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   777
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   778
TInt TMdaSequenceGenerator::GetNextTone()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   779
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   780
//
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   781
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   782
	ASSERT(iInstructionPtr); // Sanity check
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   783
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   784
	TInt ret = KRequestPending;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   785
	while (ret == KRequestPending)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   786
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   787
		if (iInstructionPtr > iLastInstruction)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   788
			ret = KErrCorrupt;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   789
		else if (*iInstructionPtr<=0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   790
	   		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   791
	   		switch (*iInstructionPtr)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   792
	   			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   793
	   		case KFixedSequenceFunctionReturn: // End of sequence
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   794
				ret = KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   795
				break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   796
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   797
	   		case KFixedSequenceFunctionStartLoop:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   798
				if (iStackIndex>2) // Validate - can only nest twice
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   799
					ret = KErrCorrupt;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   800
				else if ((iInstructionPtr+2) > iLastInstruction)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   801
					ret = KErrCorrupt; // Don't run off end of sequence
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   802
				else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   803
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   804
		   			iStack[iStackIndex++]=(TInt)(iInstructionPtr+2);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   805
		   			iStack[iStackIndex++]=(TInt)*(iInstructionPtr+1);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   806
	   				iInstructionPtr+=2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   807
					}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   808
	   			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   809
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   810
	   		case KFixedSequenceFunctionEndLoop:
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   811
				if (iStackIndex==0) // Validate - must already be nested
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   812
					ret = KErrCorrupt;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   813
				else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   814
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   815
		   			if ((--iStack[iStackIndex-1])!=0)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   816
		   				iInstructionPtr=(TInt16*)iStack[iStackIndex-2];
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   817
		   			else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   818
		   				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   819
		   				iStackIndex-=2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   820
		   				iInstructionPtr++;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   821
		   				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   822
					}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   823
	   			break;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   824
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   825
	   		default: // Bad sequence
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   826
				ret = KErrCorrupt;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   827
	   			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   828
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   829
		else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   830
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   831
			if ((iInstructionPtr+5) > iLastInstruction)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   832
				ret = KErrCorrupt; // Don't run off end of sequence
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   833
			else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   834
				{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   835
				iSamplesLeft = *iInstructionPtr++;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   836
				TInt freqOne = *iInstructionPtr++;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   837
				TInt volOne  = *iInstructionPtr++;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   838
				TInt freqTwo = *iInstructionPtr++;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   839
				TInt volTwo  = *iInstructionPtr++;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   840
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   841
				if ((volOne> 1<<15)||(volTwo > 1<<15))
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   842
					ret = KErrCorrupt;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   843
				else	
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   844
					{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   845
					iSineWave.SetFrequency(freqOne,volOne,freqTwo,volTwo);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   846
					ret = KErrNone;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   847
					}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   848
				}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   849
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   850
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   851
	return ret;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   852
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   853
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   854
// ---------------------------------
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   855
// Code to generate sine table files used by tone generator
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   856
// Optionally called from InitL()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   857
// #define GENERATE_SINE_TABLES 1
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   858
#ifdef GENERATE_SINE_TABLES
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   859
LOCAL_C GenerateSineTableL()
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   860
	{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   861
	_LIT(KSineFile,"sine.txt");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   862
	_LIT(KSineIncFile,"sineinc.txt");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   863
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   864
	RFile file;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   865
	file.Replace(MdaManager::Fs(),KSineFile,EFileWrite);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   866
	CleanupClosePushL(file);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   867
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   868
	RFile file2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   869
	file2.Replace(MdaManager::Fs(),KSineIncFile,EFileWrite);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   870
	CleanupClosePushL(file2);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   871
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   872
	const TReal pi=3.141592653589;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   873
	const TReal twopi=pi*2;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   874
	const TReal samples = 256.0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   875
	const TReal step = twopi/samples;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   876
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   877
	TBuf8<128> sinebuffer;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   878
	TBuf8<128> incbuffer;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   879
	TReal res;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   880
	TInt first=0;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   881
	TInt last=KMaxTInt;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   882
	TInt current;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   883
	_LIT8(KFormat,"%6d,");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   884
	_LIT8(KNewLine,"\n");
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   885
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   886
	for(TReal angle=0.0;angle<=(twopi-step);) // Copes with rounding errors
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   887
		{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   888
		sinebuffer.Zero();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   889
		incbuffer.Zero();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   890
		for (int i=0;i<8;i++)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   891
			{
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   892
			User::LeaveIfError(Math::Sin(res,angle));
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   893
			current = TInt(KMaxTInt16*res);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   894
			sinebuffer.AppendFormat(KFormat,current);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   895
			if (last != KMaxTInt)
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   896
				incbuffer.AppendFormat(KFormat,current-last);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   897
			else
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   898
				first = current;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   899
			last = current;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   900
			angle += step;
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   901
			}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   902
		sinebuffer.Append(KNewLine);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   903
		incbuffer.Append(KNewLine);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   904
		file.Write(sinebuffer);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   905
		file2.Write(incbuffer);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   906
		}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   907
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   908
	// Write fine difference to incbuffer - differnece between first and last
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   909
	incbuffer.Zero();
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   910
	incbuffer.AppendFormat(KFormat,first-last);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   911
	incbuffer.Append(KNewLine);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   912
	file2.Write(incbuffer);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   913
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   914
	CleanupStack::PopAndDestroy(2);
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   915
	}
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   916
#endif
79dd3e2336a0 2010wk36_01
hgs
parents:
diff changeset
   917
//-------------------------------