Annotation of uae/src/audio.c, revision 1.1.1.17

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
1.1.1.16  root        4:   * Paula audio emulation
1.1       root        5:   *
                      6:   * Copyright 1995, 1996, 1997 Bernd Schmidt
                      7:   * Copyright 1996 Marcus Sundberg
                      8:   * Copyright 1996 Manfred Thole
1.1.1.16  root        9:   * Copyright 2006 Toni Wilen
                     10:   *
                     11:   * new filter algorithm and anti&sinc interpolators by Antti S. Lankila
1.1       root       12:   */
                     13: 
                     14: #include "sysconfig.h"
                     15: #include "sysdeps.h"
                     16: 
1.1.1.17! root       17: #include <math.h>
        !            18: 
1.1       root       19: #include "options.h"
                     20: #include "memory.h"
                     21: #include "custom.h"
1.1.1.7   root       22: #include "newcpu.h"
                     23: #include "autoconf.h"
1.1       root       24: #include "gensound.h"
                     25: #include "sounddep/sound.h"
                     26: #include "events.h"
                     27: #include "audio.h"
1.1.1.8   root       28: #include "savestate.h"
1.1.1.16  root       29: #include "sinctable.h"
                     30: #include "gui.h"
                     31: 
                     32: #define MAX_EV ~0ul
1.1       root       33: 
1.1.1.16  root       34: /* periods less than this value are replaced by this value. */
                     35: #define MIN_ALLOWED_PERIOD 16
                     36: /* reserve ~20 extra slots in sinc queue for cpu volume or some such updates
                     37:  * even at maximum period. This avoids sinc queue overflow on games like
                     38:  * battle squadron that write these low period values and do cpu-based
                     39:  * updates on paula registers, probably volume. */
                     40: #define NUMBER_OF_CPU_UPDATES_ALLOWED 20
                     41: 
                     42: #define SINC_QUEUE_LENGTH (SINC_QUEUE_MAX_AGE / MIN_ALLOWED_PERIOD + NUMBER_OF_CPU_UPDATES_ALLOWED)
                     43: 
                     44: typedef struct {
1.1.1.17! root       45:     int age, output;
1.1.1.16  root       46: } sinc_queue_t;
                     47: 
                     48: struct audio_channel_data {
                     49:     unsigned long adk_mask;
                     50:     unsigned long evtime;
                     51:     unsigned long per;
                     52:     uae_u8 dmaen, intreq2, data_written;
                     53:     uaecptr lc, pt;
                     54:     int state, wper;
                     55:     unsigned int wlen;
                     56:     int current_sample, last_sample;
                     57:     int vol;
                     58:     int *voltbl;
                     59:     uae_u16 dat, nextdat, len;
1.1.1.17! root       60:     int sample_accum, sample_accum_time;
1.1.1.16  root       61:     int sinc_output_state;
                     62:     sinc_queue_t sinc_queue[SINC_QUEUE_LENGTH];
                     63:     int sinc_queue_length;
                     64: };
                     65: 
                     66: static struct audio_channel_data audio_channel[4];
1.1.1.2   root       67: int sound_available = 0;
1.1       root       68: int sound_table[64][256];
1.1.1.2   root       69: void (*sample_handler) (void);
1.1.1.16  root       70: static void (*sample_prehandler) (unsigned long best_evtime);
1.1.1.7   root       71: 
1.1.1.16  root       72: static unsigned long scaled_sample_evtime;
1.1.1.2   root       73: static unsigned long last_cycles, next_sample_evtime;
1.1       root       74: 
1.1.1.16  root       75: unsigned int obtainedfreq;
                     76: 
1.1.1.2   root       77: void init_sound_table16 (void)
1.1       root       78: {
                     79:     int i,j;
                     80: 
                     81:     for (i = 0; i < 256; i++)
                     82:        for (j = 0; j < 64; j++)
1.1.1.17! root       83:            sound_table[j][i] = j * (uae_s8)i * (get_audio_ismono () ? 1 : 2);
1.1       root       84: }
                     85: 
                     86: #ifdef MULTIPLICATION_PROFITABLE
                     87: typedef uae_s8 sample8_t;
                     88: #define DO_CHANNEL_1(v, c) do { (v) *= audio_channel[c].vol; } while (0)
                     89: #define SBASEVAL16(logn) ((logn) == 1 ? SOUND16_BASE_VAL >> 1 : SOUND16_BASE_VAL)
1.1.1.17! root       90: #define FINISH_DATA(data, b, logn) do { if (14 - (b) + (logn) > 0) (data) >>= 14 - (b) + (logn); else (data) <<= (b) - 14 - (logn); } while (0);
1.1       root       91: #else
                     92: typedef uae_u8 sample8_t;
                     93: #define DO_CHANNEL_1(v, c) do { (v) = audio_channel[c].voltbl[(v)]; } while (0)
                     94: #define SBASEVAL16(logn) SOUND16_BASE_VAL
1.1.1.17! root       95: #define FINISH_DATA(data, b, logn)
1.1       root       96: #endif
                     97: 
1.1.1.17! root       98: static uae_u32 right_word_saved[SOUND_MAX_DELAY_BUFFER];
        !            99: static uae_u32 left_word_saved[SOUND_MAX_DELAY_BUFFER];
1.1.1.7   root      100: static int saved_ptr;
1.1       root      101: 
1.1.1.17! root      102: static int mixed_on, mixed_stereo_size, mixed_mul1, mixed_mul2;
        !           103: static int led_filter_forced, sound_use_filter, sound_use_filter_sinc, led_filter_on;
        !           104: 
        !           105: /* denormals are very small floating point numbers that force FPUs into slow
        !           106:    mode. All lowpass filters using floats are suspectible to denormals unless
        !           107:    a small offset is added to avoid very small floating point numbers. */
        !           108: #define DENORMAL_OFFSET (1E-10)
        !           109: 
        !           110: static struct filter_state {
        !           111:     float rc1, rc2, rc3, rc4, rc5;
        !           112: } sound_filter_state[4];
        !           113: 
        !           114: static float a500e_filter1_a0;
        !           115: static float a500e_filter2_a0;
        !           116: static float filter_a0; /* a500 and a1200 use the same */
        !           117: 
        !           118: enum {
        !           119:   FILTER_NONE = 0,
        !           120:   FILTER_MODEL_A500,
        !           121:   FILTER_MODEL_A1200
        !           122: };
        !           123: 
        !           124: /* Amiga has two separate filtering circuits per channel, a static RC filter
        !           125:  * on A500 and the LED filter. This code emulates both.
        !           126:  *
        !           127:  * The Amiga filtering circuitry depends on Amiga model. Older Amigas seem
        !           128:  * to have a 6 dB/oct RC filter with cutoff frequency such that the -6 dB
        !           129:  * point for filter is reached at 6 kHz, while newer Amigas have no filtering.
        !           130:  *
        !           131:  * The LED filter is complicated, and we are modelling it with a pair of
        !           132:  * RC filters, the other providing a highboost. The LED starts to cut
        !           133:  * into signal somewhere around 5-6 kHz, and there's some kind of highboost
        !           134:  * in effect above 12 kHz. Better measurements are required.
        !           135:  *
        !           136:  * The current filtering should be accurate to 2 dB with the filter on,
        !           137:  * and to 1 dB with the filter off.
        !           138: */
        !           139: 
        !           140: static int filter(int input, struct filter_state *fs)
        !           141: {
        !           142:     int o;
        !           143:     float normal_output, led_output;
        !           144: 
        !           145:     input = (uae_s16)input;
        !           146:     switch (sound_use_filter) {
        !           147:     case FILTER_NONE:
        !           148:        return input;
        !           149:     case FILTER_MODEL_A500:
        !           150:        fs->rc1 = a500e_filter1_a0 * input + (1 - a500e_filter1_a0) * fs->rc1 + DENORMAL_OFFSET;
        !           151:        fs->rc2 = a500e_filter2_a0 * fs->rc1 + (1-a500e_filter2_a0) * fs->rc2;
        !           152:        normal_output = fs->rc2;
        !           153: 
        !           154:        fs->rc3 = filter_a0 * normal_output + (1 - filter_a0) * fs->rc3;
        !           155:        fs->rc4 = filter_a0 * fs->rc3       + (1 - filter_a0) * fs->rc4;
        !           156:        fs->rc5 = filter_a0 * fs->rc4       + (1 - filter_a0) * fs->rc5;
        !           157: 
        !           158:        led_output = fs->rc5;
        !           159:        break;
        !           160: 
        !           161:     case FILTER_MODEL_A1200:
        !           162:        normal_output = input;
        !           163: 
        !           164:        fs->rc2 = filter_a0 * normal_output + (1 - filter_a0) * fs->rc2 + DENORMAL_OFFSET;
        !           165:        fs->rc3 = filter_a0 * fs->rc2       + (1 - filter_a0) * fs->rc3;
        !           166:        fs->rc4 = filter_a0 * fs->rc3       + (1 - filter_a0) * fs->rc4;
        !           167: 
        !           168:        led_output = fs->rc4;
        !           169:        break;
        !           170:     }
        !           171: 
        !           172:     if (led_filter_on)
        !           173:        o = led_output;
        !           174:     else
        !           175:        o = normal_output;
        !           176: 
        !           177:     if (o > 32767)
        !           178:        o = 32767;
        !           179:     else if (o < -32768)
        !           180:        o = -32768;
        !           181: 
        !           182:     return o;
        !           183: }
        !           184: 
        !           185: /* This computes the 1st order low-pass filter term b0.
        !           186:  * The a1 term is 1.0 - b0. The center frequency marks the -3 dB point. */
        !           187: #ifndef M_PI
        !           188: #define M_PI 3.14159265358979323846
        !           189: #endif
        !           190: static float rc_calculate_a0 (int sample_rate, int cutoff_freq)
        !           191: {
        !           192:     float omega;
        !           193:     /* The BLT correction formula below blows up if the cutoff is above nyquist. */
        !           194:     if (cutoff_freq >= sample_rate / 2)
        !           195:        return 1.0;
        !           196: 
        !           197:     omega = 2 * M_PI * cutoff_freq / sample_rate;
        !           198:     /* Compensate for the bilinear transformation. This allows us to specify the
        !           199:      * stop frequency more exactly, but the filter becomes less steep further
        !           200:      * from stopband. */
        !           201:     omega = tan (omega / 2) * 2;
        !           202:     return 1 / (1 + 1 / omega);
        !           203: }
        !           204: 
        !           205: /* Always put the right word before the left word.  */
        !           206: 
