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

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.5 ! root      111: void sample16i_handler (void)
        !           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.2   root      167: void sample8_handler (void)
1.1       root      168: {
                    169:     BEGIN_BENCH
                    170:        
                    171:     uae_u32 data0 = audio_channel[0].current_sample;
                    172:     uae_u32 data1 = audio_channel[1].current_sample;
                    173:     uae_u32 data2 = audio_channel[2].current_sample;
                    174:     uae_u32 data3 = audio_channel[3].current_sample;
                    175:     DO_CHANNEL_1 (data0, 0);
                    176:     DO_CHANNEL_1 (data1, 1);
                    177:     DO_CHANNEL_1 (data2, 2);
                    178:     DO_CHANNEL_1 (data3, 3);
                    179:     data0 &= audio_channel[0].adk_mask;
                    180:     data1 &= audio_channel[1].adk_mask;
                    181:     data2 &= audio_channel[2].adk_mask;
                    182:     data3 &= audio_channel[3].adk_mask;
                    183:     data0 += data1;
                    184:     data0 += data2;
                    185:     data0 += data3;
                    186:     {
                    187:        uae_u32 data = SBASEVAL8(2) + data0;
                    188:        FINISH_DATA(8, 2);
                    189:        PUT_SOUND_BYTE (data);
                    190:     }
                    191:     END_BENCH
                    192: 
                    193:     check_sound_buffers ();
                    194: }
                    195: 
                    196: #ifdef HAVE_STEREO_SUPPORT
1.1.1.2   root      197: void sample16s_handler (void)
1.1       root      198: {
                    199:     BEGIN_BENCH
                    200: 
                    201:     uae_u32 data0 = audio_channel[0].current_sample;
                    202:     uae_u32 data1 = audio_channel[1].current_sample;
                    203:     uae_u32 data2 = audio_channel[2].current_sample;
                    204:     uae_u32 data3 = audio_channel[3].current_sample;
                    205:     DO_CHANNEL_1 (data0, 0);
                    206:     DO_CHANNEL_1 (data1, 1);
                    207:     DO_CHANNEL_1 (data2, 2);
                    208:     DO_CHANNEL_1 (data3, 3);
                    209: 
                    210:     data0 &= audio_channel[0].adk_mask;
                    211:     data1 &= audio_channel[1].adk_mask;
                    212:     data2 &= audio_channel[2].adk_mask;
                    213:     data3 &= audio_channel[3].adk_mask;
                    214:     
                    215:     data0 += data3;
                    216:     {
                    217:        uae_u32 data = SBASEVAL16(1) + data0;
                    218:        FINISH_DATA (16, 1);
                    219:        PUT_SOUND_WORD_RIGHT (data);
                    220:     }
                    221: 
                    222:     data1 += data2;
                    223:     {
                    224:        uae_u32 data = SBASEVAL16(1) + data1;
                    225:        FINISH_DATA (16, 1);
                    226:        PUT_SOUND_WORD_LEFT (data);
                    227:     }
                    228:     
                    229:     END_BENCH
                    230:     
                    231:     check_sound_buffers ();
                    232: }
                    233: 
