Skip to content

Commit ec2d6b9

Browse files
committed
Speech: compute some frequencies on demand. Save about 200 bytes RAM.
1 parent fa73626 commit ec2d6b9

File tree

2 files changed

+54
-108
lines changed

2 files changed

+54
-108
lines changed

source/lib/sam/RenderTabs.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const unsigned char sampledConsonantFlags[] =
101101

102102

103103
//tab45056
104-
unsigned char freq1data[]=
104+
const unsigned char freq1data[]=
105105
{
106106
0x00 ,0x13 ,0x13 ,0x13 ,0x13 , 0xA , 0xE ,0x12
107107
, 0x18 ,0x1A ,0x16 ,0x14 ,0x10 ,0x14 , 0xE ,0x12
@@ -115,8 +115,10 @@ unsigned char freq1data[]=
115115
, 6 ,0xA ,0xA , 6 , 6 , 6 , 0x2C , 0x13
116116
};
117117

118+
unsigned char get_freq1(unsigned char pos, unsigned char mouth);
119+
118120
//tab451356
119-
unsigned char freq2data[]=
121+
const unsigned char freq2data[]=
120122
{
121123
0x00 , 0x43 , 0x43 , 0x43 , 0x43 , 0x54 , 0x48 , 0x42 ,
122124
0x3E , 0x28 , 0x2C , 0x1E , 0x24 , 0x2C , 0x48 , 0x30 ,
@@ -130,6 +132,9 @@ unsigned char freq2data[]=
130132
0x6D , 0x56 , 0x6D , 0x54 , 0x54 , 0x54 , 0x7F , 0x7F
131133
};
132134