1.1.1.7   root      207: STATIC_INLINE void put_sound_word_right (uae_u32 w)
1.1       root      208: {
1.1.1.17! root      209:     if (mixed_on) {
1.1.1.7   root      210:        right_word_saved[saved_ptr] = w;
                    211:        return;
1.1       root      212:     }
                    213: 
1.1.1.7   root      214:     PUT_SOUND_WORD_RIGHT (w);
1.1       root      215: }
                    216: 
1.1.1.7   root      217: STATIC_INLINE void put_sound_word_left (uae_u32 w)
1.1.1.5   root      218: {
1.1.1.17! root      219:     if (mixed_on) {
1.1.1.7   root      220:        uae_u32 rold, lold, rnew, lnew, tmp;
1.1.1.5   root      221: 
1.1.1.7   root      222:        left_word_saved[saved_ptr] = w;
                    223:        lnew = w - SOUND16_BASE_VAL;
                    224:        rnew = right_word_saved[saved_ptr] - SOUND16_BASE_VAL;
1.1.1.5   root      225: 
1.1.1.17! root      226:        saved_ptr = (saved_ptr + 1) & mixed_stereo_size;
        !           227: 
1.1.1.7   root      228:        lold = left_word_saved[saved_ptr] - SOUND16_BASE_VAL;
1.1.1.17! root      229:        tmp = (rnew * mixed_mul2 + lold * mixed_mul1) / MIXED_STEREO_SCALE;
1.1.1.7   root      230:        tmp += SOUND16_BASE_VAL;
                    231:        PUT_SOUND_WORD_RIGHT (tmp);
1.1.1.5   root      232: 
1.1.1.7   root      233:        rold = right_word_saved[saved_ptr] - SOUND16_BASE_VAL;
1.1.1.17! root      234:        w = (lnew * mixed_mul2 + rold * mixed_mul1) / MIXED_STEREO_SCALE;
1.1.1.7   root      235:     }
                    236:     PUT_SOUND_WORD_LEFT (w);
                    237: }
1.1.1.5   root      238: 
1.1.1.7   root      239: #define DO_CHANNEL(v, c) do { (v) &= audio_channel[c].adk_mask; data += v; } while (0);
1.1.1.5   root      240: 
1.1.1.17! root      241: static void anti_prehandler (unsigned long best_evtime)
        !           242: {
        !           243:     int i, output;
        !           244:     struct audio_channel_data *acd;
        !           245: 
        !           246:     /* Handle accumulator antialiasiation */
        !           247:     for (i = 0; i < 4; i++) {
        !           248:        acd = &audio_channel[i];
        !           249:        output = (acd->current_sample * acd->vol) & acd->adk_mask;
        !           250:        acd->sample_accum += output * best_evtime;
        !           251:        acd->sample_accum_time += best_evtime;
        !           252:     }
        !           253: }
        !           254: 
        !           255: STATIC_INLINE void samplexx_anti_handler (int *datasp)
        !           256: {
        !           257:     int i;
        !           258:     for (i = 0; i < 4; i++) {
        !           259:        datasp[i] = audio_channel[i].sample_accum_time ? (audio_channel[i].sample_accum / audio_channel[i].sample_accum_time) : 0;
        !           260:        audio_channel[i].sample_accum = 0;
        !           261:        audio_channel[i].sample_accum_time = 0;
        !           262: 
        !           263:     }
        !           264: }
        !           265: 
1.1.1.16  root      266: static void sinc_prehandler (unsigned long best_evtime)
                    267: {
                    268:     int i, j, output;
                    269:     struct audio_channel_data *acd;
                    270: 
                    271:     for (i = 0; i < 4; i++) {
                    272:        acd = &audio_channel[i];
                    273:        output = (acd->current_sample * acd->vol) & acd->adk_mask;
                    274: 
                    275:        /* age the sinc queue and truncate it when necessary */
                    276:        for (j = 0; j < acd->sinc_queue_length; j += 1) {
                    277:            acd->sinc_queue[j].age += best_evtime;
                    278:            if (acd->sinc_queue[j].age >= SINC_QUEUE_MAX_AGE) {
                    279:                acd->sinc_queue_length = j;
                    280:                break;
                    281:            }
                    282:        }
                    283:        /* if output state changes, record the state change and also
                    284:         * write data into sinc queue for mixing in the BLEP */
                    285:        if (acd->sinc_output_state != output) {
                    286:            if (acd->sinc_queue_length > SINC_QUEUE_LENGTH - 1) {
                    287:                write_log ("warning: sinc queue truncated. Last age: %d.\n",
                    288:                           acd->sinc_queue[SINC_QUEUE_LENGTH-1].age);
                    289:                acd->sinc_queue_length = SINC_QUEUE_LENGTH - 1;
                    290:            }
                    291:            /* make room for new and add the new value */
                    292:            memmove (&acd->sinc_queue[1], &acd->sinc_queue[0],
                    293:                     sizeof(acd->sinc_queue[0]) * acd->sinc_queue_length);
                    294:            acd->sinc_queue_length += 1;
                    295:            acd->sinc_queue[0].age = best_evtime;
                    296:            acd->sinc_queue[0].output = output - acd->sinc_output_state;
                    297:            acd->sinc_output_state = output;
                    298:        }
                    299:     }
                    300: }
                    301: 
                    302: 
                    303: /* this interpolator performs BLEP mixing (bleps are shaped like integrated sinc
                    304:  * functions) with a type of BLEP that matches the filtering configuration. */
                    305: STATIC_INLINE void samplexx_sinc_handler (int *datasp)
                    306: {
                    307:     int i, n;
                    308:     int const *winsinc;
                    309: 
                    310:     if (sound_use_filter_sinc) {
                    311:        n = (sound_use_filter_sinc == FILTER_MODEL_A500) ? 0 : 2;
                    312:        if (led_filter_on)
                    313:            n += 1;
                    314:     } else {
                    315:        n = 4;
                    316:     }
                    317:     winsinc = winsinc_integral[n];
                    318: 
                    319:     for (i = 0; i < 4; i += 1) {
                    320:        int j, v;
                    321:        struct audio_channel_data *acd = &audio_channel[i];
                    322:        /* The sum rings with harmonic components up to infinity... */
                    323:        int sum = acd->sinc_output_state << 17;
                    324:        /* ...but we cancel them through mixing in BLEPs instead */
                    325:        for (j = 0; j < acd->sinc_queue_length; j += 1)
                    326:            sum -= winsinc[acd->sinc_queue[j].age] * acd->sinc_queue[j].output;
                    327:        v = sum >> 17;
                    328:        if (v > 32767)
                    329:            v = 32767;
                    330:        else if (v < -32768)
                    331:            v = -32768;
                    332:        datasp[i] = v;
                    333:     }
                    334: }
                    335: 
                    336: static void sample16i_sinc_handler (void)
                    337: {
                    338:     int datas[4], data1;
                    339: 
                    340:     samplexx_sinc_handler (datas);
                    341:     data1 = datas[0] + datas[3] + datas[1] + datas[2];
                    342:     FINISH_DATA (data1, 16, 2);
                    343:     PUT_SOUND_WORD (data1);
                    344:     check_sound_buffers ();
                    345: }
                    346: 
