-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathRoVoice_phonemes.c
137 lines (120 loc) · 3.83 KB
/
RoVoice_phonemes.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
RoverVoice - portable TTS library in C
Copyright (C) 2020 Tim K/RoverAMD <timprogrammer@rambler.ru>
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CON-
SEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLI-
GENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#define ROVERVOICE_ACCESS_PRIVATE
#include "RoVoice_uncross.h"
struct RoverPhoneme_s {
char representedLetter;
char* path;
char* vid;
RoverPhoneme* previous;
RoverPhoneme* next;
};
RoverPhoneme* RoverPhonemeCreate(const char* vid, const char ltr) {
if (!vid || isspace(ltr) != 0 || isblank(ltr) != 0 || (ispunct(ltr) != 0 && ltr != '!'))
return NULL;
char* voicePath = RoverVoiceGetVoicePath(vid);
if (!voicePath)
return NULL;
char* phonemeLetterPath = calloc(strlen(voicePath) + 7, sizeof(char));
char* otherPhonemeLetterPath = calloc(strlen(voicePath) + 8, sizeof(char));
sprintf(phonemeLetterPath, "%s/%c.wav", voicePath, ltr);
sprintf(otherPhonemeLetterPath, "%s/_%c.wav", voicePath, ltr);
RoverVoiceFixPath(phonemeLetterPath);
RoverVoiceFixPath(otherPhonemeLetterPath);
if (RoverVoiceFileExists(otherPhonemeLetterPath)) {
free(phonemeLetterPath);
phonemeLetterPath = otherPhonemeLetterPath;
}
if (!RoverVoiceFileExists(phonemeLetterPath)) {
fprintf(stderr, "'%s' - no such file\n", phonemeLetterPath);
free(phonemeLetterPath);
return NULL;
}
RoverPhoneme* phnm = malloc(sizeof(RoverPhoneme));
phnm->vid = rvstrdup(vid);
phnm->representedLetter = ltr;
phnm->path = phonemeLetterPath;
phnm->previous = NULL;
phnm->next = NULL;
return phnm;
}
bool RoverPhonemeSetAssociatedCharacter(RoverPhoneme* phm, const char letter) {
if (!phm)
return false;
RoverPhoneme* stuntDouble = RoverPhonemeCreate(phm->vid, letter);
if (!stuntDouble)
return false;
phm->representedLetter = letter;
phm->path = rvstrdup(stuntDouble->path);
RoverPhonemeRelease(stuntDouble);
return true;
}
void RoverPhonemeDump(const RoverPhoneme* phnm) {
(void)(phnm);
#ifdef DEBUG
if (!phnm)
fprintf(stderr, "(null)\n");
else
fprintf(stderr, "<RoverPhoneme*> %p { letter = '%c', path = \"%s\", previous = %p, next = %p }\n", phnm, phnm->representedLetter, phnm->path, phnm->previous, phnm->next);
#endif
}
bool RoverPhonemeDoMakeUpException(const RoverPhoneme* phnm, const char* expr) {
if (!phnm || !expr || strlen(expr) < 2)
return false;
if (expr[0] != phnm->representedLetter)
return false;
RoverPhoneme* current = RoverPhonemeGetNext(phnm);
for (unsigned i = 1; i < strlen(expr); i++) {
if (!current || current->representedLetter != expr[i])
return false;
current = RoverPhonemeGetNext(phnm);
}
return true;
}
bool RoverPhonemeSetNext(RoverPhoneme* phnm, RoverPhoneme* nextPhnm) {
if (!phnm)
return false;
phnm->next = nextPhnm;
return true;
}
bool RoverPhonemeSetPrevious(RoverPhoneme* phnm, RoverPhoneme* prevPhnm) {
if (!phnm)
return false;
phnm->previous = prevPhnm;
return true;
}
RoverPhoneme* RoverPhonemeGetNext(const RoverPhoneme* phnm) {
if (!phnm)
return NULL;
return phnm->next;
}
bool RoverPhonemeTryPlay(const RoverPhoneme* phnm) {
RoverPhonemeDump(phnm);
if (!phnm)
return false;
return RoverVoiceAudioPlayerWrapper(phnm->path);
}
char RoverPhonemeGetAssociatedCharacter(const RoverPhoneme* phnm) {
if (!phnm)
return '\0';
return phnm->representedLetter;
}
void RoverPhonemeRelease(RoverPhoneme* phnm) {
if (!phnm)
return;
phnm->previous = NULL;
phnm->next = NULL;
free(phnm);
}