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

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * OS specific functions
                      5:   *
                      6:   * Copyright 1995, 1996, 1997 Bernd Schmidt
                      7:   * Copyright 1996 Marcus Sundberg
                      8:   * Copyright 1996 Manfred Thole
                      9:   */
                     10: 
                     11: #include "sysconfig.h"
                     12: #include "sysdeps.h"
                     13: 
                     14: #include "config.h"
                     15: #include "options.h"
                     16: #include "memory.h"
                     17: #include "custom.h"
                     18: #include "gensound.h"
                     19: #include "sounddep/sound.h"
                     20: #include "events.h"
                     21: #include "audio.h"
                     22: 
                     23: #undef BENCHMARK_AUDIO
                     24: 
                     25: #ifdef BENCHMARK_AUDIO
                     26: 
                     27: #define BEGIN_BENCH frame_time_t audbench = read_processor_time ();
                     28: #define END_BENCH sh_time += read_processor_time () - audbench; sh_count++;
                     29: static frame_time_t sh_time = 0;
                     30: unsigned long sh_count = 0;
                     31: 
                     32: #else
                     33: 
                     34: #define BEGIN_BENCH
                     35: #define END_BENCH
                     36: 
                     37: #endif
                     38: 
                     39: struct audio_channel_data audio_channel[4];
1.1.1.2   root       40: int sound_available = 0;
1.1       root       41: int sound_table[64][256];
1.1.1.2   root       42: void (*sample_handler) (void);
1.1       root       43: unsigned long int sample_evtime;
1.1.1.2   root       44: static unsigned long last_cycles, next_sample_evtime;
1.1       root       45: 
1.1.1.2   root       46: void init_sound_table16 (void)
1.1       root       47: {
                     48:     int i,j;
                     49: 
                     50:     for (i = 0; i < 256; i++)
                     51:        for (j = 0; j < 64; j++)
                     52:            sound_table[j][i] = j * (uae_s8)i * (currprefs.stereo ? 2 : 1);
                     53: }
                     54: 
                     55: void init_sound_table8 (void)
                     56: {
                     57:     int i,j;
                     58: 
                     59:     for (i = 0; i < 256; i++)
                     60:        for (j = 0; j < 64; j++)
                     61:            sound_table[j][i] = (j * (uae_s8)i * (currprefs.stereo ? 2 : 1)) / 256;
                     62: }
                     63: 
                     64: #define MULTIPLICATION_PROFITABLE
                     65: 
                     66: #ifdef MULTIPLICATION_PROFITABLE
                     67: typedef uae_s8 sample8_t;
                     68: #define DO_CHANNEL_1(v, c) do { (v) *= audio_channel[c].vol; } while (0)
                     69: #define SBASEVAL8(logn) ((logn) == 1 ? SOUND8_BASE_VAL << 7 : SOUND8_BASE_VAL << 8)
                     70: #define SBASEVAL16(logn) ((logn) == 1 ? SOUND16_BASE_VAL >> 1 : SOUND16_BASE_VAL)
                     71: #define FINISH_DATA(b,logn) do { if (14 - (b) + (logn) > 0) data >>= 14 - (b) + (logn); else data <<= (b) - 14 - (logn); } while (0);
                     72: #else
                     73: typedef uae_u8 sample8_t;
                     74: #define DO_CHANNEL_1(v, c) do { (v) = audio_channel[c].voltbl[(v)]; } while (0)
                     75: #define SBASEVAL8(logn) SOUND8_BASE_VAL
                     76: #define SBASEVAL16(logn) SOUND16_BASE_VAL
                     77: #define FINISH_DATA(b,logn)
                     78: #endif
                     79: 
                     80: #define DO_CHANNEL(v, c) do { (v) &= audio_channel[c].adk_mask; data += v; } while (0);
                     81: 
1.1.1.2   root       82: void sample16_handler (void)
1.1       root       83: {
                     84:     BEGIN_BENCH
                     85: 
                     86:     uae_u32 data0 = audio_channel[0].current_sample;
                     87:     uae_u32 data1 = audio_channel[1].current_sample;
                     88:     uae_u32 data2 = audio_channel[2].current_sample;
                     89:     uae_u32 data3 = audio_channel[3].current_sample;
                     90:     DO_CHANNEL_1 (data0, 0);
                     91:     DO_CHANNEL_1 (data1, 1);
                     92:     DO_CHANNEL_1 (data2, 2);
                     93:     DO_CHANNEL_1 (data3, 3);
                     94:     data0 &= audio_channel[0].adk_mask;
                     95:     data1 &= audio_channel[1].adk_mask;
                     96:     data2 &= audio_channel[2].adk_mask;
                     97:     data3 &= audio_channel[3].adk_mask;
                     98:     data0 += data1;
                     99:     data0 += data2;
                    100:     data0 += data3;
                    101:     {
                    102:        uae_u32 data = SBASEVAL16(2) + data0;
                    103:        FINISH_DATA(16, 2);
                    104:        PUT_SOUND_WORD (data);
                    105:     }
                    106:     END_BENCH
                    107: 
                    108:     check_sound_buffers ();
                    109: }
                    110: 
1.1.1.6 ! root      111: void sample16i_rh_handler (void)
1.1.1.5   root      112: {
                    113:     unsigned long delta, ratio;
                    114: 
                    115:     BEGIN_BENCH
                    116: 
                    117:     uae_u32 data0 = audio_channel[0].current_sample;
                    118:     uae_u32 data1 = audio_channel[1].current_sample;
                    119:     uae_u32 data2 = audio_channel[2].current_sample;
                    120:     uae_u32 data3 = audio_channel[3].current_sample;
                    121:     uae_u32 data0p = audio_channel[0].last_sample;
                    122:     uae_u32 data1p = audio_channel[1].last_sample;
                    123:     uae_u32 data2p = audio_channel[2].last_sample;
                    124:     uae_u32 data3p = audio_channel[3].last_sample;
                    125:     DO_CHANNEL_1 (data0, 0);
                    126:     DO_CHANNEL_1 (data1, 1);
                    127:     DO_CHANNEL_1 (data2, 2);
                    128:     DO_CHANNEL_1 (data3, 3);
                    129:     DO_CHANNEL_1 (data0p, 0);
                    130:     DO_CHANNEL_1 (data1p, 1);
                    131:     DO_CHANNEL_1 (data2p, 2);
                    132:     DO_CHANNEL_1 (data3p, 3);
                    133: 
                    134:     data0 &= audio_channel[0].adk_mask;
                    135:     data0p &= audio_channel[0].adk_mask;
                    136:     data1 &= audio_channel[1].adk_mask;
                    137:     data1p &= audio_channel[1].adk_mask;
                    138:     data2 &= audio_channel[2].adk_mask;
                    139:     data2p &= audio_channel[2].adk_mask;
                    140:     data3 &= audio_channel[3].adk_mask;
                    141:     data3p &= audio_channel[3].adk_mask;
                    142: 
                    143:     /* linear interpolation and summing up... */
                    144:     delta = audio_channel[0].per;
                    145:     ratio = ((audio_channel[0].evtime % delta) << 8) / delta;
                    146:     data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
                    147:     delta = audio_channel[1].per;
                    148:     ratio = ((audio_channel[1].evtime % delta) << 8) / delta;
                    149:     data0 += (data1 * (256 - ratio) + data1p * ratio) >> 8;
                    150:     delta = audio_channel[2].per;
                    151:     ratio = ((audio_channel[2].evtime % delta) << 8) / delta;
                    152:     data0 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
                    153:     delta = audio_channel[3].per;
                    154:     ratio = ((audio_channel[3].evtime % delta) << 8) / delta;
                    155:     data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
                    156: 
                    157:     {
                    158:        uae_u32 data = SBASEVAL16(2) + data0;
                    159:        FINISH_DATA(16, 2);
                    160:        PUT_SOUND_WORD (data);
                    161:     }
                    162:     END_BENCH
                    163: 
                    164:     check_sound_buffers ();
                    165: }
                    166: 
1.1.1.6 ! root      167: void sample16i_crux_handler (void)
        !           168: {
        !           169:     unsigned long delta, ratio;
        !           170: 
        !           171:     BEGIN_BENCH
        !           172: 
        !           173:     uae_u32 data0 = audio_channel[0].current_sample;
        !           174:     uae_u32 data1 = audio_channel[1].current_sample;
        !           175:     uae_u32 data2 = audio_channel[2].current_sample;
        !           176:     uae_u32 data3 = audio_channel[3].current_sample;
        !           177:     uae_u32 data0p = audio_channel[0].last_sample;
        !           178:     uae_u32 data1p = audio_channel[1].last_sample;
        !           179:     uae_u32 data2p = audio_channel[2].last_sample;
        !           180:     uae_u32 data3p = audio_channel[3].last_sample;
        !           181:     DO_CHANNEL_1 (data0, 0);
        !           182:     DO_CHANNEL_1 (data1, 1);
        !           183:     DO_CHANNEL_1 (data2, 2);
        !           184:     DO_CHANNEL_1 (data3, 3);
        !           185:     DO_CHANNEL_1 (data0p, 0);
        !           186:     DO_CHANNEL_1 (data1p, 1);
        !           187:     DO_CHANNEL_1 (data2p, 2);
        !           188:     DO_CHANNEL_1 (data3p, 3);
        !           189: 
        !           190:     data0 &= audio_channel[0].adk_mask;
        !           191:     data0p &= audio_channel[0].adk_mask;
        !           192:     data1 &= audio_channel[1].adk_mask;
        !           193:     data1p &= audio_channel[1].adk_mask;
        !           194:     data2 &= audio_channel[2].adk_mask;
        !           195:     data2p &= audio_channel[2].adk_mask;
        !           196:     data3 &= audio_channel[3].adk_mask;
        !           197:     data3p &= audio_channel[3].adk_mask;
        !           198: 
        !           199:     {    
        !           200:        struct audio_channel_data *cdp;
        !           201:        int ratio, ratio1;
        !           202: #define INTERVAL (sample_evtime * 3)
        !           203:        cdp = audio_channel + 0;
        !           204:        ratio1 = cdp->per - cdp->evtime;
        !           205:        ratio = (ratio1 << 12) / INTERVAL;
        !           206:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
        !           207:            ratio = 4096;
        !           208:        data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12;
        !           209: 
        !           210:        cdp = audio_channel + 1;
        !           211:        ratio1 = cdp->per - cdp->evtime;
        !           212:        ratio = (ratio1 << 12) / INTERVAL;
        !           213:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
        !           214:            ratio = 4096;
        !           215:        data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12;
        !           216: 
        !           217:        cdp = audio_channel + 2;
        !           218:        ratio1 = cdp->per - cdp->evtime;
        !           219:        ratio = (ratio1 << 12) / INTERVAL;
        !           220:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
        !           221:            ratio = 4096;
        !           222:        data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12;
        !           223: 
        !           224:        cdp = audio_channel + 3;
        !           225:        ratio1 = cdp->per - cdp->evtime;
        !           226:        ratio = (ratio1 << 12) / INTERVAL;
        !           227:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
        !           228:            ratio = 4096;
        !           229:        data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12;
        !           230:     }
        !           231:     data1 += data2;
        !           232:     data0 += data3;
        !           233:     data0 += data1;
        !           234:     {
        !           235:        uae_u32 data = SBASEVAL16(2) + data0;
        !           236:        FINISH_DATA(16, 2);
        !           237:        PUT_SOUND_WORD (data);
        !           238:     }
        !           239:     END_BENCH
        !           240: 
        !           241:     check_sound_buffers ();
        !           242: }
        !           243: 
1.1.1.2   root      244: void sample8_handler (void)
1.1       root      245: {
                    246:     BEGIN_BENCH
                    247:        
                    248:     uae_u32 data0 = audio_channel[0].current_sample;
                    249:     uae_u32 data1 = audio_channel[1].current_sample;
                    250:     uae_u32 data2 = audio_channel[2].current_sample;
                    251:     uae_u32 data3 = audio_channel[3].current_sample;
                    252:     DO_CHANNEL_1 (data0, 0);
                    253:     DO_CHANNEL_1 (data1, 1);
                    254:     DO_CHANNEL_1 (data2, 2);
                    255:     DO_CHANNEL_1 (data3, 3);
                    256:     data0 &= audio_channel[0].adk_mask;
                    257:     data1 &= audio_channel[1].adk_mask;
                    258:     data2 &= audio_channel[2].adk_mask;
                    259:     data3 &= audio_channel[3].adk_mask;
                    260:     data0 += data1;
                    261:     data0 += data2;
                    262:     data0 += data3;
                    263:     {
                    264:        uae_u32 data = SBASEVAL8(2) + data0;
                    265:        FINISH_DATA(8, 2);
                    266:        PUT_SOUND_BYTE (data);
                    267:     }
                    268:     END_BENCH
                    269: 
                    270:     check_sound_buffers ();
                    271: }
                    272: 
                    273: #ifdef HAVE_STEREO_SUPPORT
1.1.1.2   root      274: void sample16s_handler (void)
1.1       root      275: {
                    276:     BEGIN_BENCH
                    277: 
                    278:     uae_u32 data0 = audio_channel[0].current_sample;
                    279:     uae_u32 data1 = audio_channel[1].current_sample;
                    280:     uae_u32 data2 = audio_channel[2].current_sample;
                    281:     uae_u32 data3 = audio_channel[3].current_sample;
                    282:     DO_CHANNEL_1 (data0, 0);
                    283:     DO_CHANNEL_1 (data1, 1);
                    284:     DO_CHANNEL_1 (data2, 2);
                    285:     DO_CHANNEL_1 (data3, 3);
                    286: 
                    287:     data0 &= audio_channel[0].adk_mask;
                    288:     data1 &= audio_channel[1].adk_mask;
                    289:     data2 &= audio_channel[2].adk_mask;
                    290:     data3 &= audio_channel[3].adk_mask;
                    291:     
                    292:     data0 += data3;
                    293:     {
                    294:        uae_u32 data = SBASEVAL16(1) + data0;
                    295:        FINISH_DATA (16, 1);
                    296:        PUT_SOUND_WORD_RIGHT (data);
                    297:     }
                    298: 
                    299:     data1 += data2;
                    300:     {
                    301:        uae_u32 data = SBASEVAL16(1) + data1;
                    302:        FINISH_DATA (16, 1);
                    303:        PUT_SOUND_WORD_LEFT (data);
                    304:     }
                    305:     
                    306:     END_BENCH
                    307:     
                    308:     check_sound_buffers ();
                    309: }
                    310: 
1.1.1.6 ! root      311: void sample16si_crux_handler (void)
1.1.1.5   root      312: {
                    313:     unsigned long delta, ratio;
                    314: 
                    315:     BEGIN_BENCH
                    316: 
                    317:     uae_u32 data0 = audio_channel[0].current_sample;
                    318:     uae_u32 data1 = audio_channel[1].current_sample;
                    319:     uae_u32 data2 = audio_channel[2].current_sample;
                    320:     uae_u32 data3 = audio_channel[3].current_sample;
                    321:     uae_u32 data0p = audio_channel[0].last_sample;
                    322:     uae_u32 data1p = audio_channel[1].last_sample;
                    323:     uae_u32 data2p = audio_channel[2].last_sample;
                    324:     uae_u32 data3p = audio_channel[3].last_sample;
                    325: 
                    326:     DO_CHANNEL_1 (data0, 0);
                    327:     DO_CHANNEL_1 (data1, 1);
                    328:     DO_CHANNEL_1 (data2, 2);
                    329:     DO_CHANNEL_1 (data3, 3);
                    330:     DO_CHANNEL_1 (data0p, 0);
                    331:     DO_CHANNEL_1 (data1p, 1);
                    332:     DO_CHANNEL_1 (data2p, 2);
                    333:     DO_CHANNEL_1 (data3p, 3);
                    334: 
                    335:     data0 &= audio_channel[0].adk_mask;
                    336:     data0p &= audio_channel[0].adk_mask;
                    337:     data1 &= audio_channel[1].adk_mask;
                    338:     data1p &= audio_channel[1].adk_mask;
                    339:     data2 &= audio_channel[2].adk_mask;
                    340:     data2p &= audio_channel[2].adk_mask;
                    341:     data3 &= audio_channel[3].adk_mask;
                    342:     data3p &= audio_channel[3].adk_mask;
                    343: 
                    344:     {    
                    345:        struct audio_channel_data *cdp;
                    346:        int ratio, ratio1;
1.1.1.6 ! root      347: #define INTERVAL (sample_evtime * 3)
1.1.1.5   root      348:        cdp = audio_channel + 0;
                    349:        ratio1 = cdp->per - cdp->evtime;
                    350:        ratio = (ratio1 << 12) / INTERVAL;
                    351:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
                    352:            ratio = 4096;
                    353:        data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12;
                    354: 
                    355:        cdp = audio_channel + 1;
                    356:        ratio1 = cdp->per - cdp->evtime;
                    357:        ratio = (ratio1 << 12) / INTERVAL;
                    358:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
                    359:            ratio = 4096;
                    360:        data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12;
                    361: 
                    362:        cdp = audio_channel + 2;
                    363:        ratio1 = cdp->per - cdp->evtime;
                    364:        ratio = (ratio1 << 12) / INTERVAL;
                    365:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
                    366:            ratio = 4096;
                    367:        data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12;
                    368: 
                    369:        cdp = audio_channel + 3;
                    370:        ratio1 = cdp->per - cdp->evtime;
                    371:        ratio = (ratio1 << 12) / INTERVAL;
                    372:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
                    373:            ratio = 4096;
                    374:        data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12;
                    375:     }
                    376:     data1 += data2;
                    377:     data0 += data3;
1.1.1.6 ! root      378:     {
        !           379:        uae_u32 data = SBASEVAL16 (1) + data0;
        !           380:        FINISH_DATA (16, 1);
        !           381:        PUT_SOUND_WORD_RIGHT (data);
        !           382:     }
        !           383: 
        !           384:     {
        !           385:        uae_u32 data = SBASEVAL16 (1) + data1;
        !           386:        FINISH_DATA (16, 1);
        !           387:        PUT_SOUND_WORD_LEFT (data);
        !           388:     }
        !           389:     
        !           390:     END_BENCH
        !           391:     
        !           392:     check_sound_buffers ();
        !           393: }
        !           394: 
        !           395: void sample16si_rh_handler (void)
        !           396: {
        !           397:     unsigned long delta, ratio;
        !           398: 
        !           399:     BEGIN_BENCH
        !           400: 
        !           401:     uae_u32 data0 = audio_channel[0].current_sample;
        !           402:     uae_u32 data1 = audio_channel[1].current_sample;
        !           403:     uae_u32 data2 = audio_channel[2].current_sample;
        !           404:     uae_u32 data3 = audio_channel[3].current_sample;
        !           405:     uae_u32 data0p = audio_channel[0].last_sample;
        !           406:     uae_u32 data1p = audio_channel[1].last_sample;
        !           407:     uae_u32 data2p = audio_channel[2].last_sample;
        !           408:     uae_u32 data3p = audio_channel[3].last_sample;
        !           409: 
        !           410:     DO_CHANNEL_1 (data0, 0);
        !           411:     DO_CHANNEL_1 (data1, 1);
        !           412:     DO_CHANNEL_1 (data2, 2);
        !           413:     DO_CHANNEL_1 (data3, 3);
        !           414:     DO_CHANNEL_1 (data0p, 0);
        !           415:     DO_CHANNEL_1 (data1p, 1);
        !           416:     DO_CHANNEL_1 (data2p, 2);
        !           417:     DO_CHANNEL_1 (data3p, 3);
        !           418: 
        !           419:     data0 &= audio_channel[0].adk_mask;
        !           420:     data0p &= audio_channel[0].adk_mask;
        !           421:     data1 &= audio_channel[1].adk_mask;
        !           422:     data1p &= audio_channel[1].adk_mask;
        !           423:     data2 &= audio_channel[2].adk_mask;
        !           424:     data2p &= audio_channel[2].adk_mask;
        !           425:     data3 &= audio_channel[3].adk_mask;
        !           426:     data3p &= audio_channel[3].adk_mask;
        !           427: 
        !           428:     /* linear interpolation and summing up... */
        !           429:     delta = audio_channel[0].per;
        !           430:     ratio = ((audio_channel[0].evtime % delta) << 8) / delta;
        !           431:     data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
        !           432:     delta = audio_channel[1].per;
        !           433:     ratio = ((audio_channel[1].evtime % delta) << 8) / delta;
        !           434:     data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8;
        !           435:     delta = audio_channel[2].per;
        !           436:     ratio = ((audio_channel[2].evtime % delta) << 8) / delta;
        !           437:     data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
        !           438:     delta = audio_channel[3].per;
        !           439:     ratio = ((audio_channel[3].evtime % delta) << 8) / delta;
        !           440:     data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
1.1.1.5   root      441:     {
                    442:        uae_u32 data = SBASEVAL16 (1) + data0;
                    443:        FINISH_DATA (16, 1);
                    444:        PUT_SOUND_WORD_RIGHT (data);
                    445:     }
                    446: 
                    447:     {
                    448:        uae_u32 data = SBASEVAL16 (1) + data1;
                    449:        FINISH_DATA (16, 1);
                    450:        PUT_SOUND_WORD_LEFT (data);
                    451:     }
                    452:     
                    453:     END_BENCH
                    454:     
                    455:     check_sound_buffers ();
                    456: }
                    457: 
1.1.1.2   root      458: void sample8s_handler (void)
1.1       root      459: {
                    460:     BEGIN_BENCH
                    461: 
                    462:     uae_u32 data0 = audio_channel[0].current_sample;
                    463:     uae_u32 data1 = audio_channel[1].current_sample;
                    464:     uae_u32 data2 = audio_channel[2].current_sample;
                    465:     uae_u32 data3 = audio_channel[3].current_sample;
                    466:     DO_CHANNEL_1 (data0, 0);
                    467:     DO_CHANNEL_1 (data1, 1);
                    468:     DO_CHANNEL_1 (data2, 2);
                    469:     DO_CHANNEL_1 (data3, 3);
                    470: 
                    471:     data0 &= audio_channel[0].adk_mask;
                    472:     data1 &= audio_channel[1].adk_mask;
                    473:     data2 &= audio_channel[2].adk_mask;
                    474:     data3 &= audio_channel[3].adk_mask;
                    475: 
                    476:     data0 += data3;
                    477:     {
                    478:        uae_u32 data = SBASEVAL8(1) + data0;
                    479:        FINISH_DATA (8, 1);
                    480:        PUT_SOUND_BYTE_RIGHT (data);
                    481:     }
                    482:     data1 += data2;
                    483:     {
                    484:        uae_u32 data = SBASEVAL8(1) + data1;
                    485:        FINISH_DATA (8, 1);
                    486:        PUT_SOUND_BYTE_LEFT (data);
                    487:     }
                    488: 
                    489:     END_BENCH
                    490:     
                    491:     check_sound_buffers ();
                    492: }
                    493: #else
1.1.1.2   root      494: void sample8s_handler (void)
1.1       root      495: {
                    496:     sample8_handler();
                    497: }
1.1.1.2   root      498: void sample16s_handler (void)
1.1       root      499: {
                    500:     sample16_handler();
                    501: }
1.1.1.6 ! root      502: void sample16si_crux_handler (void)
        !           503: {
        !           504:     sample16i_crux_handler();
        !           505: }
        !           506: void sample16si_rh_handler (void)
        !           507: {
        !           508:     sample16i_rh_handler();
        !           509: }
1.1       root      510: #endif
                    511: 
1.1.1.2   root      512: static uae_u8 int2ulaw (int ch)
1.1       root      513: {
                    514:     int mask;
                    515: 
                    516:     if (ch < 0) {
                    517:       ch = -ch;
                    518:       mask = 0x7f;
                    519:     }
                    520:     else {
                    521:       mask = 0xff;
                    522:     }
                    523: 
                    524:     if (ch < 32) {
                    525:        ch = 0xF0 | ( 15 - (ch/2) );
                    526:     } else if (ch < 96) {
                    527:        ch = 0xE0 | ( 15 - (ch-32)/4 );
                    528:     } else if (ch < 224) {
                    529:        ch = 0xD0 | ( 15 - (ch-96)/8 );
                    530:     } else if (ch < 480) {
                    531:        ch = 0xC0 | ( 15 - (ch-224)/16 );
                    532:     } else if (ch < 992 ) {
                    533:        ch = 0xB0 | ( 15 - (ch-480)/32 );
                    534:     } else if (ch < 2016) {
                    535:        ch = 0xA0 | ( 15 - (ch-992)/64 );
                    536:     } else if (ch < 4064) {
                    537:        ch = 0x90 | ( 15 - (ch-2016)/128 );
                    538:     } else if (ch < 8160) {
                    539:        ch = 0x80 | ( 15 - (ch-4064)/256 );
                    540:     } else {
                    541:        ch = 0x80;
                    542:     }
                    543:     return (uae_u8)(mask & ch);
                    544: }
                    545: 
                    546: void sample_ulaw_handler (void)
                    547: {
                    548:     int nr;
                    549:     uae_u32 data = 0;
                    550: 
                    551:     for (nr = 0; nr < 4; nr++) {
                    552:        if (!(adkcon & (0x11 << nr))) {
                    553:            uae_u32 d = audio_channel[nr].current_sample;
                    554:            DO_CHANNEL_1 (d, nr);
                    555:            data += d;
                    556:        }
                    557:     }
                    558:     PUT_SOUND_BYTE (int2ulaw (data));
                    559:     check_sound_buffers ();
                    560: }
                    561: 
                    562: static void audio_handler (int nr)
                    563: {
                    564:     struct audio_channel_data *cdp = audio_channel + nr;
                    565: 
                    566:     switch (cdp->state) {
                    567:      case 0:
                    568:        fprintf(stderr, "Bug in sound code\n");
                    569:        break;
                    570: 
                    571:      case 1:
                    572:        /* We come here at the first hsync after DMA was turned on. */
1.1.1.2   root      573:        cdp->evtime = maxhpos;
1.1       root      574: 
                    575:        cdp->state = 5;
                    576:        INTREQ(0x8000 | (0x80 << nr));
                    577:        if (cdp->wlen != 1)
                    578:            cdp->wlen--;
                    579:        cdp->nextdat = chipmem_bank.wget(cdp->pt);
                    580: 
                    581:        cdp->pt += 2;
                    582:        break;
                    583: 
                    584:      case 5:
                    585:        /* We come here at the second hsync after DMA was turned on. */
                    586:        if (currprefs.produce_sound == 0)
                    587:            cdp->per = 65535;
                    588: 
1.1.1.2   root      589:        cdp->evtime = cdp->per;
1.1       root      590:        cdp->dat = cdp->nextdat;
1.1.1.5   root      591:        cdp->last_sample = cdp->current_sample;
1.1       root      592:        cdp->current_sample = (sample8_t)(cdp->dat >> 8);
                    593: 
                    594:        cdp->state = 2;
                    595:        {
                    596:            int audav = adkcon & (1 << nr);
                    597:            int audap = adkcon & (16 << nr);
                    598:            int napnav = (!audav && !audap) || audav;
                    599:            if (napnav)
                    600:                cdp->data_written = 2;
                    601:        }
                    602:        break;
                    603: 
                    604:      case 2:
                    605:        /* We come here when a 2->3 transition occurs */
                    606:        if (currprefs.produce_sound == 0)
                    607:            cdp->per = 65535;
                    608: 
1.1.1.5   root      609:        cdp->last_sample = cdp->current_sample;
1.1       root      610:        cdp->current_sample = (sample8_t)(cdp->dat & 0xFF);
1.1.1.2   root      611:        cdp->evtime = cdp->per;
1.1       root      612: 
                    613:        cdp->state = 3;
                    614: 
                    615:        /* Period attachment? */
                    616:        if (adkcon & (0x10 << nr)) {
                    617:            if (cdp->intreq2 && cdp->dmaen)
                    618:                INTREQ(0x8000 | (0x80 << nr));
                    619:            cdp->intreq2 = 0;
                    620: 
                    621:            cdp->dat = cdp->nextdat;
                    622:            if (cdp->dmaen)
                    623:                cdp->data_written = 2;
                    624:            if (nr < 3) {
                    625:                if (cdp->dat == 0)
                    626:                    (cdp+1)->per = 65535;
                    627: 
                    628:                else if (cdp->dat < maxhpos/2 && currprefs.produce_sound < 3)
                    629:                    (cdp+1)->per = maxhpos/2;
                    630:                else
                    631:                    (cdp+1)->per = cdp->dat;
                    632:            }
                    633:        }
                    634:        break;
                    635: 
                    636:      case 3:
                    637:        /* We come here when a 3->2 transition occurs */
                    638:        if (currprefs.produce_sound == 0)
                    639:            cdp->per = 65535;
                    640: 
1.1.1.2   root      641:        cdp->evtime = cdp->per;
1.1       root      642: 
                    643:        if ((INTREQR() & (0x80 << nr)) && !cdp->dmaen) {
                    644:            cdp->state = 0;
1.1.1.5   root      645:            cdp->last_sample = 0;
1.1       root      646:            cdp->current_sample = 0;
                    647:            break;
                    648:        } else {
                    649:            int audav = adkcon & (1 << nr);
                    650:            int audap = adkcon & (16 << nr);
                    651:            int napnav = (!audav && !audap) || audav;
                    652:            cdp->state = 2;
                    653: 
                    654:            if ((cdp->intreq2 && cdp->dmaen && napnav)
                    655:                || (napnav && !cdp->dmaen))
                    656:                INTREQ(0x8000 | (0x80 << nr));
                    657:            cdp->intreq2 = 0;
                    658: 
                    659:            cdp->dat = cdp->nextdat;
1.1.1.5   root      660:            cdp->last_sample = cdp->current_sample;
1.1       root      661:            cdp->current_sample = (sample8_t)(cdp->dat >> 8);
                    662: 
                    663:            if (cdp->dmaen && napnav)
                    664:                cdp->data_written = 2;
                    665: 
                    666:            /* Volume attachment? */
                    667:            if (audav) {
                    668:                if (nr < 3) {
                    669:                    (cdp+1)->vol = cdp->dat;
                    670: #ifndef MULTIPLICATION_PROFITABLE
                    671:                    (cdp+1)->voltbl = sound_table[cdp->dat];
                    672: #endif
                    673:                }
                    674:            }
                    675:        }
                    676:        break;
                    677: 
                    678:      default:
                    679:        cdp->state = 0;
                    680:        break;
                    681:     }
                    682: }
                    683: 
                    684: void aud0_handler (void)
                    685: {
                    686:     audio_handler (0);
                    687: }
                    688: void aud1_handler (void)
                    689: {
                    690:     audio_handler (1);
                    691: }
                    692: void aud2_handler (void)
                    693: {
                    694:     audio_handler (2);
                    695: }
                    696: void aud3_handler (void)
                    697: {
                    698:     audio_handler (3);
                    699: }
                    700: 
                    701: void audio_reset (void)
                    702: {
                    703:     memset (audio_channel, 0, sizeof audio_channel);
                    704:     audio_channel[0].per = 65535;
                    705:     audio_channel[1].per = 65535;
                    706:     audio_channel[2].per = 65535;
                    707:     audio_channel[3].per = 65535;
                    708:     audio_channel[0].voltbl = sound_table[0];
                    709:     audio_channel[1].voltbl = sound_table[0];
                    710:     audio_channel[2].voltbl = sound_table[0];
                    711:     audio_channel[3].voltbl = sound_table[0];
1.1.1.2   root      712: 
                    713:     last_cycles = 0;
                    714:     next_sample_evtime = sample_evtime;
                    715: }
                    716: 
1.1.1.6 ! root      717: STATIC_INLINE int sound_prefs_changed (void)
1.1.1.2   root      718: {
                    719:     return (changed_prefs.produce_sound != currprefs.produce_sound
                    720:            || changed_prefs.stereo != currprefs.stereo
1.1.1.4   root      721:            || changed_prefs.sound_freq != currprefs.sound_freq
1.1.1.2   root      722:            || changed_prefs.sound_bits != currprefs.sound_bits);
                    723: }
                    724: 
                    725: void check_prefs_changed_audio (void)
                    726: {
1.1.1.6 ! root      727:     if (sound_available && sound_prefs_changed ()) {
        !           728:        close_sound ();
1.1.1.2   root      729: 
1.1.1.6 ! root      730:        currprefs.produce_sound = changed_prefs.produce_sound;
        !           731:        currprefs.stereo = changed_prefs.stereo;
        !           732:        currprefs.sound_bits = changed_prefs.sound_bits;
        !           733:        currprefs.sound_freq = changed_prefs.sound_freq;
        !           734: 
        !           735:        if (currprefs.produce_sound >= 2) {
        !           736:            if (init_sound ()) {
        !           737:                last_cycles = cycles - 1;
        !           738:                next_sample_evtime = sample_evtime;
        !           739:            } else
        !           740:                if (! sound_available) {
        !           741:                    fprintf (stderr, "Sound is not supported.\n");
        !           742:                } else {
        !           743:                    fprintf (stderr, "Sorry, can't initialize sound.\n");
        !           744:                    currprefs.produce_sound = 0;
        !           745:                    /* So we don't do this every frame */
        !           746:                    changed_prefs.produce_sound = 0;
        !           747:                }
        !           748:        }
1.1.1.2   root      749:     }
1.1.1.6 ! root      750:     /* Select the right interpolation method.  */
        !           751:     if (sample_handler == sample16_handler
        !           752:        || sample_handler == sample16i_crux_handler
        !           753:        || sample_handler == sample16i_rh_handler)
        !           754:        sample_handler = (currprefs.sound_interpol == 0 ? sample16_handler
        !           755:                          : currprefs.sound_interpol == 1 ? sample16i_rh_handler
        !           756:                          : sample16i_crux_handler);
        !           757:     else if (sample_handler == sample16s_handler
        !           758:             || sample_handler == sample16si_crux_handler
        !           759:             || sample_handler == sample16si_rh_handler)
        !           760:        sample_handler = (currprefs.sound_interpol == 0 ? sample16s_handler
        !           761:                          : currprefs.sound_interpol == 1 ? sample16si_rh_handler
        !           762:                          : sample16si_crux_handler);
1.1.1.2   root      763: }
                    764: 
                    765: void update_audio (void)
                    766: {
                    767:     unsigned long int n_cycles;
                    768: 
1.1.1.4   root      769:     if (currprefs.produce_sound < 2)
1.1.1.2   root      770:        return;
                    771: 
                    772:     n_cycles = cycles - last_cycles;
                    773:     for (;;) {
                    774:        int best = -1;
                    775:        unsigned long int best_evtime = n_cycles + 1;
                    776:        if (audio_channel[0].state != 0 && best_evtime > audio_channel[0].evtime)
                    777:            best = 0, best_evtime = audio_channel[0].evtime;
                    778:        if (audio_channel[1].state != 0 && best_evtime > audio_channel[1].evtime)
                    779:            best = 1, best_evtime = audio_channel[1].evtime;
                    780:        if (audio_channel[2].state != 0 && best_evtime > audio_channel[2].evtime)
                    781:            best = 2, best_evtime = audio_channel[2].evtime;
                    782:        if (audio_channel[3].state != 0 && best_evtime > audio_channel[3].evtime)
                    783:            best = 3, best_evtime = audio_channel[3].evtime;
                    784:        if (best_evtime > next_sample_evtime)
                    785:            best_evtime = next_sample_evtime;
                    786: 
                    787:        if (best_evtime > n_cycles)
                    788:            break;
                    789: 
                    790:        next_sample_evtime -= best_evtime;
                    791:        audio_channel[0].evtime -= best_evtime;
                    792:        audio_channel[1].evtime -= best_evtime;
                    793:        audio_channel[2].evtime -= best_evtime;
                    794:        audio_channel[3].evtime -= best_evtime;
                    795:        n_cycles -= best_evtime;
1.1.1.3   root      796:        if (next_sample_evtime == 0 && currprefs.produce_sound > 1) {
1.1.1.2   root      797:            next_sample_evtime = sample_evtime;
                    798:            (*sample_handler) ();
                    799:        }
                    800:        if (audio_channel[0].evtime == 0 && audio_channel[0].state != 0)
                    801:            audio_handler (0);
                    802:        if (audio_channel[1].evtime == 0 && audio_channel[1].state != 0)
                    803:            audio_handler (1);
                    804:        if (audio_channel[2].evtime == 0 && audio_channel[2].state != 0)
                    805:            audio_handler (2);
                    806:        if (audio_channel[3].evtime == 0 && audio_channel[3].state != 0)
                    807:            audio_handler (3);
                    808:     }
                    809:     last_cycles = cycles - n_cycles;
                    810: }
                    811: 
                    812: void AUDxDAT (int nr, uae_u16 v)
                    813: {
                    814:     struct audio_channel_data *cdp = audio_channel + nr;
                    815: 
                    816:     update_audio ();
                    817: 
                    818:     cdp->dat = v;
                    819:     if (cdp->state == 0 && !(INTREQR() & (0x80 << nr))) {
                    820:        cdp->state = 2;
                    821:        INTREQ(0x8000 | (0x80 << nr));
                    822:        /* data_written = 2 ???? */
                    823:        cdp->evtime = cdp->per;
                    824:     }
                    825: }
                    826: 
                    827: void AUDxLCH (int nr, uae_u16 v)
                    828: {
                    829:     update_audio ();
                    830: 
                    831:     audio_channel[nr].lc = (audio_channel[nr].lc & 0xffff) | ((uae_u32)v << 16);
                    832: }
                    833: 
                    834: void AUDxLCL (int nr, uae_u16 v)
                    835: {
                    836:     update_audio ();
                    837: 
                    838:     audio_channel[nr].lc = (audio_channel[nr].lc & ~0xffff) | (v & 0xFFFE);
                    839: }
                    840: 
                    841: void AUDxPER (int nr, uae_u16 v)
                    842: {
                    843:     update_audio ();
                    844: 
                    845:     if (v == 0)
                    846:        v = 65535;
                    847: 
                    848:     if (v < maxhpos/2 && currprefs.produce_sound < 3)
                    849:        v = maxhpos/2;
                    850: 
                    851:     audio_channel[nr].per = v;
                    852: }
                    853: 
                    854: void AUDxLEN (int nr, uae_u16 v)
                    855: {
                    856:     update_audio ();
                    857: 
                    858:     audio_channel[nr].len = v;
                    859: }
                    860: 
                    861: void AUDxVOL (int nr, uae_u16 v)
                    862: {
                    863:     int v2 = v & 64 ? 63 : v & 63;
                    864: 
                    865:     update_audio ();
                    866: 
                    867:     audio_channel[nr].vol = v2;
                    868: #ifndef MULTIPLICATION_PROFITABLE
                    869:     audio_channel[nr].voltbl = sound_table[v2];
                    870: #endif
1.1       root      871: }
                    872: 
                    873: void dump_audio_bench (void)
                    874: {
                    875: #ifdef BENCHMARK_AUDIO
                    876:     printf ("Average cycles per sample handler: %f\n", ((double)sh_time / sh_count));
                    877: #endif
                    878: }

unix.superglobalmegacorp.com

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