summaryrefslogtreecommitdiff
path: root/apps/plugins/zxbox/spsound.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/zxbox/spsound.c')
-rw-r--r--apps/plugins/zxbox/spsound.c288
1 files changed, 288 insertions, 0 deletions
diff --git a/apps/plugins/zxbox/spsound.c b/apps/plugins/zxbox/spsound.c
new file mode 100644
index 0000000000..3ff2690d00
--- /dev/null
+++ b/apps/plugins/zxbox/spsound.c
@@ -0,0 +1,288 @@
1/*
2 * Copyright (C) 1996-1998 Szeredi Miklos 2006 Anton Romanov
3 * Email: mszeredi@inf.bme.hu
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version. See the file COPYING.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 */
20
21/* #define DEBUG_AUDIO */
22
23#include "spsound.h"
24
25#include "zxconfig.h"
26#include "spperif.h"
27#include "z80.h"
28#include "misc.h"
29#include "interf.h"
30#include "spmain.h"
31
32#include <stdio.h>
33
34int bufframes = 1;
35
36int sound_avail = 0;
37int sound_on = 1;
38
39int sound_to_autoclose = 0;
40int doneplay=0;
41
42
43#ifdef HAVE_SOUND
44
45#include "stdlib.h"
46#include "file.h"
47#include "time.h"
48#include "errno.h"
49#include "string.h"
50
51
52
53#define SKIPTIME 5000
54
55static int last_not_played=0;
56
57#define SPS_OPENED 0
58#define SPS_AUTOCLOSED -1
59#define SPS_BUSY -2
60#define SPS_CLOSED -3
61#define SPS_NONEXIST -4
62
63static int sndstate = SPS_CLOSED;
64
65static void close_snd(int normal);
66unsigned short my_buf[TMNUM*2*3*2] IBSS_ATTR;
67
68
69const byte lin8_ulaw[] = {
70 31, 31, 31, 32, 32, 32, 32, 33,
71 33, 33, 33, 34, 34, 34, 34, 35,
72 35, 35, 35, 36, 36, 36, 36, 37,
73 37, 37, 37, 38, 38, 38, 38, 39,
74 39, 39, 39, 40, 40, 40, 40, 41,
75 41, 41, 41, 42, 42, 42, 42, 43,
76 43, 43, 43, 44, 44, 44, 44, 45,
77 45, 45, 45, 46, 46, 46, 46, 47,
78 47, 47, 47, 48, 48, 49, 49, 50,
79 50, 51, 51, 52, 52, 53, 53, 54,
80 54, 55, 55, 56, 56, 57, 57, 58,
81 58, 59, 59, 60, 60, 61, 61, 62,
82 62, 63, 63, 64, 65, 66, 67, 68,
83 69, 70, 71, 72, 73, 74, 75, 76,
84 77, 78, 79, 81, 83, 85, 87, 89,
85 91, 93, 95, 99, 103, 107, 111, 119,
86 255, 247, 239, 235, 231, 227, 223, 221,
87 219, 217, 215, 213, 211, 209, 207, 206,
88 205, 204, 203, 202, 201, 200, 199, 198,
89 197, 196, 195, 194, 193, 192, 191, 191,
90 190, 190, 189, 189, 188, 188, 187, 187,
91 186, 186, 185, 185, 184, 184, 183, 183,
92 182, 182, 181, 181, 180, 180, 179, 179,
93 178, 178, 177, 177, 176, 176, 175, 175,
94 175, 175, 174, 174, 174, 174, 173, 173,
95 173, 173, 172, 172, 172, 172, 171, 171,
96 171, 171, 170, 170, 170, 170, 169, 169,
97 169, 169, 168, 168, 168, 168, 167, 167,
98 167, 167, 166, 166, 166, 166, 165, 165,
99 165, 165, 164, 164, 164, 164, 163, 163,
100 163, 163, 162, 162, 162, 162, 161, 161,
101 161, 161, 160, 160, 160, 160, 159, 159,
102};
103
104static void open_snd(void)
105{
106 sndstate = SPS_OPENED;
107 sound_avail=1;
108 rb->pcm_play_stop();
109 rb->pcm_set_frequency(44100);
110
111}
112
113static void close_snd(int normal)
114{
115 (void)normal;
116 sound_avail = 0;
117 rb->pcm_play_stop();
118 rb->pcm_set_frequency(44100);
119}
120
121
122
123void init_spect_sound(void)
124{
125#if 1 /* TODO: Is this OK? */
126 open_snd();
127#endif
128}
129
130
131//#define VOLREDUCE settings.volume
132//
133#ifndef VOLREDUCE
134#define VOLREDUCE 0
135#endif
136
137#define CONVU8(x) ((byte) (((x) >> VOLREDUCE) + 128))
138
139#ifdef CONVERT_TO_ULAW
140# define CONV(x) lin8_ulaw[(int) CONVU8(x)]
141#else
142# define CONV(x) CONVU8(x)
143#endif
144
145#define HIGH_PASS(hp, sv) (((hp) * 15 + (sv)) >> 4)
146#define TAPESOUND(tsp) ((*tsp) >> 4)
147
148static void process_sound(void)
149{
150 static int soundhp;
151 int i;
152 byte *sb;
153 register int sv;
154
155 sb = sp_sound_buf;
156 if(last_not_played) {
157 soundhp = *sb;
158 last_not_played = 0;
159 }
160
161 if(!sp_playing_tape) {
162 for(i = TMNUM; i; sb++,i--) {
163 sv = *sb;
164 soundhp = HIGH_PASS(soundhp, sv);
165 *sb = CONV(sv - soundhp);
166 }
167 }
168 else {
169 signed char *tsp;
170
171 tsp = sp_tape_sound;
172 for(i = TMNUM; i; sb++,tsp++,i--) {
173 sv = *sb + TAPESOUND(tsp);
174 soundhp = (soundhp * 15 + sv)>>4;
175 *sb = CONV(sv - soundhp);
176 }
177 }
178}
179
180void autoclose_sound(void)
181{
182 /* do we have any reason to autoclose sound? */
183#if 0
184 if(sound_on && sound_to_autoclose && sndstate >= SPS_CLOSED) {
185 close_snd(1);
186 sndstate = SPS_AUTOCLOSED;
187 }
188#endif
189}
190void get_more(unsigned char** start, size_t* size)
191{
192 doneplay = 1;
193 *start = (unsigned char*)(my_buf);
194 *size = TMNUM*4*3*2;
195}
196
197/* sp_sound_buf is Unsigned 8 bit, Rate 8000 Hz, Mono */
198
199void write_buf(void){
200 int i,j;
201
202 /* still not sure what is the best way to do this */
203#if 0
204 my_buf[i] = /*(sp_sound_buf[i]<<8)-0x8000*/sp_sound_buf[i]<<8;
205
206
207 for (i = 0, j = 0; i<TMNUM; i++, j+=6)
208 my_buf[j] = my_buf[j+1] = my_buf[j+2] = my_buf[j+3] = my_buf[j+4] = my_buf[j+5] = (((byte)sp_sound_buf[i])<<8) >> settings.volume;
209#endif
210
211
212 for (i = 0, j = 0; i<TMNUM; i++, j+=12)
213 my_buf[j] = my_buf[j+1] = my_buf[j+2] = my_buf[j+3]\
214 = my_buf[j+4] = my_buf[j+5] = my_buf[j+6]\
215 = my_buf[j+7] = my_buf[j+8] = my_buf[j+9] \
216 = my_buf[j+10] = my_buf[j+11] \
217 = (((byte)sp_sound_buf[i])<<8) >> settings.volume;
218
219 rb->pcm_play_data(&get_more,NULL,0);
220
221#if 0
222 /* can use to save and later analyze what we produce */
223 i = rb->open ( "/sound.raw" , O_WRONLY | O_APPEND | O_CREAT );
224 rb->write ( i , sp_sound_buf , TMNUM );
225 rb->close (i);
226
227
228 i = rb->open ( "/sound2.raw" , O_WRONLY | O_APPEND |O_CREAT);
229 rb->write ( i , (unsigned char *)my_buf , TMNUM*4*3 );
230 rb->close (i);
231#endif
232
233
234 while(!doneplay)
235 rb->yield();
236
237}
238void play_sound(int evenframe)
239{
240 if(evenframe) return;
241 if(!sound_on) {
242 if(sndstate <= SPS_CLOSED) return;
243 if(sndstate < SPS_OPENED) {
244 sndstate = SPS_CLOSED;
245 return;
246 }
247 close_snd(1);
248 return;
249 }
250
251 z80_proc.sound_change = 0;
252
253 process_sound();
254
255 write_buf();
256}
257
258
259void setbufsize(void)
260{
261
262}
263
264
265#else /* HAVE_SOUND */
266
267/* Dummy functions */
268
269void setbufsize(void)
270{
271}
272
273void init_spect_sound(void)
274{
275}
276
277void play_sound(int evenframe)
278{
279 (void)evenframe;
280}
281
282void autoclose_sound(void)
283{
284}
285
286#endif /* NO_SOUND */
287
288