1.1.1.7   root      347: void sample16_handler (void)
                    348: {
1.1.1.13  root      349:     uae_u32 data0 = audio_channel[0].current_sample;
                    350:     uae_u32 data1 = audio_channel[1].current_sample;
                    351:     uae_u32 data2 = audio_channel[2].current_sample;
                    352:     uae_u32 data3 = audio_channel[3].current_sample;
                    353:     DO_CHANNEL_1 (data0, 0);
                    354:     DO_CHANNEL_1 (data1, 1);
                    355:     DO_CHANNEL_1 (data2, 2);
                    356:     DO_CHANNEL_1 (data3, 3);
                    357:     data0 &= audio_channel[0].adk_mask;
                    358:     data1 &= audio_channel[1].adk_mask;
                    359:     data2 &= audio_channel[2].adk_mask;
                    360:     data3 &= audio_channel[3].adk_mask;
                    361:     data0 += data1;
                    362:     data0 += data2;
                    363:     data0 += data3;
                    364:     {
                    365:        uae_u32 data = SBASEVAL16(2) + data0;
                    366:        FINISH_DATA (data, 16, 2);
1.1.1.17! root      367:        if (sound_use_filter)
        !           368:            data = filter (data, &sound_filter_state[0]);
1.1.1.13  root      369:        PUT_SOUND_WORD (data);
1.1.1.5   root      370:     }
                    371:     check_sound_buffers ();
                    372: }
                    373: 
1.1.1.17! root      374: /* This interpolator examines sample points when Paula switches the output
        !           375:  * voltage and computes the average of Paula's output */
        !           376: static void sample16i_anti_handler (void)
        !           377: {
        !           378:     int datas[4], data1;
        !           379: 
        !           380:     samplexx_anti_handler (datas);
        !           381:     data1 = datas[0] + datas[3] + datas[1] + datas[2];
        !           382:     FINISH_DATA (data1, 16, 2);
        !           383:     if (sound_use_filter)
        !           384:        data1 = filter (data1, &sound_filter_state[0]);
        !           385:     PUT_SOUND_WORD (data1);
        !           386:     check_sound_buffers ();
        !           387: }
        !           388: 
1.1.1.16  root      389: static void sample16i_rh_handler (void)
1.1.1.6   root      390: {
1.1.1.13  root      391:     unsigned long delta, ratio;
                    392: 
                    393:     uae_u32 data0 = audio_channel[0].current_sample;
                    394:     uae_u32 data1 = audio_channel[1].current_sample;
                    395:     uae_u32 data2 = audio_channel[2].current_sample;
                    396:     uae_u32 data3 = audio_channel[3].current_sample;
                    397:     uae_u32 data0p = audio_channel[0].last_sample;
                    398:     uae_u32 data1p = audio_channel[1].last_sample;
                    399:     uae_u32 data2p = audio_channel[2].last_sample;
                    400:     uae_u32 data3p = audio_channel[3].last_sample;
                    401:     DO_CHANNEL_1 (data0, 0);
                    402:     DO_CHANNEL_1 (data1, 1);
                    403:     DO_CHANNEL_1 (data2, 2);
                    404:     DO_CHANNEL_1 (data3, 3);
                    405:     DO_CHANNEL_1 (data0p, 0);
                    406:     DO_CHANNEL_1 (data1p, 1);
                    407:     DO_CHANNEL_1 (data2p, 2);
                    408:     DO_CHANNEL_1 (data3p, 3);
1.1.1.6   root      409: 
1.1.1.13  root      410:     data0 &= audio_channel[0].adk_mask;
                    411:     data0p &= audio_channel[0].adk_mask;
                    412:     data1 &= audio_channel[1].adk_mask;
                    413:     data1p &= audio_channel[1].adk_mask;
                    414:     data2 &= audio_channel[2].adk_mask;
                    415:     data2p &= audio_channel[2].adk_mask;
                    416:     data3 &= audio_channel[3].adk_mask;
                    417:     data3p &= audio_channel[3].adk_mask;
1.1.1.6   root      418: 
1.1.1.13  root      419:     /* linear interpolation and summing up... */
                    420:     delta = audio_channel[0].per;
                    421:     ratio = ((audio_channel[0].evtime % delta) << 8) / delta;
                    422:     data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
                    423:     delta = audio_channel[1].per;
                    424:     ratio = ((audio_channel[1].evtime % delta) << 8) / delta;
                    425:     data0 += (data1 * (256 - ratio) + data1p * ratio) >> 8;
                    426:     delta = audio_channel[2].per;
                    427:     ratio = ((audio_channel[2].evtime % delta) << 8) / delta;
                    428:     data0 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
                    429:     delta = audio_channel[3].per;
                    430:     ratio = ((audio_channel[3].evtime % delta) << 8) / delta;
                    431:     data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
1.1.1.6   root      432: 
1.1.1.13  root      433:     {
                    434:        uae_u32 data = SBASEVAL16(2) + data0;
                    435:        FINISH_DATA (data, 16, 2);
1.1.1.17! root      436:        if (sound_use_filter)
        !           437:            data = filter (data, &sound_filter_state[0]);
1.1.1.13  root      438:        PUT_SOUND_WORD (data);
1.1.1.6   root      439:     }
1.1.1.13  root      440: 
                    441:     check_sound_buffers ();
1.1.1.7   root      442: }
1.1.1.6   root      443: 
1.1.1.16  root      444: static void sample16i_crux_handler (void)
1.1.1.7   root      445: {
1.1.1.13  root      446:     uae_u32 data0 = audio_channel[0].current_sample;
                    447:     uae_u32 data1 = audio_channel[1].current_sample;
                    448:     uae_u32 data2 = audio_channel[2].current_sample;
                    449:     uae_u32 data3 = audio_channel[3].current_sample;
                    450:     uae_u32 data0p = audio_channel[0].last_sample;
                    451:     uae_u32 data1p = audio_channel[1].last_sample;
                    452:     uae_u32 data2p = audio_channel[2].last_sample;
                    453:     uae_u32 data3p = audio_channel[3].last_sample;
                    454:     DO_CHANNEL_1 (data0, 0);
                    455:     DO_CHANNEL_1 (data1, 1);
                    456:     DO_CHANNEL_1 (data2, 2);
                    457:     DO_CHANNEL_1 (data3, 3);
                    458:     DO_CHANNEL_1 (data0p, 0);
                    459:     DO_CHANNEL_1 (data1p, 1);
                    460:     DO_CHANNEL_1 (data2p, 2);
                    461:     DO_CHANNEL_1 (data3p, 3);
                    462: 
                    463:     data0 &= audio_channel[0].adk_mask;
                    464:     data0p &= audio_channel[0].adk_mask;
                    465:     data1 &= audio_channel[1].adk_mask;
                    466:     data1p &= audio_channel[1].adk_mask;
                    467:     data2 &= audio_channel[2].adk_mask;
                    468:     data2p &= audio_channel[2].adk_mask;
                    469:     data3 &= audio_channel[3].adk_mask;
                    470:     data3p &= audio_channel[3].adk_mask;
                    471: 
1.1.1.15  root      472:     {
1.1.1.13  root      473:        struct audio_channel_data *cdp;
                    474:        unsigned long ratio, ratio1;
1.1.1.7   root      475: #define INTERVAL (scaled_sample_evtime * 3)
1.1.1.13  root      476:        cdp = audio_channel + 0;
                    477:        ratio1 = cdp->per - cdp->evtime;
                    478:        ratio = (ratio1 << 12) / INTERVAL;
                    479:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
                    480:            ratio = 4096;
                    481:        data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12;
                    482: 
                    483:        cdp = audio_channel + 1;
                    484:        ratio1 = cdp->per - cdp->evtime;
                    485:        ratio = (ratio1 << 12) / INTERVAL;
                    486:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
                    487:            ratio = 4096;
                    488:        data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12;
                    489: 
                    490:        cdp = audio_channel + 2;
                    491:        ratio1 = cdp->per - cdp->evtime;
                    492:        ratio = (ratio1 << 12) / INTERVAL;
                    493:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
                    494:            ratio = 4096;
                    495:        data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12;
                    496: 
                    497:        cdp = audio_channel + 3;
                    498:        ratio1 = cdp->per - cdp->evtime;
                    499:        ratio = (ratio1 << 12) / INTERVAL;
                    500:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
                    501:            ratio = 4096;
                    502:        data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12;
                    503:     }
                    504:     data1 += data2;
                    505:     data0 += data3;
                    506:     data0 += data1;
                    507:     {
                    508:        uae_u32 data = SBASEVAL16(2) + data0;
                    509:        FINISH_DATA (data, 16, 2);
1.1.1.17! root      510:        if (sound_use_filter)
        !           511:            data = filter (data, &sound_filter_state[0]);
1.1.1.13  root      512:        PUT_SOUND_WORD (data);
1.1.1.7   root      513:     }
1.1.1.6   root      514:     check_sound_buffers ();
                    515: }
                    516: 