1.1.1.5 ! root      234: void sample16si_handler (void)
        !           235: {
        !           236:     unsigned long delta, ratio;
        !           237: 
        !           238:     BEGIN_BENCH
        !           239: 
        !           240:     uae_u32 data0 = audio_channel[0].current_sample;
        !           241:     uae_u32 data1 = audio_channel[1].current_sample;
        !           242:     uae_u32 data2 = audio_channel[2].current_sample;
        !           243:     uae_u32 data3 = audio_channel[3].current_sample;
        !           244:     uae_u32 data0p = audio_channel[0].last_sample;
        !           245:     uae_u32 data1p = audio_channel[1].last_sample;
        !           246:     uae_u32 data2p = audio_channel[2].last_sample;
        !           247:     uae_u32 data3p = audio_channel[3].last_sample;
        !           248: 
        !           249:     DO_CHANNEL_1 (data0, 0);
        !           250:     DO_CHANNEL_1 (data1, 1);
        !           251:     DO_CHANNEL_1 (data2, 2);
        !           252:     DO_CHANNEL_1 (data3, 3);
        !           253:     DO_CHANNEL_1 (data0p, 0);
        !           254:     DO_CHANNEL_1 (data1p, 1);
        !           255:     DO_CHANNEL_1 (data2p, 2);
        !           256:     DO_CHANNEL_1 (data3p, 3);
        !           257: 
        !           258:     data0 &= audio_channel[0].adk_mask;
        !           259:     data0p &= audio_channel[0].adk_mask;
        !           260:     data1 &= audio_channel[1].adk_mask;
        !           261:     data1p &= audio_channel[1].adk_mask;
        !           262:     data2 &= audio_channel[2].adk_mask;
        !           263:     data2p &= audio_channel[2].adk_mask;
        !           264:     data3 &= audio_channel[3].adk_mask;
        !           265:     data3p &= audio_channel[3].adk_mask;
        !           266: 
        !           267: # if 0
        !           268:     /* linear interpolation and summing up... */
        !           269:     delta = audio_channel[0].per;
        !           270:     ratio = ((audio_channel[0].evtime % delta) << 8) / delta;
        !           271:     data0 = (data0 * (256 - ratio) + data0p * ratio) >> 8;
        !           272:     delta = audio_channel[1].per;
        !           273:     ratio = ((audio_channel[1].evtime % delta) << 8) / delta;
        !           274:     data1 = (data1 * (256 - ratio) + data1p * ratio) >> 8;
        !           275:     delta = audio_channel[2].per;
        !           276:     ratio = ((audio_channel[2].evtime % delta) << 8) / delta;
        !           277:     data1 += (data2 * (256 - ratio) + data2p * ratio) >> 8;
        !           278:     delta = audio_channel[3].per;
        !           279:     ratio = ((audio_channel[3].evtime % delta) << 8) / delta;
        !           280:     data0 += (data3 * (256 - ratio) + data3p * ratio) >> 8;
        !           281: #else
        !           282:     {    
        !           283:        struct audio_channel_data *cdp;
        !           284:        int ratio, ratio1;
        !           285: #define INTERVAL (sample_evtime)
        !           286:        cdp = audio_channel + 0;
        !           287:        ratio1 = cdp->per - cdp->evtime;
        !           288:        ratio = (ratio1 << 12) / INTERVAL;
        !           289:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
        !           290:            ratio = 4096;
        !           291:        data0 = (data0 * ratio + data0p * (4096 - ratio)) >> 12;
        !           292: 
        !           293:        cdp = audio_channel + 1;
        !           294:        ratio1 = cdp->per - cdp->evtime;
        !           295:        ratio = (ratio1 << 12) / INTERVAL;
        !           296:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
        !           297:            ratio = 4096;
        !           298:        data1 = (data1 * ratio + data1p * (4096 - ratio)) >> 12;
        !           299: 
        !           300:        cdp = audio_channel + 2;
        !           301:        ratio1 = cdp->per - cdp->evtime;
        !           302:        ratio = (ratio1 << 12) / INTERVAL;
        !           303:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
        !           304:            ratio = 4096;
        !           305:        data2 = (data2 * ratio + data2p * (4096 - ratio)) >> 12;
        !           306: 
        !           307:        cdp = audio_channel + 3;
        !           308:        ratio1 = cdp->per - cdp->evtime;
        !           309:        ratio = (ratio1 << 12) / INTERVAL;
        !           310:        if (cdp->evtime < sample_evtime || ratio1 >= INTERVAL)
        !           311:            ratio = 4096;
        !           312:        data3 = (data3 * ratio + data3p * (4096 - ratio)) >> 12;
        !           313:     }
        !           314:     data1 += data2;
        !           315:     data0 += data3;
        !           316: #endif
        !           317:     {
        !           318:        uae_u32 data = SBASEVAL16 (1) + data0;
        !           319:        FINISH_DATA (16, 1);
        !           320:        PUT_SOUND_WORD_RIGHT (data);
        !           321:     }
        !           322: 
        !           323:     {
        !           324:        uae_u32 data = SBASEVAL16 (1) + data1;
        !           325:        FINISH_DATA (16, 1);
        !           326:        PUT_SOUND_WORD_LEFT (data);
        !           327:     }
        !           328:     
        !           329:     END_BENCH
        !           330:     
        !           331:     check_sound_buffers ();
        !           332: }
        !           333: 
1.1.1.2   root      334: void sample8s_handler (void)
1.1       root      335: {
                    336:     BEGIN_BENCH
                    337: 
                    338:     uae_u32 data0 = audio_channel[0].current_sample;
                    339:     uae_u32 data1 = audio_channel[1].current_sample;
                    340:     uae_u32 data2 = audio_channel[2].current_sample;
                    341:     uae_u32 data3 = audio_channel[3].current_sample;
                    342:     DO_CHANNEL_1 (data0, 0);
                    343:     DO_CHANNEL_1 (data1, 1);
                    344:     DO_CHANNEL_1 (data2, 2);
                    345:     DO_CHANNEL_1 (data3, 3);
                    346: 
                    347:     data0 &= audio_channel[0].adk_mask;
                    348:     data1 &= audio_channel[1].adk_mask;
                    349:     data2 &= audio_channel[2].adk_mask;
                    350:     data3 &= audio_channel[3].adk_mask;
                    351: 
                    352:     data0 += data3;
                    353:     {
                    354:        uae_u32 data = SBASEVAL8(1) + data0;
                    355:        FINISH_DATA (8, 1);
                    356:        PUT_SOUND_BYTE_RIGHT (data);
                    357:     }
                    358:     data1 += data2;
                    359:     {
                    360:        uae_u32 data = SBASEVAL8(1) + data1;
                    361:        FINISH_DATA (8, 1);
                    362:        PUT_SOUND_BYTE_LEFT (data);
                    363:     }
                    364: 
                    365:     END_BENCH
                    366:     
                    367:     check_sound_buffers ();
                    368: }
                    369: #else
1.1.1.2   root      370: void sample8s_handler (void)
1.1       root      371: {
                    372:     sample8_handler();
                    373: }
1.1.1.2   root      374: void sample16s_handler (void)
1.1       root      375: {
                    376:     sample16_handler();
                    377: }
                    378: #endif
                    379: 
