1 
2 /*
3  *   O2EM Free Odyssey2 / Videopac+ Emulator
4  *
5  *   Created by Daniel Boris <dboris@comcast.net>  (c) 1997,1998
6  *
7  *   Developed by Andre de la Rocha   <adlroc@users.sourceforge.net>
8  *             Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
9  *
10  *   http://o2em.sourceforge.net
11  *
12  *
13  *
14  *   O2 Voice emulation
15  */
16 
17 
18 #include "vmachine.h"
19 #include "cpu.h"
20 #include "voice.h"
21 
22 static int16_t *voices[9][128];
23 static int voice_bank=0;
24 static int voice_num=-1;
25 static int voice_addr=0;
26 static int voice_ok=0;
27 static int voice_st=0;
28 static unsigned long clk_voice_start=0;
29 
load_voice_samples(char * path)30 void load_voice_samples(char *path)
31 {
32 #ifndef __LIBRETRO__
33    int bank, sam, i, ld=0;
34    char name[MAXC];
35    int16_t *sp=NULL;
36 
37    printf("Loading voice samples...  ");
38    fflush(stdout);
39 
40    for (i=0; i<9; i++) {
41       for (sam=0; sam<128; sam++) {
42 
43          if (i)
44             bank = 0xE8+i-1;
45          else
46             bank = 0xE4;
47 
48          sprintf(name,"%svoice/%02x%02x.wav",path,bank,sam+0x80);
49 
50          voices[i][sam] = load_sample(name);
51 
52          if (!voices[i][sam]) {
53             sprintf(name,"%svoice/%02X%02X.WAV",path,bank,sam+0x80);
54             voices[i][sam] = load_sample(name);
55          }
56 
57          if (voices[i][sam]) {
58             ld++;
59             if (!sp) sp = voices[i][sam];
60          }
61 
62       }
63    }
64 
65    printf("%d samples loaded\n",ld);
66 
67    if (ld>0){
68       voice_num = allocate_voice(sp);
69       if (voice_num != -1)
70          voice_ok=1;
71       else {
72          printf("  ERROR: could not allocate sound card voice\n");
73          voice_ok=0;
74       }
75    }
76 #endif
77 
78 }
79 
80 
update_voice(void)81 void update_voice(void)
82 {
83 #ifndef __LIBRETRO__
84    if (!voice_ok) return;
85    if (voice_st==2) {
86       if (voice_get_position(voice_num) < 0){
87          if ((voice_bank>=0) && (voice_bank<9) && (voice_addr>=0x80) && (voice_addr<=0xff)) {
88             if (voices[voice_bank][voice_addr-0x80]) {
89                reallocate_voice(voice_num, voices[voice_bank][voice_addr-0x80]);
90                voice_set_volume(voice_num, (255*app_data.vvolume)/100);
91                voice_start(voice_num);
92                clk_voice_start = clk_counter;
93                voice_st=1;
94             } else {
95                voice_st=0;
96             }
97          }
98       }
99    } else if (voice_st==1) {
100       if ((voice_get_position(voice_num) < 0) || (clk_counter-clk_voice_start>20) ) {
101          voice_st=0;
102       }
103    }
104 #endif
105 }
106 
107 
trigger_voice(int addr)108 void trigger_voice(int addr)
109 {
110 #ifndef __LIBRETRO__
111    if (voice_ok){
112       if (voice_st) update_voice();
113       if ((voice_st==0) && (voice_bank>=0) && (voice_bank<9) && (addr>=0x80) && (addr<=0xff)){
114          voice_addr = addr;
115          voice_st = 2;
116          update_voice();
117       }
118    }
119 #endif
120 }
121 
122 
set_voice_bank(int bank)123 void set_voice_bank(int bank){
124 #ifndef __LIBRETRO__
125 	if (!voice_ok) return;
126 	if ((bank>=0) && (bank<=8)) voice_bank = bank;
127 #endif
128 }
129 
130 
get_voice_status(void)131 int get_voice_status(void){
132 #ifndef __LIBRETRO__
133 	if (voice_ok){
134 		update_voice();
135 		if (voice_st) return 1;
136 	}
137 #endif
138 	return 0;
139 }
140 
141 
reset_voice(void)142 void reset_voice(void){
143 #ifndef __LIBRETRO__
144 	if (voice_ok) {
145 		voice_stop(voice_num);
146 		voice_bank=0;
147 		voice_addr=0;
148 		voice_st=0;
149 	}
150 #endif
151 }
152 
153 
mute_voice(void)154 void mute_voice(void){
155 #ifndef __LIBRETRO__
156 	if (voice_ok) {
157 		voice_stop(voice_num);
158 	}
159 #endif
160 }
161 
162 
close_voice(void)163 void close_voice(void){
164 #ifndef __LIBRETRO__
165 	reset_voice();
166 #endif
167 	voice_ok=0;
168 }
169 
170 
171