1.1.1.16  root      517: #ifdef HAVE_STEREO_SUPPORT
1.1.1.17! root      518: static void sample16si_anti_handler (void)
        !           519: {
        !           520:     int datas[4], data1, data2;
        !           521: 
        !           522:     samplexx_anti_handler (datas);
        !           523:     data1 = datas[0] + datas[3];
        !           524:     data2 = datas[1] + datas[2];
        !           525:     FINISH_DATA (data1, 16, 1);
        !           526:     if (sound_use_filter)
        !           527:        data1 = filter (data1, &sound_filter_state[0]);
        !           528:     put_sound_word_right (data1);
        !           529:     FINISH_DATA (data2, 16, 1);
        !           530:     if (sound_use_filter)
        !           531:        data2 = filter (data2, &sound_filter_state[1]);
        !           532:     put_sound_word_left (data2);
        !           533:     check_sound_buffers ();
        !           534: }
        !           535: 
1.1.1.16  root      536: static void sample16si_sinc_handler (void)
1.1       root      537: {
1.1.1.16  root      538:     int datas[4], data1, data2;
1.1       root      539: 
1.1.1.16  root      540:     samplexx_sinc_handler (datas);
                    541:     data1 = datas[0] + datas[3];
                    542:     data2 = datas[1] + datas[2];
                    543:     FINISH_DATA (data1, 16, 1);
1.1.1.17! root      544:     put_sound_word_right (data1);
1.1.1.16  root      545:     FINISH_DATA (data2, 16, 1);
1.1.1.17! root      546:     put_sound_word_left (data2);
1.1       root      547:     check_sound_buffers ();
                    548: }
                    549: 
1.1.1.2   root      550: void sample16s_handler (void)
1.1       root      551: {
1.1.1.13  root      552:     uae_u32 data0 = audio_channel[0].current_sample;
                    553:     uae_u32 data1 = audio_channel[1].current_sample;
                    554:     uae_u32 data2 = audio_channel[2].current_sample;
                    555:     uae_u32 data3 = audio_channel[3].current_sample;
                    556:     DO_CHANNEL_1 (data0, 0);
                    557:     DO_CHANNEL_1 (data1, 1);
                    558:     DO_CHANNEL_1 (data2, 2);
                    559:     DO_CHANNEL_1 (data3, 3);
                    560: 
                    561:     data0 &= audio_channel[0].adk_mask;
                    562:     data1 &= audio_channel[1].adk_mask;
                    563:     data2 &= audio_channel[2].adk_mask;
                    564:     data3 &= audio_channel[3].adk_mask;
1.1.1.15  root      565: 
1.1.1.13  root      566:     data0 += data3;
                    567:     {
                    568:        uae_u32 data = SBASEVAL16(1) + data0;
                    569:        FINISH_DATA (data, 16, 1);
1.1.1.17! root      570:        if (sound_use_filter)
        !           571:            data = filter (data, &sound_filter_state[0]);
1.1.1.13  root      572:        put_sound_word_right (data);
                    573:     }
1.1       root      574: 
1.1.1.13  root      575:     data1 += data2;
                    576:     {
1.1.1.15  root      577:        uae_u32 data = SBASEVAL16(1) + data1;
1.1.1.13  root      578:        FINISH_DATA (data, 16, 1);
1.1.1.17! root      579:        if (sound_use_filter)
        !           580:            data = filter (data, &sound_filter_state[1]);
1.1.1.13  root      581:        put_sound_word_left (data);
1.1       root      582:     }
1.1.1.7   root      583: 
1.1       root      584:     check_sound_buffers ();
                    585: }
                    586: 
1.1.1.16  root      587: static void sample16si_crux_handler (void)
1.1.1.5   root      588: {
1.1.1.13  root      589:     uae_u32 data0 = audio_channel[0].current_sample;
                    590:     uae_u32 data1 = audio_channel[1].current_sample;
                    591:     uae_u32 data2 = audio_channel[2].current_sample;
                    592:     uae_u32 data3 = audio_channel[3].current_sample;
                    593:     uae_u32 data0p = audio_channel[0].last_sample;
                    594:     uae_u32 data1p = audio_channel[1].last_sample;
                    595:     uae_u32 data2p = audio_channel[2].last_sample;
                    596:     uae_u32 data3p = audio_channel[3].last_sample;
                    597: 
                    598:     DO_CHANNEL_1 (data0, 0);
                    599:     DO_CHANNEL_1 (data1, 1);
                    600:     DO_CHANNEL_1 (data2, 2);
                    601:     DO_CHANNEL_1 (data3, 3);
                    602:     DO_CHANNEL_1 (data0p, 0);
                    603:     DO_CHANNEL_1 (data1p, 1);
                    604:     DO_CHANNEL_1 (data2p, 2);
                    605:     DO_CHANNEL_1 (data3p, 3);
                    606: 
                    607:     data0 &= audio_channel[0].adk_mask;
                    608:     data0p &= audio_channel[0].adk_mask;
                    609:     data1 &= audio_channel[1].adk_mask;
                    610:     data1p &= audio_channel[1].adk_mask;
                    611:     data2 &= audio_channel[2].adk_mask;
                    612:     data2p &= audio_channel[2].adk_mask;
                    613:     data3 &= audio_channel[3].adk_mask;
                    614:     data3p &= audio_channel[3].adk_mask;
                    615: 
1.1.1.15  root      616:     {
1.1.1.13  root      617:        struct audio_channel_data *cdp;
                    618:        unsigned long ratio, ratio1;
1.1.1.7   root      619: #define INTERVAL (scaled_sample_evtime * 3)
1.1.1.13  root      620:        cdp = audio_channel + 0;
                    621:        ratio1 = cdp->per - cdp->evtime;
                    622:        ratio = (ratio1 << 12) / INTERVAL;
                    623:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
                    624:            ratio = 4096;
                    625:        data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12;
                    626: 
                    627:        cdp = audio_channel + 1;
                    628:        ratio1 = cdp->per - cdp->evtime;
                    629:        ratio = (ratio1 << 12) / INTERVAL;
                    630:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
                    631:            ratio = 4096;
                    632:        data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12;
                    633: 
                    634:        cdp = audio_channel + 2;
                    635:        ratio1 = cdp->per - cdp->evtime;
                    636:        ratio = (ratio1 << 12) / INTERVAL;
                    637:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
                    638:            ratio = 4096;
                    639:        data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12;
                    640: 
                    641:        cdp = audio_channel + 3;
                    642:        ratio1 = cdp->per - cdp->evtime;
                    643:        ratio = (ratio1 << 12) / INTERVAL;
                    644:        if (cdp->evtime < scaled_sample_evtime || ratio1 >= INTERVAL)
                    645:            ratio = 4096;
                    646:        data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12;
                    647:     }
                    648:     data1 += data2;
                    649:     data0 += data3;
                    650:     {
                    651:        uae_u32 data = SBASEVAL16 (1) + data0;
                    652:        FINISH_DATA (data, 16, 1);
1.1.1.17! root      653:        if (sound_use_filter)
        !           654:            data = filter (data, &sound_filter_state[0]);
1.1.1.13  root      655:        put_sound_word_right (data);
                    656:     }
1.1.1.6   root      657: 
1.1.1.13  root      658:     {
                    659:        uae_u32 data = SBASEVAL16 (1) + data1;
                    660:        FINISH_DATA (data, 16, 1);
1.1.1.17! root      661:        if (sound_use_filter)
        !           662:            data = filter (data, &sound_filter_state[1]);
1.1.1.13  root      663:        put_sound_word_left (data);
                    664:     }
1.1.1.6   root      665:     check_sound_buffers ();
                    666: }
                    667: 
1.1.1.16  root      668: static void sample16si_rh_handler (void)
1.1.1.6   root      669: {
1.1.1.13  root      670:     unsigned long delta, ratio;
1.1.1.6   root      671: 
1.1.1.13  root      672:     uae_u32 data0 = audio_channel[0].current_sample;
                    673:     uae_u32 data1 = audio_channel[1].current_sample;
                    674:     uae_u32 data2 = audio_channel[2].current_sample;
                    675:     uae_u32 data3 = audio_channel[3].current_sample;
                    676:     uae_u32 data0p = audio_channel[0].last_sample;
                    677:     uae_u32 data1p = audio_channel[1].last_sample;
                    678:     uae_u32 data2p = audio_channel[2].last_sample;
                    679:     uae_u32 data3p = audio_channel[3].last_sample;
1.1.1.5   root      680: 
1.1.1.13  root      681:     DO_CHANNEL_1 (data0, 0);
                    682:     DO_CHANNEL_1 (data1, 1);
                    683:     DO_CHANNEL_1 (data2, 2);
                    684:     DO_CHANNEL_1 (data3, 3);
                    685:     DO_CHANNEL_1 (data0p, 0);
                    686:     DO_CHANNEL_1 (data1p, 1);
                    687:     DO_CHANNEL_1 (data2p, 2);
                    688:     DO_CHANNEL_1 (data3p, 3);
                    689: 
                    690:     data0 &= audio_channel[0].adk_mask;
                    691:     data0p &= audio_channel[0].adk_mask;
                    692:     data1 &= audio_channel[1].adk_mask;
                    693:     data1p &= audio_channel[1].adk_mask;
                    694:     data2 &= audio_channel[2].adk_mask;
                    695:     data2p &= audio_channel[2].adk_mask;
                    696:     data3 &= audio_channel[3].adk_mask;
                    697:     data3p &= audio_channel[3].adk_mask;
                    698: 
                    699:     /* linear interpolation and summing up... */
                    700:     delta = audio_channel[0].per;
                    701:     ratio = ((audio_channel[0].evtime % delta) << 8) / delta;
                    702:     data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
                    703:     delta = audio_channel[1].per;
                    704:     ratio = ((audio_channel[1].evtime % delta) << 8) / delta;
                    705:     data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8;
                    706:     delta = audio_channel[2].per;
                    707:     ratio = ((audio_channel[2].evtime % delta) << 8) / delta;
                    708:     data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
                    709:     delta = audio_channel[3].per;
                    710:     ratio = ((audio_channel[3].evtime % delta) << 8) / delta;
                    711:     data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
                    712:     {
                    713:        uae_u32 data = SBASEVAL16 (1) + data0;
                    714:        FINISH_DATA (data, 16, 1);
1.1.1.17! root      715:        if (sound_use_filter)
        !           716:            data = filter (data, &sound_filter_state[0]);
1.1.1.13  root      717:        put_sound_word_right (data);
                    718:     }
                    719: 
                    720:     {
                    721:        uae_u32 data = SBASEVAL16 (1) + data1;
                    722:        FINISH_DATA (data, 16, 1);
1.1.1.17! root      723:        if (sound_use_filter)
        !           724:            data = filter (data, &sound_filter_state[1]);
1.1.1.13  root      725:        put_sound_word_left (data);
                    726:     }
1.1.1.5   root      727:     check_sound_buffers ();
                    728: }
                    729: 
1.1       root      730: #else
1.1.1.2   root      731: void sample16s_handler (void)
1.1       root      732: {
1.1.1.16  root      733:     sample16_handler ();
1.1       root      734: }
1.1.1.16  root      735: static void sample16si_crux_handler (void)
1.1.1.6   root      736: {
1.1.1.16  root      737:     sample16i_crux_handler ();
1.1.1.6   root      738: }
1.1.1.16  root      739: static void sample16si_rh_handler (void)
1.1.1.6   root      740: {
1.1.1.16  root      741:     sample16i_rh_handler ();
1.1.1.6   root      742: }
1.1       root      743: #endif
                    744: 
1.1.1.16  root      745: void switch_audio_interpol (void)
1.1       root      746: {
1.1.1.16  root      747:     if (currprefs.sound_interpol == 0) {
                    748:        changed_prefs.sound_interpol = 1;
                    749:        write_log ("Interpol on: rh\n");
                    750:     } else if (currprefs.sound_interpol == 1) {
                    751:        changed_prefs.sound_interpol = 2;
                    752:        write_log ("Interpol on: crux\n");
                    753:     } else if (currprefs.sound_interpol == 2) {
                    754:        changed_prefs.sound_interpol = 3;
                    755:        write_log ("Interpol on: sinc\n");
1.1.1.17! root      756:     } else if (currprefs.sound_interpol == 3) {
        !           757:        changed_prefs.sound_interpol = 4;
        !           758:        write_log ("Interpol on: anti\n");
1.1       root      759:     } else {
1.1.1.16  root      760:        changed_prefs.sound_interpol = 0;
                    761:        write_log ("Interpol off\n");
1.1       root      762:     }
1.1.1.16  root      763:     return;
1.1       root      764: }
1.1.1.16  root      765:  
1.1.1.7   root      766: void schedule_audio (void)
                    767: {
1.1.1.16  root      768:     unsigned long best = MAX_EV;
1.1.1.7   root      769:     int i;
                    770: 
                    771:     eventtab[ev_audio].active = 0;
                    772:     eventtab[ev_audio].oldcycles = get_cycles ();
1.1.1.16  root      773:     for (i = 0; i < 4; i++) {
1.1.1.7   root      774:        struct audio_channel_data *cdp = audio_channel + i;
                    775: 
1.1.1.16  root      776:        if (cdp->evtime != MAX_EV) {
1.1.1.7   root      777:            if (best > cdp->evtime) {
                    778:                best = cdp->evtime;
                    779:                eventtab[ev_audio].active = 1;
                    780:            }
1.1.1.15  root      781:        }
1.1.1.7   root      782:     }
                    783:     eventtab[ev_audio].evtime = get_cycles () + best;
                    784: }
                    785: 
1.1.1.16  root      786: /*
                    787:  * TODO: This function has been moved here from the audio back-end layer
                    788:  * since it was common to all.
                    789:  * Needs further cleaning up and a better name - or replacing entirely.
                    790:  */
                    791: void update_sound (unsigned int freq)
                    792: {
                    793:     if (obtainedfreq) {
1.1.1.17! root      794:        if (currprefs.ntscmode)
        !           795:            scaled_sample_evtime = (unsigned long)(MAXHPOS_NTSC * MAXVPOS_NTSC * freq * CYCLE_UNIT + obtainedfreq - 1) / obtainedfreq;
        !           796:        else
        !           797:            scaled_sample_evtime = (unsigned long)(MAXHPOS_PAL * MAXVPOS_PAL * freq * CYCLE_UNIT + obtainedfreq - 1) / obtainedfreq;
1.1.1.16  root      798:     }
                    799: }
                    800: 
                    801: static void audio_handler (unsigned int nr)
1.1       root      802: {
                    803:     struct audio_channel_data *cdp = audio_channel + nr;
                    804: 
1.1.1.16  root      805:     cdp->evtime = MAX_EV;
1.1       root      806:     switch (cdp->state) {
                    807:      case 0:
1.1.1.11  root      808:        write_log ("Bug in sound code\n");
1.1       root      809:        break;
                    810: 
                    811:      case 1:
                    812:        /* We come here at the first hsync after DMA was turned on. */
1.1.1.7   root      813:        cdp->evtime = maxhpos * CYCLE_UNIT;
1.1       root      814: 
                    815:        cdp->state = 5;
                    816:        INTREQ(0x8000 | (0x80 << nr));
                    817:        if (cdp->wlen != 1)
1.1.1.9   root      818:            cdp->wlen = (cdp->wlen - 1) & 0xFFFF;
1.1.1.17! root      819:        cdp->nextdat = chipmem_agnus_wget (cdp->pt);
1.1       root      820: 
                    821:        cdp->pt += 2;
                    822:        break;
                    823: 
                    824:      case 5:
                    825:        /* We come here at the second hsync after DMA was turned on. */
                    826:        if (currprefs.produce_sound == 0)
1.1.1.7   root      827:            cdp->per = PERIOD_MAX;
1.1       root      828: 
1.1.1.2   root      829:        cdp->evtime = cdp->per;
1.1       root      830:        cdp->dat = cdp->nextdat;
1.1.1.5   root      831:        cdp->last_sample = cdp->current_sample;
1.1       root      832:        cdp->current_sample = (sample8_t)(cdp->dat >> 8);
                    833: 
                    834:        cdp->state = 2;
                    835:        {
                    836:            int audav = adkcon & (1 << nr);
                    837:            int audap = adkcon & (16 << nr);
                    838:            int napnav = (!audav && !audap) || audav;
                    839:            if (napnav)
                    840:                cdp->data_written = 2;
                    841:        }
                    842:        break;
                    843: 
                    844:      case 2:
                    845:        /* We come here when a 2->3 transition occurs */
                    846:        if (currprefs.produce_sound == 0)
1.1.1.7   root      847:            cdp->per = PERIOD_MAX;
1.1       root      848: 
1.1.1.5   root      849:        cdp->last_sample = cdp->current_sample;
1.1       root      850:        cdp->current_sample = (sample8_t)(cdp->dat & 0xFF);
1.1.1.2   root      851:        cdp->evtime = cdp->per;
1.1       root      852: 
                    853:        cdp->state = 3;
                    854: 
                    855:        /* Period attachment? */
                    856:        if (adkcon & (0x10 << nr)) {
                    857:            if (cdp->intreq2 && cdp->dmaen)
1.1.1.9   root      858:                INTREQ (0x8000 | (0x80 << nr));
1.1       root      859:            cdp->intreq2 = 0;
                    860: 
                    861:            cdp->dat = cdp->nextdat;
                    862:            if (cdp->dmaen)
                    863:                cdp->data_written = 2;
                    864:            if (nr < 3) {
                    865:                if (cdp->dat == 0)
1.1.1.7   root      866:                    (cdp+1)->per = PERIOD_MAX;
                    867:                else if (cdp->dat < maxhpos * CYCLE_UNIT / 2 && currprefs.produce_sound < 3)
                    868:                    (cdp+1)->per = maxhpos * CYCLE_UNIT / 2;
1.1       root      869:                else
1.1.1.7   root      870:                    (cdp+1)->per = cdp->dat * CYCLE_UNIT;
1.1       root      871:            }
                    872:        }
                    873:        break;
                    874: 
                    875:      case 3:
                    876:        /* We come here when a 3->2 transition occurs */
                    877:        if (currprefs.produce_sound == 0)
1.1.1.7   root      878:            cdp->per = PERIOD_MAX;
1.1       root      879: 
1.1.1.2   root      880:        cdp->evtime = cdp->per;
1.1       root      881: 
1.1.1.17! root      882:        if ((INTREQR () & (0x80 << nr)) && !cdp->dmaen) {
1.1       root      883:            cdp->state = 0;
1.1.1.16  root      884:            cdp->evtime = MAX_EV;
1.1.1.5   root      885:            cdp->last_sample = 0;
1.1       root      886:            cdp->current_sample = 0;
                    887:            break;
                    888:        } else {
                    889:            int audav = adkcon & (1 << nr);
                    890:            int audap = adkcon & (16 << nr);
                    891:            int napnav = (!audav && !audap) || audav;
                    892:            cdp->state = 2;
                    893: 
                    894:            if ((cdp->intreq2 && cdp->dmaen && napnav)
                    895:                || (napnav && !cdp->dmaen))
                    896:                INTREQ(0x8000 | (0x80 << nr));
                    897:            cdp->intreq2 = 0;
                    898: 
                    899:            cdp->dat = cdp->nextdat;
1.1.1.5   root      900:            cdp->last_sample = cdp->current_sample;
1.1       root      901:            cdp->current_sample = (sample8_t)(cdp->dat >> 8);
                    902: 
                    903:            if (cdp->dmaen && napnav)
                    904:                cdp->data_written = 2;
                    905: 
                    906:            /* Volume attachment? */
                    907:            if (audav) {
                    908:                if (nr < 3) {
                    909:                    (cdp+1)->vol = cdp->dat;
                    910: #ifndef MULTIPLICATION_PROFITABLE
                    911:                    (cdp+1)->voltbl = sound_table[cdp->dat];
                    912: #endif
                    913:                }
                    914:            }
                    915:        }
                    916:        break;
                    917: 
                    918:      default:
                    919:        cdp->state = 0;
                    920:        break;
                    921:     }
                    922: }
                    923: 
1.1.1.16  root      924: static void audio_channel_enable_dma (struct audio_channel_data *cdp)
1.1.1.10  root      925: {
1.1.1.16  root      926:     if (cdp->evtime == MAX_EV) {
1.1.1.10  root      927:        cdp->state = 1;
                    928:        cdp->pt = cdp->lc;
                    929:        cdp->wper = cdp->per;
                    930:        cdp->wlen = cdp->len;
                    931:        cdp->data_written = 2;
                    932:        cdp->evtime = eventtab[ev_hsync].evtime - get_cycles ();
                    933:     }
                    934: }
                    935: 
1.1.1.16  root      936: static void audio_channel_disable_dma (struct audio_channel_data *cdp)
1.1.1.10  root      937: {
                    938:     if (cdp->state == 1 || cdp->state == 5) {
                    939:        cdp->state = 0;
1.1.1.16  root      940:        cdp->evtime = MAX_EV;
1.1.1.10  root      941:        cdp->last_sample = 0;
                    942:        cdp->current_sample = 0;
                    943:     }
                    944: }
                    945: 
1.1       root      946: void audio_reset (void)
                    947: {
1.1.1.8   root      948:     int i;
1.1.1.16  root      949:     struct audio_channel_data *cdp;
                    950: 
1.1.1.17! root      951:     memset (sound_filter_state, 0, sizeof sound_filter_state);
1.1.1.8   root      952:     if (savestate_state != STATE_RESTORE) {
1.1.1.16  root      953:        for (i = 0; i < 4; i++) {
                    954:            cdp = &audio_channel[i];
                    955:            memset (cdp, 0, sizeof *audio_channel);
                    956:            cdp->per = PERIOD_MAX;
                    957:            cdp->vol = 0;
                    958:            cdp->evtime = MAX_EV;
                    959:        }
1.1.1.8   root      960:     } else
                    961:        for (i = 0; i < 4; i++)
                    962:            audio_channel[i].dmaen = (dmacon & 0x200) && (dmacon & (1 << i));
                    963: 
                    964: #ifndef MULTIPLICATION_PROFITABLE
1.1.1.13  root      965:     for (i = 0; i < 4; i++)
1.1.1.16  root      966:        audio_channel[i].voltbl = sound_table[audio_channel[i].vol];
1.1.1.8   root      967: #endif
1.1.1.2   root      968: 
1.1.1.16  root      969:     last_cycles = get_cycles ();
1.1.1.7   root      970:     next_sample_evtime = scaled_sample_evtime;
1.1.1.8   root      971:     schedule_audio ();
1.1.1.16  root      972:     events_schedule ();
1.1.1.2   root      973: }
                    974: 
1.1.1.6   root      975: STATIC_INLINE int sound_prefs_changed (void)
1.1.1.2   root      976: {
                    977:     return (changed_prefs.produce_sound != currprefs.produce_sound
1.1.1.13  root      978:            || changed_prefs.sound_stereo != currprefs.sound_stereo
1.1.1.9   root      979:            || changed_prefs.sound_maxbsiz != currprefs.sound_maxbsiz
1.1.1.17! root      980:            || changed_prefs.sound_freq != currprefs.sound_freq);
1.1.1.2   root      981: }
                    982: 
                    983: void check_prefs_changed_audio (void)
                    984: {
1.1.1.17! root      985:     int old_mixed_on = mixed_on;
        !           986:     int old_mixed_size = mixed_stereo_size;
        !           987:     int sep, delay;
        !           988: 
        !           989:     /* Some options we can just apply without reinitializing the sound
        !           990:        backend.  */
        !           991:     currprefs.sound_interpol = changed_prefs.sound_interpol;
        !           992:     currprefs.sound_filter = changed_prefs.sound_filter;
        !           993:     currprefs.sound_filter_type = changed_prefs.sound_filter_type;
        !           994: 
        !           995:     sep = currprefs.sound_stereo_separation = changed_prefs.sound_stereo_separation;
        !           996:     delay = currprefs.sound_mixed_stereo_delay = changed_prefs.sound_mixed_stereo_delay;
        !           997:     mixed_mul1 = MIXED_STEREO_SCALE / 2 - sep;
        !           998:     mixed_mul2 = MIXED_STEREO_SCALE / 2 + sep;
        !           999:     mixed_stereo_size = delay > 0 ? (1 << (delay - 1)) - 1 : 0;
        !          1000:     mixed_on = (sep > 0 && sep < MIXED_STEREO_MAX) || mixed_stereo_size > 0;
        !          1001:     if (mixed_on && old_mixed_size != mixed_stereo_size) {
        !          1002:        saved_ptr = 0;
        !          1003:        memset (right_word_saved, 0, sizeof right_word_saved);
        !          1004:     }
        !          1005: 
1.1.1.6   root     1006:     if (sound_available && sound_prefs_changed ()) {
1.1.1.17! root     1007:        if (currprefs.produce_sound >= 2)
        !          1008:            close_sound ();
1.1.1.2   root     1009: 
1.1.1.6   root     1010:        currprefs.produce_sound = changed_prefs.produce_sound;
1.1.1.13  root     1011:        currprefs.sound_stereo = changed_prefs.sound_stereo;
1.1.1.6   root     1012:        currprefs.sound_freq = changed_prefs.sound_freq;
1.1.1.9   root     1013:        currprefs.sound_maxbsiz = changed_prefs.sound_maxbsiz;
1.1.1.6   root     1014:        if (currprefs.produce_sound >= 2) {
1.1.1.17! root     1015:            if (!init_audio ()) {
1.1.1.6   root     1016:                if (! sound_available) {
1.1.1.11  root     1017:                    write_log ("Sound is not supported.\n");
1.1.1.6   root     1018:                } else {
1.1.1.11  root     1019:                    write_log ("Sorry, can't initialize sound.\n");
1.1.1.6   root     1020:                    currprefs.produce_sound = 0;
                   1021:                    /* So we don't do this every frame */
                   1022:                    changed_prefs.produce_sound = 0;
                   1023:                }
1.1.1.17! root     1024:            }
        !          1025:            next_sample_evtime = scaled_sample_evtime;
        !          1026:            last_cycles = get_cycles () - 1;
        !          1027:            compute_vsynctime ();
        !          1028:        }
        !          1029:        if (currprefs.produce_sound == 0) {
        !          1030:            eventtab[ev_audio].active = 0;
        !          1031:            events_schedule ();
1.1.1.6   root     1032:        }
1.1.1.2   root     1033:     }
1.1.1.17! root     1034: 
        !          1035:     led_filter_forced = -1; // always off
        !          1036:     sound_use_filter = sound_use_filter_sinc = 0;
        !          1037:     if (currprefs.sound_filter != FILTER_SOUND_OFF) {
        !          1038:        if (currprefs.sound_filter == FILTER_SOUND_ON)
        !          1039:            led_filter_forced = 1;
        !          1040:        if (currprefs.sound_filter == FILTER_SOUND_EMUL)
        !          1041:            led_filter_forced = 0;
        !          1042:        if (currprefs.sound_filter_type == FILTER_SOUND_TYPE_A500)
        !          1043:            sound_use_filter = FILTER_MODEL_A500;
        !          1044:        else if (currprefs.sound_filter_type == FILTER_SOUND_TYPE_A1200)
        !          1045:            sound_use_filter = FILTER_MODEL_A1200;
        !          1046:     }
        !          1047:     a500e_filter1_a0 = rc_calculate_a0(currprefs.sound_freq, 6200);
        !          1048:     a500e_filter2_a0 = rc_calculate_a0(currprefs.sound_freq, 20000);
        !          1049:     filter_a0 = rc_calculate_a0(currprefs.sound_freq, 7000);
        !          1050:     led_filter_audio();
        !          1051: 
1.1.1.6   root     1052:     /* Select the right interpolation method.  */
                   1053:     if (sample_handler == sample16_handler
                   1054:        || sample_handler == sample16i_crux_handler
1.1.1.16  root     1055:        || sample_handler == sample16i_rh_handler
1.1.1.17! root     1056:        || sample_handler == sample16i_sinc_handler
        !          1057:        || sample_handler == sample16i_anti_handler)
        !          1058:     {
1.1.1.6   root     1059:        sample_handler = (currprefs.sound_interpol == 0 ? sample16_handler
                   1060:                          : currprefs.sound_interpol == 1 ? sample16i_rh_handler
1.1.1.16  root     1061:                          : currprefs.sound_interpol == 2 ? sample16i_crux_handler
1.1.1.17! root     1062:                          : currprefs.sound_interpol == 3 ? sample16i_sinc_handler
        !          1063:                          : sample16i_anti_handler);
1.1.1.16  root     1064:     } else if (sample_handler == sample16s_handler
1.1.1.17! root     1065:               || sample_handler == sample16si_crux_handler
        !          1066:               || sample_handler == sample16si_rh_handler
        !          1067:               || sample_handler == sample16si_sinc_handler
        !          1068:               || sample_handler == sample16si_anti_handler)
1.1.1.6   root     1069:        sample_handler = (currprefs.sound_interpol == 0 ? sample16s_handler
                   1070:                          : currprefs.sound_interpol == 1 ? sample16si_rh_handler
1.1.1.16  root     1071:                          : currprefs.sound_interpol == 2 ? sample16si_crux_handler
1.1.1.17! root     1072:                          : currprefs.sound_interpol == 3 ? sample16si_sinc_handler
        !          1073:                          : sample16si_anti_handler);
1.1.1.16  root     1074:     sample_prehandler = NULL;
1.1.1.17! root     1075:     if (currprefs.sound_interpol == 3) {
        !          1076:        sound_use_filter_sinc = sound_use_filter;
        !          1077:        sound_use_filter = 0;
1.1.1.16  root     1078:        sample_prehandler = sinc_prehandler;
1.1.1.17! root     1079:     } else if (currprefs.sound_interpol == 4) {
        !          1080:        sample_prehandler = anti_prehandler;
1.1.1.7   root     1081:     }
1.1.1.2   root     1082: }
                   1083: 
                   1084: void update_audio (void)
                   1085: {
                   1086:     unsigned long int n_cycles;
                   1087: 
1.1.1.8   root     1088:     if (currprefs.produce_sound == 0 || savestate_state == STATE_RESTORE)
1.1.1.2   root     1089:        return;
                   1090: 
1.1.1.7   root     1091:     n_cycles = get_cycles () - last_cycles;
1.1.1.2   root     1092:     for (;;) {
                   1093:        unsigned long int best_evtime = n_cycles + 1;
1.1.1.16  root     1094:        if (audio_channel[0].evtime != MAX_EV && best_evtime > audio_channel[0].evtime)
1.1.1.10  root     1095:            best_evtime = audio_channel[0].evtime;
1.1.1.16  root     1096:        if (audio_channel[1].evtime != MAX_EV && best_evtime > audio_channel[1].evtime)
1.1.1.10  root     1097:            best_evtime = audio_channel[1].evtime;
1.1.1.16  root     1098:        if (audio_channel[2].evtime != MAX_EV && best_evtime > audio_channel[2].evtime)
1.1.1.10  root     1099:            best_evtime = audio_channel[2].evtime;
1.1.1.16  root     1100:        if (audio_channel[3].evtime != MAX_EV && best_evtime > audio_channel[3].evtime)
1.1.1.10  root     1101:            best_evtime = audio_channel[3].evtime;
1.1.1.7   root     1102:        if (currprefs.produce_sound > 1 && best_evtime > next_sample_evtime)
1.1.1.2   root     1103:            best_evtime = next_sample_evtime;
                   1104: 
                   1105:        if (best_evtime > n_cycles)
                   1106:            break;
                   1107: 
1.1.1.16  root     1108:        if (audio_channel[0].evtime != MAX_EV)
                   1109:            audio_channel[0].evtime -= best_evtime;
                   1110:        if (audio_channel[1].evtime != MAX_EV)
                   1111:            audio_channel[1].evtime -= best_evtime;
                   1112:        if (audio_channel[2].evtime != MAX_EV)
                   1113:            audio_channel[2].evtime -= best_evtime;
                   1114:        if (audio_channel[3].evtime != MAX_EV)
                   1115:            audio_channel[3].evtime -= best_evtime;
1.1.1.2   root     1116:        n_cycles -= best_evtime;
1.1.1.16  root     1117:        if (currprefs.produce_sound > 1) {
                   1118:            next_sample_evtime -= best_evtime;
                   1119:            if (sample_prehandler)
                   1120:                sample_prehandler (best_evtime / CYCLE_UNIT);
                   1121:            if (next_sample_evtime == 0) {
                   1122:                next_sample_evtime = scaled_sample_evtime;
                   1123:                (*sample_handler) ();
                   1124:            }
1.1.1.2   root     1125:        }
1.1.1.16  root     1126:        if (audio_channel[0].evtime == 0)
1.1.1.2   root     1127:            audio_handler (0);
1.1.1.16  root     1128:        if (audio_channel[1].evtime == 0)
1.1.1.2   root     1129:            audio_handler (1);
1.1.1.16  root     1130:        if (audio_channel[2].evtime == 0)
1.1.1.2   root     1131:            audio_handler (2);
1.1.1.16  root     1132:        if (audio_channel[3].evtime == 0)
1.1.1.2   root     1133:            audio_handler (3);
                   1134:     }
1.1.1.7   root     1135:     last_cycles = get_cycles () - n_cycles;
                   1136: }
                   1137: 
1.1.1.16  root     1138: void update_audio_dmacon (void)
                   1139: {
                   1140:     unsigned int i;
                   1141:     update_audio ();
                   1142: 
                   1143:     for (i = 0; i < 4; i++) {
                   1144:        struct audio_channel_data *cdp = audio_channel + i;
                   1145:        int chan_ena = (dmacon & 0x200) && (dmacon & (1<<i));
                   1146:        if (cdp->dmaen == chan_ena)
                   1147:            continue;
                   1148:        cdp->dmaen = chan_ena;
                   1149:        if (cdp->dmaen)
                   1150:            audio_channel_enable_dma (cdp);
                   1151:        else
                   1152:            audio_channel_disable_dma (cdp);
                   1153:     }
                   1154:     schedule_audio ();
                   1155: }
                   1156: 
1.1.1.7   root     1157: void audio_evhandler (void)
                   1158: {
                   1159:     if (currprefs.produce_sound == 0)
                   1160:        abort ();
                   1161: 
                   1162:     update_audio ();
                   1163:     schedule_audio ();
1.1.1.2   root     1164: }
                   1165: 
