2 * Copyright (C) 1996-1998 Szeredi Miklos 2006 Anton Romanov
3 * Email: mszeredi@inf.bme.hu
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.
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.
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.
21 /* #define DEBUG_AUDIO */
39 int sound_to_autoclose
= 0;
55 static int last_not_played
=0;
58 #define SPS_AUTOCLOSED -1
61 #define SPS_NONEXIST -4
63 static int sndstate
= SPS_CLOSED
;
65 static void close_snd(int normal
);
66 unsigned short my_buf
[TMNUM
*2*3*2];
69 const 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,
104 static void open_snd(void)
106 sndstate
= SPS_OPENED
;
109 #if INPUT_SRC_CAPS != 0
110 /* Select playback */
111 rb
->audio_set_input_source(AUDIO_SRC_PLAYBACK
, SRCF_PLAYBACK
);
112 rb
->audio_set_output_source(AUDIO_SRC_PLAYBACK
);
114 rb
->pcm_set_frequency(SAMPR_44
);
117 static void close_snd(int normal
)
122 rb
->pcm_set_frequency(HW_SAMPR_DEFAULT
);
127 void init_spect_sound(void)
129 #if 1 /* TODO: Is this OK? */
139 #define CONVU8(x) ((byte) (((x) >> VOLREDUCE) + 128))
141 #ifdef CONVERT_TO_ULAW
142 # define CONV(x) lin8_ulaw[(int) CONVU8(x)]
144 # define CONV(x) CONVU8(x)
147 #define HIGH_PASS(hp, sv) (((hp) * 15 + (sv)) >> 4)
148 #define TAPESOUND(tsp) ((*tsp) >> 4)
150 static void process_sound(void)
158 if(last_not_played
) {
163 if(!sp_playing_tape
) {
164 for(i
= TMNUM
; i
; sb
++,i
--) {
166 soundhp
= HIGH_PASS(soundhp
, sv
);
167 *sb
= CONV(sv
- soundhp
);
174 for(i
= TMNUM
; i
; sb
++,tsp
++,i
--) {
175 sv
= *sb
+ TAPESOUND(tsp
);
176 soundhp
= (soundhp
* 15 + sv
)>>4;
177 *sb
= CONV(sv
- soundhp
);
182 void autoclose_sound(void)
184 /* do we have any reason to autoclose sound? */
186 if(sound_on
&& sound_to_autoclose
&& sndstate
>= SPS_CLOSED
) {
188 sndstate
= SPS_AUTOCLOSED
;
192 void get_more(unsigned char** start
, size_t* size
)
200 /* sp_sound_buf is Unsigned 8 bit, Rate 8000 Hz, Mono */
202 void write_buf(void){
205 /* still not sure what is the best way to do this */
207 my_buf
[i
] = /*(sp_sound_buf[i]<<8)-0x8000*/sp_sound_buf
[i
]<<8;
210 for (i
= 0, j
= 0; i
<TMNUM
; i
++, j
+=6)
211 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
;
215 for (i
= 0, j
= 0; i
<TMNUM
; i
++, j
+=12)
216 my_buf
[j
] = my_buf
[j
+1] = my_buf
[j
+2] = my_buf
[j
+3]\
217 = my_buf
[j
+4] = my_buf
[j
+5] = my_buf
[j
+6]\
218 = my_buf
[j
+7] = my_buf
[j
+8] = my_buf
[j
+9] \
219 = my_buf
[j
+10] = my_buf
[j
+11] \
220 = (((byte
)sp_sound_buf
[i
])<<8) >> settings
.volume
;
222 rb
->pcm_play_data(&get_more
,(unsigned char*)(my_buf
),TMNUM
*4*3*2);
225 /* can use to save and later analyze what we produce */
226 i
= rb
->open ( "/sound.raw" , O_WRONLY
| O_APPEND
| O_CREAT
);
227 rb
->write ( i
, sp_sound_buf
, TMNUM
);
231 i
= rb
->open ( "/sound2.raw" , O_WRONLY
| O_APPEND
|O_CREAT
);
232 rb
->write ( i
, (unsigned char *)my_buf
, TMNUM
*4*3 );
241 void play_sound(int evenframe
)
243 if(evenframe
) return;
245 if(sndstate
<= SPS_CLOSED
) return;
246 if(sndstate
< SPS_OPENED
) {
247 sndstate
= SPS_CLOSED
;
254 z80_proc
.sound_change
= 0;
262 void setbufsize(void)
268 #else /* HAVE_SOUND */
270 /* Dummy functions */
272 void setbufsize(void)
276 void init_spect_sound(void)
280 void play_sound(int evenframe
)
285 void autoclose_sound(void)
289 #endif /* NO_SOUND */