fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

rc759: Add exponential decay to the speaker output

+157 -149
+150 -141
src/arch/rc759/speaker.c
··· 5 5 /***************************************************************************** 6 6 * File name: src/arch/rc759/speaker.c * 7 7 * Created: 2012-07-08 by Hampa Hug <hampa@hampa.ch> * 8 - * Copyright: (C) 2012 Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2012-2021 Hampa Hug <hampa@hampa.ch> * 9 9 *****************************************************************************/ 10 10 11 11 /***************************************************************************** ··· 33 33 #endif 34 34 35 35 36 + static void rc759_spk_flush (rc759_speaker_t *spk); 37 + static void rc759_spk_check (rc759_speaker_t *spk); 38 + 39 + 40 + void rc759_spk_init (rc759_speaker_t *spk) 41 + { 42 + spk->drv = NULL; 43 + 44 + spk->playing = 0; 45 + 46 + spk->speaker_out = 0; 47 + spk->speaker_val = 0x8000; 48 + spk->sample_acc = 0x8000; 49 + 50 + spk->timeout_clk = 0; 51 + spk->timeout_val = 0x8000; 52 + 53 + spk->clk = 0; 54 + spk->rem = 0; 55 + 56 + spk->srate = 44100; 57 + 58 + spk->input_clock = 1000000; 59 + 60 + spk->lowpass_freq = 0; 61 + 62 + snd_iir2_init (&spk->iir); 63 + 64 + spk->buf_cnt = 0; 65 + 66 + rc759_spk_set_volume (spk, 500); 67 + 68 + spk->speaker_out = 1; 69 + spk->speaker_val = spk->val_on; 70 + } 71 + 72 + void rc759_spk_free (rc759_speaker_t *spk) 73 + { 74 + rc759_spk_flush (spk); 75 + 76 + if (spk->drv != NULL) { 77 + snd_close (spk->drv); 78 + } 79 + } 80 + 81 + rc759_speaker_t *rc759_spk_new (void) 82 + { 83 + rc759_speaker_t *spk; 84 + 85 + if ((spk = malloc (sizeof (rc759_speaker_t))) == NULL) { 86 + return (NULL); 87 + } 88 + 89 + rc759_spk_init (spk); 90 + 91 + return (spk); 92 + } 93 + 94 + void rc759_spk_del (rc759_speaker_t *spk) 95 + { 96 + if (spk != NULL) { 97 + rc759_spk_free (spk); 98 + free (spk); 99 + } 100 + } 101 + 102 + void rc759_spk_set_clk_fct (rc759_speaker_t *spk, void *ext, void *fct) 103 + { 104 + spk->get_clk_ext = ext; 105 + spk->get_clk = fct; 106 + } 107 + 108 + void rc759_spk_set_input_clock (rc759_speaker_t *spk, unsigned long clk) 109 + { 110 + spk->input_clock = clk; 111 + } 112 + 113 + int rc759_spk_set_driver (rc759_speaker_t *spk, const char *driver, unsigned long srate) 114 + { 115 + if (spk->drv != NULL) { 116 + snd_close (spk->drv); 117 + } 118 + 119 + if ((spk->drv = snd_open (driver)) == NULL) { 120 + return (1); 121 + } 122 + 123 + spk->srate = srate; 124 + 125 + if (snd_set_params (spk->drv, 1, srate, 1)) { 126 + snd_close (spk->drv); 127 + spk->drv = NULL; 128 + return (1); 129 + } 130 + 131 + return (0); 132 + } 133 + 134 + void rc759_spk_set_lowpass (rc759_speaker_t *spk, unsigned long freq) 135 + { 136 + spk->lowpass_freq = freq; 137 + 138 + snd_iir2_set_lowpass (&spk->iir, spk->lowpass_freq, spk->srate); 139 + } 140 + 141 + void rc759_spk_set_volume (rc759_speaker_t *spk, unsigned vol) 142 + { 143 + if (vol > 1000) { 144 + vol = 1000; 145 + } 146 + 147 + vol = (32768UL * vol) / 1000; 148 + 149 + if (vol > 32767) { 150 + vol = 32767; 151 + } 152 + 153 + spk->val_on = 0x8000 + vol; 154 + spk->val_off = 0x8000 - vol; 155 + } 156 + 157 + void rc759_spk_set_out (rc759_speaker_t *spk, unsigned char val) 158 + { 159 + rc759_spk_check (spk); 160 + 161 + val = (val != 0); 162 + 163 + if (spk->speaker_out == val) { 164 + return; 165 + } 166 + 167 + spk->speaker_out = val; 168 + spk->speaker_val = spk->speaker_out ? spk->val_on : spk->val_off; 169 + } 170 + 36 171 static 37 172 void rc759_spk_play (rc759_speaker_t *spk, uint16_t *buf, unsigned cnt) 38 173 { ··· 91 226 #endif 92 227 93 228 spk->playing = 1; 94 - 95 - spk->timeout_val = 0x8000; 229 + spk->sample_acc = spk->speaker_val; 230 + spk->timeout_val = spk->speaker_val; 96 231 spk->timeout_clk = 0; 97 - 98 - spk->sample_acc = 0x8000; 99 - 100 232 spk->rem = 0; 101 233 102 234 /* Fill the sound buffer a bit so we don't underrun immediately */ 103 - rc759_spk_write (spk, 0, spk->srate / 8); 235 + rc759_spk_write (spk, 0, spk->srate / 16); 104 236 } 105 237 106 238 static ··· 118 250 static 119 251 void rc759_spk_check (rc759_speaker_t *spk) 120 252 { 121 - unsigned long clk, tmp, acc; 122 - uint16_t val; 123 - 124 - val = spk->speaker_out ? spk->val_on : spk->val_off; 253 + unsigned long clk, tmp, acc; 125 254 126 255 tmp = spk->get_clk (spk->get_clk_ext); 127 256 clk = tmp - spk->clk; 128 257 spk->clk = tmp; 129 258 130 259 if (spk->playing == 0) { 131 - if (spk->timeout_val != val) { 260 + if (spk->timeout_val != spk->speaker_val) { 132 261 rc759_spk_on (spk); 133 262 } 263 + 134 264 return; 135 265 } 136 - else if (spk->timeout_val == val) { 266 + 267 + if (spk->timeout_val == spk->speaker_val) { 137 268 spk->timeout_clk += clk; 138 269 139 270 if (spk->timeout_clk > (1 * spk->input_clock)) { ··· 142 273 } 143 274 } 144 275 else { 145 - spk->timeout_val = val; 276 + spk->timeout_val = spk->speaker_val; 146 277 spk->timeout_clk = clk; 147 278 } 148 279 149 280 acc = spk->sample_acc; 150 281 151 282 while (clk > 0) { 152 - /* about 3000 Hz cut-off */ 153 - acc = (63 * acc + val) / 64; 283 + /* 15158 Hz cut-off */ 284 + acc = (63 * acc + spk->speaker_val) / 64; 154 285 155 286 spk->rem += spk->srate; 156 287 157 288 if (spk->rem >= spk->input_clock) { 158 289 rc759_spk_write (spk, acc ^ 0x8000, 1); 159 290 spk->rem -= spk->input_clock; 291 + 292 + spk->speaker_val = (255UL * spk->speaker_val + 0x8000) / 256; 160 293 } 161 294 162 295 clk -= 1; ··· 165 298 spk->sample_acc = acc; 166 299 } 167 300 168 - void rc759_spk_init (rc759_speaker_t *spk) 169 - { 170 - spk->drv = NULL; 171 - 172 - spk->playing = 0; 173 - 174 - spk->speaker_out = 0; 175 - 176 - spk->timeout_clk = 0; 177 - spk->timeout_val = 0x8000; 178 - 179 - spk->clk = 0; 180 - spk->rem = 0; 181 - 182 - spk->sample_acc = 0x8000; 183 - 184 - spk->srate = 44100; 185 - 186 - spk->input_clock = 1000000; 187 - 188 - spk->lowpass_freq = 0; 189 - 190 - snd_iir2_init (&spk->iir); 191 - 192 - spk->buf_cnt = 0; 193 - 194 - rc759_spk_set_volume (spk, 500); 195 - 196 - spk->timeout_val = spk->val_off; 197 - } 198 - 199 - void rc759_spk_free (rc759_speaker_t *spk) 200 - { 201 - rc759_spk_flush (spk); 202 - 203 - if (spk->drv != NULL) { 204 - snd_close (spk->drv); 205 - } 206 - } 207 - 208 - rc759_speaker_t *rc759_spk_new (void) 209 - { 210 - rc759_speaker_t *spk; 211 - 212 - spk = malloc (sizeof (rc759_speaker_t)); 213 - 214 - if (spk == NULL) { 215 - return (NULL); 216 - } 217 - 218 - rc759_spk_init (spk); 219 - 220 - return (spk); 221 - } 222 - 223 - void rc759_spk_del (rc759_speaker_t *spk) 224 - { 225 - if (spk != NULL) { 226 - rc759_spk_free (spk); 227 - free (spk); 228 - } 229 - } 230 - 231 - void rc759_spk_set_clk_fct (rc759_speaker_t *spk, void *ext, void *fct) 232 - { 233 - spk->get_clk_ext = ext; 234 - spk->get_clk = fct; 235 - } 236 - 237 - void rc759_spk_set_input_clock (rc759_speaker_t *spk, unsigned long clk) 238 - { 239 - spk->input_clock = clk; 240 - } 241 - 242 - int rc759_spk_set_driver (rc759_speaker_t *spk, const char *driver, unsigned long srate) 243 - { 244 - if (spk->drv != NULL) { 245 - snd_close (spk->drv); 246 - } 247 - 248 - spk->drv = snd_open (driver); 249 - 250 - if (spk->drv == NULL) { 251 - return (1); 252 - } 253 - 254 - spk->srate = srate; 255 - 256 - if (snd_set_params (spk->drv, 1, srate, 1)) { 257 - snd_close (spk->drv); 258 - spk->drv = NULL; 259 - return (1); 260 - } 261 - 262 - return (0); 263 - } 264 - 265 - void rc759_spk_set_lowpass (rc759_speaker_t *spk, unsigned long freq) 266 - { 267 - spk->lowpass_freq = freq; 268 - 269 - snd_iir2_set_lowpass (&spk->iir, spk->lowpass_freq, spk->srate); 270 - } 271 - 272 - void rc759_spk_set_volume (rc759_speaker_t *spk, unsigned vol) 273 - { 274 - if (vol > 1000) { 275 - vol = 1000; 276 - } 277 - 278 - vol = (32767UL * vol) / 1000; 279 - 280 - spk->val_msk = 0; 281 - spk->val_on = 0x8000 + vol; 282 - spk->val_off = 0x8000 - vol; 283 - } 284 - 285 - void rc759_spk_set_out (rc759_speaker_t *spk, unsigned char val) 286 - { 287 - rc759_spk_check (spk); 288 - 289 - spk->speaker_out = (val != 0); 290 - } 291 - 292 - void rc759_spk_clock (rc759_speaker_t *spk, unsigned long cnt) 301 + void rc759_spk_clock (rc759_speaker_t *spk, unsigned cnt) 293 302 { 294 303 rc759_spk_check (spk); 295 304 }
+7 -8
src/arch/rc759/speaker.h
··· 5 5 /***************************************************************************** 6 6 * File name: src/arch/rc759/speaker.h * 7 7 * Created: 2012-07-08 by Hampa Hug <hampa@hampa.ch> * 8 - * Copyright: (C) 2012 Hampa Hug <hampa@hampa.ch> * 8 + * Copyright: (C) 2012-2021 Hampa Hug <hampa@hampa.ch> * 9 9 *****************************************************************************/ 10 10 11 11 /***************************************************************************** ··· 36 36 char playing; 37 37 38 38 char speaker_out; 39 + uint16_t speaker_val; 40 + uint16_t sample_acc; 41 + 42 + uint16_t val_on; 43 + uint16_t val_off; 39 44 40 45 uint16_t timeout_val; 41 46 unsigned long timeout_clk; ··· 43 48 unsigned long clk; 44 49 unsigned long rem; 45 50 46 - unsigned long sample_acc; 47 - 48 51 unsigned long srate; 49 52 50 53 unsigned long input_clock; ··· 54 57 55 58 unsigned buf_cnt; 56 59 uint16_t buf[RC759_SPEAKER_BUF]; 57 - 58 - uint16_t val_msk; 59 - uint16_t val_on; 60 - uint16_t val_off; 61 60 62 61 void *get_clk_ext; 63 62 unsigned long (*get_clk) (void *ext); ··· 82 81 83 82 void rc759_spk_set_out (rc759_speaker_t *spk, unsigned char val); 84 83 85 - void rc759_spk_clock (rc759_speaker_t *spk, unsigned long cnt); 84 + void rc759_spk_clock (rc759_speaker_t *spk, unsigned cnt); 86 85 87 86 88 87 #endif