135+
unsigned char get_freq2(unsigned char pos, unsigned char throat);
136+
137+
133138
//tab45216
134139
const unsigned char freq3data[]=
135140
{

source/lib/sam/render.c

Lines changed: 47 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ extern unsigned char A, X, Y;
1616

1717

1818
void AddInflection(sam_memory* sam, unsigned char mem48, unsigned char phase1);
19-
unsigned char trans(unsigned char mem39212, unsigned char mem39213);
2019

2120

2221
// contains the final soundbuffer
@@ -393,8 +392,8 @@ do
393392
// copy from the source to the frames list
394393
do
395394
{
396-
sam->render.frequency1[X] = freq1data[Y]; // F1 frequency
397-
sam->render.frequency2[X] = freq2data[Y]; // F2 frequency
395+
sam->render.frequency1[X] = get_freq1(Y, sam->common.mouth); // F1 frequency
396+
sam->render.frequency2[X] = get_freq2(Y, sam->common.throat); // F2 frequency
398397
sam->render.frequency3[X] = freq3data[Y]; // F3 frequency
399398
sam->render.amplitude1[X] = ampl1data[Y]; // F1 amplitude
400399
sam->render.amplitude2[X] = ampl2data[Y]; // F2 amplitude
@@ -891,117 +890,59 @@ void AddInflection(sam_memory* sam, unsigned char mem48, unsigned char phase1)
891890
goto pos48398;
892891
}
893892

893+
static inline unsigned char trans(unsigned char mem39212, unsigned char mem39213) {
894+
return (mem39212*mem39213) >> 7;
895+
}
896+
894897
/*
895898
SAM's voice can be altered by changing the frequencies of the
896899
mouth formant (F1) and the throat formant (F2). Only the voiced
897900
phonemes (5-29 and 48-53) are altered.
898901
*/
899-
void SetMouthThroat(unsigned char mouth, unsigned char throat)
900-
{
901-
unsigned char initialFrequency;
902-
unsigned char newFrequency = 0;
903-
//unsigned char mouth; //mem38880
904-
//unsigned char throat; //mem38881
905-
906-
// mouth formants (F1) 5..29
907-
unsigned char mouthFormants5_29[30] = {
908-
0, 0, 0, 0, 0, 10,
909-
14, 19, 24, 27, 23, 21, 16, 20, 14, 18, 14, 18, 18,
910-
16, 13, 15, 11, 18, 14, 11, 9, 6, 6, 6};
911-
912-
// throat formants (F2) 5..29
913-
unsigned char throatFormants5_29[30] = {
914-
255, 255,
915-
255, 255, 255, 84, 73, 67, 63, 40, 44, 31, 37, 45, 73, 49,
916-
36, 30, 51, 37, 29, 69, 24, 50, 30, 24, 83, 46, 54, 86};
917-
918-
// there must be no zeros in this 2 tables
919-
// formant 1 frequencies (mouth) 48..53
920-
unsigned char mouthFormants48_53[6] = {19, 27, 21, 27, 18, 13};
921-
922-
// formant 2 frequencies (throat) 48..53
923-
unsigned char throatFormants48_53[6] = {72, 39, 31, 43, 30, 34};
924-
925-
unsigned char pos = 5; //mem39216
926-
//pos38942:
927-
// recalculate formant frequencies 5..29 for the mouth (F1) and throat (F2)
928-
while(pos != 30)
929-
{
930-
// recalculate mouth frequency
931-
initialFrequency = mouthFormants5_29[pos];
932-
if (initialFrequency != 0) newFrequency = trans(mouth, initialFrequency);
933-
freq1data[pos] = newFrequency;
934-
935-
// recalculate throat frequency
936-
initialFrequency = throatFormants5_29[pos];
937-
if(initialFrequency != 0) newFrequency = trans(throat, initialFrequency);
938-
freq2data[pos] = newFrequency;
939-
pos++;
940-
}
941902

942-
//pos39059:
943-
// recalculate formant frequencies 48..53
944-
pos = 48;
945-
Y = 0;
946-
while(pos != 54)
947-
{
948-
// recalculate F1 (mouth formant)
949-
initialFrequency = mouthFormants48_53[Y];
950-
newFrequency = trans(mouth, initialFrequency);
951-
freq1data[pos] = newFrequency;
952-
953-
// recalculate F2 (throat formant)
954-
initialFrequency = throatFormants48_53[Y];
955-
newFrequency = trans(throat, initialFrequency);
956-
freq2data[pos] = newFrequency;
957-
Y++;
958-
pos++;
959-
}
960-
}
903+
static const unsigned char recalculate[] = {
904+
0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
905+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
906+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
907+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
908+
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
909+
1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
910+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
911+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
912+
0, 0, 0, 0
913+
};
961914

915+
static const unsigned char mouth_formants[] = {
916+
0, 0, 0, 0, 0, 10, 14, 19, 24, 27,
917+
23, 21, 16, 20, 14, 18, 14, 18, 18, 16,
918+
13, 15, 11, 18, 14, 11, 9, 6, 6, 6,
919+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
920+
0, 0, 0, 0, 0, 0, 0, 0, 19, 27,
921+
21, 27, 18, 13, 0,
922+
};
962923

963-
//return = (mem39212*mem39213) >> 1
964-
unsigned char trans(unsigned char mem39212, unsigned char mem39213)
965-
{
966-
//pos39008:
967-
unsigned char carry;
968-
int temp;
969-
unsigned char mem39214, mem39215;
970-
A = 0;
971-
mem39215 = 0;
972-
mem39214 = 0;
973-
X = 8;
974-
do
975-
{
976-
carry = mem39212 & 1;
977-
mem39212 = mem39212 >> 1;
978-
if (carry != 0)
979-
{
980-
/*
981-
39018: LSR 39212
982-
39021: BCC 39033
983-
*/
984-
carry = 0;
985-
A = mem39215;
986-
temp = (int)A + (int)mem39213;
987-
A = A + mem39213;
988-
if (temp > 255) carry = 1;
989-
mem39215 = A;
990-
}
991-
temp = mem39215 & 1;
992-
mem39215 = (mem39215 >> 1) | (carry?128:0);
993-
carry = temp;
994-
//39033: ROR 39215
995-
X--;
996-
} while (X != 0);
997-
temp = mem39214 & 128;
998-
mem39214 = (mem39214 << 1) | (carry?1:0);
999-
carry = temp;
1000-
temp = mem39215 & 128;
1001-
mem39215 = (mem39215 << 1) | (carry?1:0);
1002-
carry = temp;
1003-
1004-
return mem39215;
924+
925+
unsigned char get_freq1(unsigned char pos, unsigned char mouth) {
926+
if (recalculate[pos]) {
927+
return trans(mouth, mouth_formants[pos]);
928+
} else {
929+
return freq1data[pos];
930+
}
1005931
}
1006932

933+
static const unsigned char throat_formants[] = {
934+
0, 0, 0, 0, 0, 84, 73, 67, 63, 40,
935+
44, 31, 37, 45, 73, 49, 36, 30, 51, 37,
936+
29, 69, 24, 50, 30, 24, 83, 46, 54, 86,
937+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
938+
0, 0, 0, 0, 0, 0, 0, 0, 72, 39,
939+
31, 43, 30, 34, 0,
940+
};
1007941

942+
unsigned char get_freq2(unsigned char pos, unsigned char throat) {
943+
if (recalculate[pos]) {
944+
return trans(throat, throat_formants[pos]);
945+
} else {
946+
return freq2data[pos];
947+
}
948+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy