action_gui GUI_whichbutton(int x, int y, SDL_Surface * pscreen, struct vdIn *videoIn) { int nbutton, retval; FIXED scaleh = TO_FIXED(pscreen->h) / (videoIn->height + 32); int nheight = FROM_FIXED(scaleh * videoIn->height); if (y < nheight) return (A_VIDEO); nbutton = FROM_FIXED(scaleh * 32); /* 8 buttons across the screen, corresponding to 0-7 extand to 16*/ retval = (x * 16) / (pscreen->w); /* Bottom half of the button denoted by flag|0x10 */ if (y > (nheight + (nbutton / 2))) retval |= 0x10; return ((action_gui) retval); }
void Effects_Buffer::apply_config() { int i; if ( !bufs_size ) return; s.treble = TO_FIXED( config_.treble ); bool echo_dirty = false; fixed_t old_feedback = s.feedback; s.feedback = TO_FIXED( config_.feedback ); if ( !old_feedback && s.feedback ) echo_dirty = true; // delays for ( i = stereo; --i >= 0; ) { long delay = config_.delay [i] * sample_rate() / 1000 * stereo; delay = max( delay, long (max_read * stereo) ); delay = min( delay, long (echo_size - max_read * stereo) ); if ( s.delay [i] != delay ) { s.delay [i] = delay; echo_dirty = true; } } // side channels for ( i = 2; --i >= 0; ) { chans [i+2].cfg.vol = chans [i].cfg.vol = config_.side_chans [i].vol * 0.5f; chans [i+2].cfg.pan = chans [i].cfg.pan = config_.side_chans [i].pan; } // convert volumes for ( i = chans.size(); --i >= 0; ) { chan_t& ch = chans [i]; ch.vol [0] = TO_FIXED( ch.cfg.vol - ch.cfg.vol * ch.cfg.pan ); ch.vol [1] = TO_FIXED( ch.cfg.vol + ch.cfg.vol * ch.cfg.pan ); if ( ch.cfg.surround ) ch.vol [0] = -ch.vol [0]; } assign_buffers(); // set side channels for ( i = chans.size(); --i >= 0; ) { chan_t& ch = chans [i]; ch.channel.left = chans [ch.cfg.echo*2 ].channel.center; ch.channel.right = chans [ch.cfg.echo*2+1].channel.center; } bool old_echo = !no_echo && !no_effects; // determine whether effects and echo are needed at all no_effects = true; no_echo = true; for ( i = chans.size(); --i >= extra_chans; ) { chan_t& ch = chans [i]; if ( ch.cfg.echo && s.feedback ) no_echo = false; if ( ch.vol [0] != TO_FIXED( 1 ) || ch.vol [1] != TO_FIXED( 1 ) ) no_effects = false; } if ( !no_echo ) no_effects = false; if ( chans [0].vol [0] != TO_FIXED( 1 ) || chans [0].vol [1] != TO_FIXED( 0 ) || chans [1].vol [0] != TO_FIXED( 0 ) || chans [1].vol [1] != TO_FIXED( 1 ) ) no_effects = false; if ( !config_.enabled ) no_effects = true; if ( no_effects ) { for ( i = chans.size(); --i >= 0; ) { chan_t& ch = chans [i]; ch.channel.center = &bufs [2]; ch.channel.left = &bufs [0]; ch.channel.right = &bufs [1]; } } mixer.bufs [0] = &bufs [0]; mixer.bufs [1] = &bufs [1]; mixer.bufs [2] = &bufs [2]; if ( echo_dirty || (!old_echo && (!no_echo && !no_effects)) ) clear_echo(); channels_changed(); }
void Effects_Buffer::assign_buffers() { // assign channels to buffers int buf_count = 0; for ( int i = 0; i < (int) chans.size(); i++ ) { // put second two side channels at end to give priority to main channels // in case closest matching is necessary int x = i; if ( i > 1 ) x += 2; if ( x >= (int) chans.size() ) x -= (chans.size() - 2); chan_t& ch = chans [x]; int b = 0; for ( ; b < buf_count; b++ ) { if ( ch.vol [0] == bufs [b].vol [0] && ch.vol [1] == bufs [b].vol [1] && (ch.cfg.echo == bufs [b].echo || !s.feedback) ) break; } if ( b >= buf_count ) { if ( buf_count < bufs_max ) { bufs [b].vol [0] = ch.vol [0]; bufs [b].vol [1] = ch.vol [1]; bufs [b].echo = ch.cfg.echo; buf_count++; } else { // TODO: this is a mess, needs refinement dprintf( "Effects_Buffer ran out of buffers; using closest match\n" ); b = 0; fixed_t best_dist = TO_FIXED( 8 ); for ( int h = buf_count; --h >= 0; ) { #define CALC_LEVELS( vols, sum, diff, surround ) \ fixed_t sum, diff;\ bool surround = false;\ {\ fixed_t vol_0 = vols [0];\ if ( vol_0 < 0 ) vol_0 = -vol_0, surround = true;\ fixed_t vol_1 = vols [1];\ if ( vol_1 < 0 ) vol_1 = -vol_1, surround = true;\ sum = vol_0 + vol_1;\ diff = vol_0 - vol_1;\ } CALC_LEVELS( ch.vol, ch_sum, ch_diff, ch_surround ); CALC_LEVELS( bufs [h].vol, buf_sum, buf_diff, buf_surround ); fixed_t dist = abs( ch_sum - buf_sum ) + abs( ch_diff - buf_diff ); if ( ch_surround != buf_surround ) dist += TO_FIXED( 1 ) / 2; if ( s.feedback && ch.cfg.echo != bufs [h].echo ) dist += TO_FIXED( 1 ) / 2; if ( best_dist > dist ) { best_dist = dist; b = h; } } } } //dprintf( "ch %d->buf %d\n", x, b ); ch.channel.center = &bufs [b]; } }
int main(int argc, char **argv) { struct tap tapfile; struct wav wavfile; FILE *infile; long pulse; long i; fixedpoint len, accum; long channels[2]; int wave[2]; int sample; getopts(argc, argv); if (invert) { wave[0] = LOW; wave[1] = HIGH; } else { wave[0] = HIGH; wave[1] = LOW; } if (optind == argc) { infile = stdin; } else if (optind == argc - 1) { if (!strcmp(argv[optind], "-")) { infile = stdin; } else { infile = fopen(argv[optind], "rb"); if (!infile) { perror(argv[optind]); return 1; } } } else { fprintf(stderr, "%s: too many arguments\n", argv0); usage(); return 1; } if (tap_read_header(&tapfile, infile)) { fprintf(stderr, "%s: error reading TAP file\n", argv0); return 1; } wavfile.SampleRate = samplerate; wavfile.BitsPerSample = 8; wavfile.NumChannels = 1; if (wav_write_header(&wavfile, stdout)) { fprintf(stderr, "%s: error writing WAV file\n", argv0); return 1; } filter_init(&lowpass_filter, lowpass_freq, wavfile.SampleRate); #if 0 /* put one initial sample so the first pulse is recognized */ channels[0] = wave[1]; wav_put_sample(&wavfile, channels); accum = TO_FIXED(1.5); #else accum = TO_FIXED(2); #endif while ((pulse = tap_get_pulse(&tapfile)) >= 0) { //fprintf(stderr, "pulse: %6ld (%04lx)\n", pulse, pulse); //if (pulse < 8*256) //++pulsehist[pulse/8]; len = TO_FIXED(((double)pulse * samplerate / PAL_MHZ / speed / 1000000)); if (len < TO_FIXED(2)) { fprintf(stderr, "%s: warning: pulse length (%ld) is less than 2 samples\n", argv0, pulse); } #if 0 accum = FIXED_F(len + accum); #else len += accum; accum = FIXED_F(len); #endif #if 0 fprintf(stderr, "%ld.%03ld 0.%03ld \n", FIXED_I(len), FIXED_F(len) * 1000 / FIXED_ONE, FIXED_F(accum) * 1000 / FIXED_ONE); #endif for (i = 0; i < FIXED_I(len) / 2 - 1; ++i) { channels[0] = filter_lowpass(&lowpass_filter, wave[0]) << 16; wav_put_sample(&wavfile, channels); } for (; i < FIXED_I(len) - 2; ++i) { channels[0] = filter_lowpass(&lowpass_filter, wave[1]) << 16; wav_put_sample(&wavfile, channels); } #if 0 channels[0] = FIXED_MUL(wave[1], accum) + FIXED_MUL(wave[0], FIXED_ONE - accum); wav_put_sample(&wavfile, channels); #else sample = FIXED_MUL(wave[1], accum); channels[0] = filter_lowpass(&lowpass_filter, sample) << 16; wav_put_sample(&wavfile, channels); sample -= wave[1]; channels[0] = filter_lowpass(&lowpass_filter, sample) << 16; wav_put_sample(&wavfile, channels); #endif } wav_close(&wavfile); return 0; }