1.1.1.15  root     1166: void audio_hsync (int dmaaction)
                   1167: {
                   1168:     int nr;
                   1169: 
                   1170:     update_audio ();
                   1171: 
                   1172:     /* Sound data is fetched at the beginning of each line */
                   1173:     for (nr = 0; nr < 4; nr++) {
                   1174:        struct audio_channel_data *cdp = audio_channel + nr;
                   1175: 
                   1176:        if (cdp->data_written == 2) {
                   1177:            cdp->data_written = 0;
1.1.1.17! root     1178:            cdp->nextdat = chipmem_agnus_wget (cdp->pt);
1.1.1.15  root     1179:            cdp->pt += 2;
                   1180:            if (cdp->state == 2 || cdp->state == 3) {
                   1181:                if (cdp->wlen == 1) {
                   1182:                    cdp->pt = cdp->lc;
                   1183:                    cdp->wlen = cdp->len;
                   1184:                    cdp->intreq2 = 1;
                   1185:                } else
                   1186:                    cdp->wlen = (cdp->wlen - 1) & 0xFFFF;
                   1187:            }
                   1188:        }
                   1189:     }
                   1190: }
                   1191: 
1.1.1.17! root     1192: void AUDxDAT (int nr, uae_u16 v)
1.1.1.2   root     1193: {
                   1194:     struct audio_channel_data *cdp = audio_channel + nr;
                   1195: 
1.1.1.7   root     1196:     if (currprefs.produce_sound == 0)
                   1197:        return;
                   1198: 
1.1.1.2   root     1199:     update_audio ();
                   1200: 
                   1201:     cdp->dat = v;
1.1.1.17! root     1202:     if (cdp->state == 0 && !(INTREQR () & (0x80 << nr))) {
1.1.1.2   root     1203:        cdp->state = 2;
1.1.1.17! root     1204:        INTREQ (0x8000 | (0x80 << nr));
1.1.1.2   root     1205:        /* data_written = 2 ???? */
                   1206:        cdp->evtime = cdp->per;
1.1.1.7   root     1207:        schedule_audio ();
                   1208:        events_schedule ();
1.1.1.2   root     1209:     }
                   1210: }
                   1211: 
1.1.1.17! root     1212: void AUDxLCH (int nr, uae_u16 v)
1.1.1.2   root     1213: {
                   1214:     update_audio ();
                   1215: 
                   1216:     audio_channel[nr].lc = (audio_channel[nr].lc & 0xffff) | ((uae_u32)v << 16);
                   1217: }
                   1218: 
1.1.1.17! root     1219: void AUDxLCL (int nr, uae_u16 v)
1.1.1.2   root     1220: {
                   1221:     update_audio ();
                   1222: 
                   1223:     audio_channel[nr].lc = (audio_channel[nr].lc & ~0xffff) | (v & 0xFFFE);
                   1224: }
                   1225: 
1.1.1.17! root     1226: void AUDxPER (int nr, uae_u16 v)
1.1.1.2   root     1227: {
1.1.1.7   root     1228:     unsigned long per = v * CYCLE_UNIT;
1.1.1.2   root     1229:     update_audio ();
                   1230: 
1.1.1.7   root     1231:     if (per == 0)
                   1232:        per = PERIOD_MAX;
1.1.1.2   root     1233: 
1.1.1.7   root     1234:     if (per < maxhpos * CYCLE_UNIT / 2 && currprefs.produce_sound < 3)
                   1235:        per = maxhpos * CYCLE_UNIT / 2;
1.1.1.16  root     1236:     /* the sinc code registers paula output state changes, but has a finite
                   1237:      * buffer in which to do so. Hence, we forbid very low values; this should
                   1238:      * only limit the accurate rendering of supersonic sounds, which are
                   1239:      * filtered away on the sinc output path anyway. */
                   1240:     if (currprefs.produce_sound == 3 && sample_handler == sample16si_sinc_handler && per < MIN_ALLOWED_PERIOD * CYCLE_UNIT)
                   1241:        per = MIN_ALLOWED_PERIOD * CYCLE_UNIT;
1.1.1.2   root     1242: 
1.1.1.16  root     1243:     if (audio_channel[nr].per == PERIOD_MAX && per != PERIOD_MAX
                   1244:        && audio_channel[nr].evtime != MAX_EV) {
1.1.1.8   root     1245:        audio_channel[nr].evtime = CYCLE_UNIT;
1.1.1.9   root     1246:        if (currprefs.produce_sound > 0) {
                   1247:            schedule_audio ();
                   1248:            events_schedule ();
                   1249:        }
1.1.1.8   root     1250:     }
1.1.1.16  root     1251: 
1.1.1.7   root     1252:     audio_channel[nr].per = per;
1.1.1.2   root     1253: }
                   1254: 
1.1.1.17! root     1255: void AUDxLEN (int nr, uae_u16 v)
1.1.1.2   root     1256: {
                   1257:     update_audio ();
                   1258:     audio_channel[nr].len = v;
                   1259: }
                   1260: 
1.1.1.17! root     1261: void AUDxVOL (int nr, uae_u16 v)
1.1.1.2   root     1262: {
                   1263:     int v2 = v & 64 ? 63 : v & 63;
                   1264: 
                   1265:     update_audio ();
                   1266: 
                   1267:     audio_channel[nr].vol = v2;
                   1268: #ifndef MULTIPLICATION_PROFITABLE
                   1269:     audio_channel[nr].voltbl = sound_table[v2];
                   1270: #endif
1.1       root     1271: }
                   1272: 
1.1.1.15  root     1273: void update_adkmasks (void)
                   1274: {
                   1275:     unsigned long t;
                   1276: 
                   1277:     t = adkcon | (adkcon >> 4);
                   1278:     audio_channel[0].adk_mask = (((t >> 0) & 1) - 1);
                   1279:     audio_channel[1].adk_mask = (((t >> 1) & 1) - 1);
                   1280:     audio_channel[2].adk_mask = (((t >> 2) & 1) - 1);
                   1281:     audio_channel[3].adk_mask = (((t >> 3) & 1) - 1);
                   1282: }
                   1283: 
1.1.1.7   root     1284: int init_audio (void)
1.1       root     1285: {
1.1.1.16  root     1286:     int result = init_sound ();
                   1287:     update_sound (vblank_hz);
                   1288:     return result;
1.1.1.7   root     1289: }
                   1290: 
1.1.1.17! root     1291: void led_filter_audio (void)
        !          1292: {
        !          1293:     led_filter_on = 0;
        !          1294:     if (led_filter_forced > 0 || (gui_data.powerled && led_filter_forced >= 0))
        !          1295:        led_filter_on = 1;
        !          1296:     gui_led (0, gui_data.powerled);
        !          1297: }
        !          1298: 
1.1.1.8   root     1299: /* audio save/restore code FIXME: not working correctly */
                   1300: /* help needed */
                   1301: 
1.1.1.16  root     1302: const uae_u8 *restore_audio (int i, const uae_u8 *src)
1.1.1.8   root     1303: {
                   1304:     struct audio_channel_data *acd;
                   1305:     uae_u16 p;
                   1306: 
                   1307:     acd = audio_channel + i;
                   1308:     acd->state = restore_u8 ();
                   1309:     acd->vol = restore_u8 ();
                   1310:     acd->intreq2 = restore_u8 ();
                   1311:     acd->data_written = restore_u8 ();
                   1312:     acd->len = restore_u16 ();
                   1313:     acd->wlen = restore_u16 ();
                   1314:     p = restore_u16 ();
                   1315:     acd->per = p ? p * CYCLE_UNIT : PERIOD_MAX;
                   1316:     p = restore_u16 ();
                   1317:     acd->wper = p ? p * CYCLE_UNIT : PERIOD_MAX;
                   1318:     acd->lc = restore_u32 ();
                   1319:     acd->pt = restore_u32 ();
                   1320:     acd->evtime = restore_u32 ();
                   1321: 
                   1322:     return src;
                   1323: }
                   1324: 
1.1.1.15  root     1325: uae_u8 *save_audio (int i, int *len)
1.1.1.8   root     1326: {
                   1327:     struct audio_channel_data *acd;
                   1328:     uae_u8 *dst = malloc (100);
                   1329:     uae_u8 *dstbak = dst;
                   1330:     uae_u16 p;
                   1331: 
                   1332:     acd = audio_channel + i;
                   1333:     save_u8 ((uae_u8)acd->state);
                   1334:     save_u8 (acd->vol);
                   1335:     save_u8 (acd->intreq2);
                   1336:     save_u8 (acd->data_written);
                   1337:     save_u16 (acd->len);
                   1338:     save_u16 (acd->wlen);
                   1339:     p = acd->per == PERIOD_MAX ? 0 : acd->per / CYCLE_UNIT;
                   1340:     save_u16 (p);
                   1341:     p = acd->per == PERIOD_MAX ? 0 : acd->wper / CYCLE_UNIT;
                   1342:     save_u16 (p);
                   1343:     save_u32 (acd->lc);
                   1344:     save_u32 (acd->pt);
                   1345:     save_u32 (acd->evtime);
                   1346:     *len = dst - dstbak;
                   1347:     return dstbak;
                   1348: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.