1.1.1.2   root      380: static uae_u8 int2ulaw (int ch)
1.1       root      381: {
                    382:     int mask;
                    383: 
                    384:     if (ch < 0) {
                    385:       ch = -ch;
                    386:       mask = 0x7f;
                    387:     }
                    388:     else {
                    389:       mask = 0xff;
                    390:     }
                    391: 
                    392:     if (ch < 32) {
                    393:        ch = 0xF0 | ( 15 - (ch/2) );
                    394:     } else if (ch < 96) {
                    395:        ch = 0xE0 | ( 15 - (ch-32)/4 );
                    396:     } else if (ch < 224) {
                    397:        ch = 0xD0 | ( 15 - (ch-96)/8 );
                    398:     } else if (ch < 480) {
                    399:        ch = 0xC0 | ( 15 - (ch-224)/16 );
                    400:     } else if (ch < 992 ) {
                    401:        ch = 0xB0 | ( 15 - (ch-480)/32 );
                    402:     } else if (ch < 2016) {
                    403:        ch = 0xA0 | ( 15 - (ch-992)/64 );
                    404:     } else if (ch < 4064) {
                    405:        ch = 0x90 | ( 15 - (ch-2016)/128 );
                    406:     } else if (ch < 8160) {
                    407:        ch = 0x80 | ( 15 - (ch-4064)/256 );
                    408:     } else {
                    409:        ch = 0x80;
                    410:     }
                    411:     return (uae_u8)(mask & ch);
                    412: }
                    413: 
                    414: void sample_ulaw_handler (void)
                    415: {
                    416:     int nr;
                    417:     uae_u32 data = 0;
                    418: 
                    419:     for (nr = 0; nr < 4; nr++) {
                    420:        if (!(adkcon & (0x11 << nr))) {
                    421:            uae_u32 d = audio_channel[nr].current_sample;
                    422:            DO_CHANNEL_1 (d, nr);
                    423:            data += d;
                    424:        }
                    425:     }
                    426:     PUT_SOUND_BYTE (int2ulaw (data));
                    427:     check_sound_buffers ();
                    428: }
                    429: 
                    430: static void audio_handler (int nr)
                    431: {
                    432:     struct audio_channel_data *cdp = audio_channel + nr;
                    433: 
                    434:     switch (cdp->state) {
                    435:      case 0:
                    436:        fprintf(stderr, "Bug in sound code\n");
                    437:        break;
                    438: 
                    439:      case 1:
                    440:        /* We come here at the first hsync after DMA was turned on. */
1.1.1.2   root      441:        cdp->evtime = maxhpos;
1.1       root      442: 
                    443:        cdp->state = 5;
                    444:        INTREQ(0x8000 | (0x80 << nr));
                    445:        if (cdp->wlen != 1)
                    446:            cdp->wlen--;
                    447:        cdp->nextdat = chipmem_bank.wget(cdp->pt);
                    448: 
                    449:        cdp->pt += 2;
                    450:        break;
                    451: 
                    452:      case 5:
                    453:        /* We come here at the second hsync after DMA was turned on. */
                    454:        if (currprefs.produce_sound == 0)
                    455:            cdp->per = 65535;
                    456: 
1.1.1.2   root      457:        cdp->evtime = cdp->per;
1.1       root      458:        cdp->dat = cdp->nextdat;
1.1.1.5 ! root      459:        cdp->last_sample = cdp->current_sample;
1.1       root      460:        cdp->current_sample = (sample8_t)(cdp->dat >> 8);
                    461: 
                    462:        cdp->state = 2;
                    463:        {
                    464:            int audav = adkcon & (1 << nr);
                    465:            int audap = adkcon & (16 << nr);
                    466:            int napnav = (!audav && !audap) || audav;
                    467:            if (napnav)
                    468:                cdp->data_written = 2;
                    469:        }
                    470:        break;
                    471: 
                    472:      case 2:
                    473:        /* We come here when a 2->3 transition occurs */
                    474:        if (currprefs.produce_sound == 0)
                    475:            cdp->per = 65535;
                    476: 
1.1.1.5 ! root      477:        cdp->last_sample = cdp->current_sample;
1.1       root      478:        cdp->current_sample = (sample8_t)(cdp->dat & 0xFF);
1.1.1.2   root      479:        cdp->evtime = cdp->per;
1.1       root      480: 
                    481:        cdp->state = 3;
                    482: 
                    483:        /* Period attachment? */
                    484:        if (adkcon & (0x10 << nr)) {
                    485:            if (cdp->intreq2 && cdp->dmaen)
                    486:                INTREQ(0x8000 | (0x80 << nr));
                    487:            cdp->intreq2 = 0;
                    488: 
                    489:            cdp->dat = cdp->nextdat;
                    490:            if (cdp->dmaen)
                    491:                cdp->data_written = 2;
                    492:            if (nr < 3) {
                    493:                if (cdp->dat == 0)
                    494:                    (cdp+1)->per = 65535;
                    495: 
                    496:                else if (cdp->dat < maxhpos/2 && currprefs.produce_sound < 3)
                    497:                    (cdp+1)->per = maxhpos/2;
                    498:                else
                    499:                    (cdp+1)->per = cdp->dat;
                    500:            }
                    501:        }
                    502:        break;
                    503: 
                    504:      case 3:
                    505:        /* We come here when a 3->2 transition occurs */
                    506:        if (currprefs.produce_sound == 0)
                    507:            cdp->per = 65535;
                    508: 
1.1.1.2   root      509:        cdp->evtime = cdp->per;
1.1       root      510: 
                    511:        if ((INTREQR() & (0x80 << nr)) && !cdp->dmaen) {
                    512:            cdp->state = 0;
1.1.1.5 ! root      513:            cdp->last_sample = 0;
1.1       root      514:            cdp->current_sample = 0;
                    515:            break;
                    516:        } else {
                    517:            int audav = adkcon & (1 << nr);
                    518:            int audap = adkcon & (16 << nr);
                    519:            int napnav = (!audav && !audap) || audav;
                    520:            cdp->state = 2;
                    521: 
                    522:            if ((cdp->intreq2 && cdp->dmaen && napnav)
                    523:                || (napnav && !cdp->dmaen))
                    524:                INTREQ(0x8000 | (0x80 << nr));
                    525:            cdp->intreq2 = 0;
                    526: 
                    527:            cdp->dat = cdp->nextdat;
1.1.1.5 ! root      528:            cdp->last_sample = cdp->current_sample;
1.1       root      529:            cdp->current_sample = (sample8_t)(cdp->dat >> 8);
                    530: 
                    531:            if (cdp->dmaen && napnav)
                    532:                cdp->data_written = 2;
                    533: 
                    534:            /* Volume attachment? */
                    535:            if (audav) {
                    536:                if (nr < 3) {
                    537:                    (cdp+1)->vol = cdp->dat;
                    538: #ifndef MULTIPLICATION_PROFITABLE
                    539:                    (cdp+1)->voltbl = sound_table[cdp->dat];
                    540: #endif
                    541:                }
                    542:            }
                    543:        }
                    544:        break;
                    545: 
                    546:      default:
                    547:        cdp->state = 0;
                    548:        break;
                    549:     }
                    550: }
                    551: 
                    552: void aud0_handler (void)
                    553: {
                    554:     audio_handler (0);
                    555: }
                    556: void aud1_handler (void)
                    557: {
                    558:     audio_handler (1);
                    559: }
                    560: void aud2_handler (void)
                    561: {
                    562:     audio_handler (2);
                    563: }
                    564: void aud3_handler (void)
                    565: {
                    566:     audio_handler (3);
                    567: }
                    568: 
                    569: void audio_reset (void)
                    570: {
                    571:     memset (audio_channel, 0, sizeof audio_channel);
                    572:     audio_channel[0].per = 65535;
                    573:     audio_channel[1].per = 65535;
                    574:     audio_channel[2].per = 65535;
                    575:     audio_channel[3].per = 65535;
                    576:     audio_channel[0].voltbl = sound_table[0];
                    577:     audio_channel[1].voltbl = sound_table[0];
                    578:     audio_channel[2].voltbl = sound_table[0];
                    579:     audio_channel[3].voltbl = sound_table[0];
1.1.1.2   root      580: 
                    581:     last_cycles = 0;
                    582:     next_sample_evtime = sample_evtime;
                    583: }
                    584: 
                    585: static __inline__ int sound_prefs_changed (void)
                    586: {
                    587:     return (changed_prefs.produce_sound != currprefs.produce_sound
                    588:            || changed_prefs.stereo != currprefs.stereo
1.1.1.4   root      589:            || changed_prefs.sound_freq != currprefs.sound_freq
1.1.1.2   root      590:            || changed_prefs.sound_bits != currprefs.sound_bits);
                    591: }
                    592: 
                    593: void check_prefs_changed_audio (void)
                    594: {
                    595:     if (! sound_available || ! sound_prefs_changed ())
                    596:        return;
                    597: 
                    598:     close_sound ();
1.1.1.3   root      599: 
1.1.1.2   root      600:     currprefs.produce_sound = changed_prefs.produce_sound;
                    601:     currprefs.stereo = changed_prefs.stereo;
                    602:     currprefs.sound_bits = changed_prefs.sound_bits;
1.1.1.4   root      603:     currprefs.sound_freq = changed_prefs.sound_freq;
1.1.1.2   root      604: 
1.1.1.3   root      605:     if (currprefs.produce_sound < 2)
                    606:        return;
                    607: 
                    608:     if (init_sound ()) {
                    609:        last_cycles = cycles - 1;
                    610:        next_sample_evtime = sample_evtime;
                    611:        return;
                    612:     }
                    613:     if (! sound_available) {
                    614:        fprintf (stderr, "Sound is not supported.\n");
1.1.1.2   root      615:     } else {
1.1.1.3   root      616:        fprintf (stderr, "Sorry, can't initialize sound.\n");
                    617:        currprefs.produce_sound = 0;
                    618:        /* So we don't do this every frame */
                    619:        changed_prefs.produce_sound = 0;
1.1.1.2   root      620:     }
                    621: }
                    622: 
                    623: void update_audio (void)
                    624: {
                    625:     unsigned long int n_cycles;
                    626: 
1.1.1.4   root      627:     if (currprefs.produce_sound < 2)
1.1.1.2   root      628:        return;
                    629: 
                    630:     n_cycles = cycles - last_cycles;
                    631:     for (;;) {
                    632:        int best = -1;
                    633:        unsigned long int best_evtime = n_cycles + 1;
                    634:        if (audio_channel[0].state != 0 && best_evtime > audio_channel[0].evtime)
                    635:            best = 0, best_evtime = audio_channel[0].evtime;
                    636:        if (audio_channel[1].state != 0 && best_evtime > audio_channel[1].evtime)
                    637:            best = 1, best_evtime = audio_channel[1].evtime;
                    638:        if (audio_channel[2].state != 0 && best_evtime > audio_channel[2].evtime)
                    639:            best = 2, best_evtime = audio_channel[2].evtime;
                    640:        if (audio_channel[3].state != 0 && best_evtime > audio_channel[3].evtime)
                    641:            best = 3, best_evtime = audio_channel[3].evtime;
                    642:        if (best_evtime > next_sample_evtime)
                    643:            best_evtime = next_sample_evtime;
                    644: 
                    645:        if (best_evtime > n_cycles)
                    646:            break;
                    647: 
                    648:        next_sample_evtime -= best_evtime;
                    649:        audio_channel[0].evtime -= best_evtime;
                    650:        audio_channel[1].evtime -= best_evtime;
                    651:        audio_channel[2].evtime -= best_evtime;
                    652:        audio_channel[3].evtime -= best_evtime;
                    653:        n_cycles -= best_evtime;
1.1.1.3   root      654:        if (next_sample_evtime == 0 && currprefs.produce_sound > 1) {
1.1.1.2   root      655:            next_sample_evtime = sample_evtime;
                    656:            (*sample_handler) ();
                    657:        }
                    658:        if (audio_channel[0].evtime == 0 && audio_channel[0].state != 0)
                    659:            audio_handler (0);
                    660:        if (audio_channel[1].evtime == 0 && audio_channel[1].state != 0)
                    661:            audio_handler (1);
                    662:        if (audio_channel[2].evtime == 0 && audio_channel[2].state != 0)
                    663:            audio_handler (2);
                    664:        if (audio_channel[3].evtime == 0 && audio_channel[3].state != 0)
                    665:            audio_handler (3);
                    666:     }
                    667:     last_cycles = cycles - n_cycles;
                    668: }
                    669: 
                    670: void AUDxDAT (int nr, uae_u16 v)
                    671: {
                    672:     struct audio_channel_data *cdp = audio_channel + nr;
                    673: 
                    674:     update_audio ();
                    675: 
                    676:     cdp->dat = v;
                    677:     if (cdp->state == 0 && !(INTREQR() & (0x80 << nr))) {
                    678:        cdp->state = 2;
                    679:        INTREQ(0x8000 | (0x80 << nr));
                    680:        /* data_written = 2 ???? */
                    681:        cdp->evtime = cdp->per;
                    682:     }
                    683: }
                    684: 
                    685: void AUDxLCH (int nr, uae_u16 v)
                    686: {
                    687:     update_audio ();
                    688: 
                    689:     audio_channel[nr].lc = (audio_channel[nr].lc & 0xffff) | ((uae_u32)v << 16);
                    690: }
                    691: 
                    692: void AUDxLCL (int nr, uae_u16 v)
                    693: {
                    694:     update_audio ();
                    695: 
                    696:     audio_channel[nr].lc = (audio_channel[nr].lc & ~0xffff) | (v & 0xFFFE);
                    697: }
                    698: 
                    699: void AUDxPER (int nr, uae_u16 v)
                    700: {
                    701:     update_audio ();
                    702: 
                    703:     if (v == 0)
                    704:        v = 65535;
                    705: 
                    706:     if (v < maxhpos/2 && currprefs.produce_sound < 3)
                    707:        v = maxhpos/2;
                    708: 
                    709:     audio_channel[nr].per = v;
                    710: }
                    711: 
                    712: void AUDxLEN (int nr, uae_u16 v)
                    713: {
                    714:     update_audio ();
                    715: 
                    716:     audio_channel[nr].len = v;
                    717: }
                    718: 
                    719: void AUDxVOL (int nr, uae_u16 v)
                    720: {
                    721:     int v2 = v & 64 ? 63 : v & 63;
                    722: 
                    723:     update_audio ();
                    724: 
                    725:     audio_channel[nr].vol = v2;
                    726: #ifndef MULTIPLICATION_PROFITABLE
                    727:     audio_channel[nr].voltbl = sound_table[v2];
                    728: #endif
1.1       root      729: }
                    730: 
                    731: void dump_audio_bench (void)
                    732: {
                    733: #ifdef BENCHMARK_AUDIO
                    734:     printf ("Average cycles per sample handler: %f\n", ((double)sh_time / sh_count));
                    735: #endif
                    736: }

unix.superglobalmegacorp.com

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