void sound_playrout(void) { int c; playroutine(); if (usehardsid) { #ifdef __WIN32__ for (c = 0; c < NUMSIDREGS; c++) { unsigned o = sid_getorder(c); if (cycleexacthardsid) { HardSID_Write(usehardsid-1, SIDWRITEDELAY, o, sidreg[o]); } else { WriteToHardSID(usehardsid-1, o, sidreg[o]); } } #else for (c = 0; c < NUMSIDREGS; c++) { unsigned o = sid_getorder(c); Uint32 dataword = (o << 8) | sidreg[o]; write(hardsidfd, &dataword, 4); } #endif } else if (usecatweasel) { #ifdef __WIN32__ DWORD w; unsigned char buf[NUMSIDREGS * 2]; for(w = 0; w < NUMSIDREGS; w++) { unsigned o = sid_getorder(w); buf[w*2] = o; buf[w*2+1] = sidreg[o]; } DeviceIoControl(catweaselhandle, SID_SID_PEEK_POKE, buf, sizeof(buf), 0L, 0UL, &w, 0L); #else for (c = 0; c < NUMSIDREGS; c++) { unsigned o = sid_getorder(c); lseek(catweaselfd, o, SEEK_SET); write(catweaselfd, &sidreg[o], 1); } #endif } }
int sid_fillbuffer(short *ptr, int samples, const int cyc) { int os = samples; int rc = cyc / 3; // NUMVOICE int badline = rand() % NUMSIDREGS; int tdelta; int tdelta2; int result; int total = 0; int c; tdelta = clockrate * samples / samplerate; for (c = 0; c < NUMSIDREGS; c++) { unsigned char o = sid_getorder(c); // Extra delay per music routine iteration if (cyc > 0 && ((c == 0) || (c == 7) || (c == 14))) { tdelta2 = rc; if(usefp) result = sidfp->clock(tdelta2, ptr, samples); else result = sid->clock(tdelta2, ptr, samples); total += result; ptr += result; samples -= result; tdelta -= rc; } // Possible random badline delay once per writing /* if ((badline == c) && (residdelay)) { tdelta2 = residdelay; result = sid->clock(tdelta2, ptr, samples); total += result; ptr += result; samples -= result; tdelta -= residdelay; } */ if(usefp) sidfp->write(o, sidreg[o]); else sid->write(o, sidreg[o]); tdelta2 = SIDWRITEDELAY; if(usefp) result = sidfp->clock(tdelta2, ptr, samples); else result = sid->clock(tdelta2, ptr, samples); total += result; ptr += result; samples -= result; tdelta -= SIDWRITEDELAY; } if(usefp) result = sidfp->clock(tdelta, ptr, samples); else result = sid->clock(tdelta, ptr, samples); total += result; if(total > os) abort(); assert(total <= os); return total; }
int sound_thread(void *userdata) { unsigned long flush_cycles_interactive = hardsidbufinteractive * 1000; /* 0 = flush off for interactive mode*/ unsigned long flush_cycles_playback = hardsidbufplayback * 1000; /* 0 = flush off for playback mode*/ unsigned long cycles_after_flush = 0; boolean interactive; while (runplayerthread) { unsigned cycles = 1000000 / framerate; // HardSID should be clocked at 1MHz int c; if (flush_cycles_interactive > 0 || flush_cycles_playback > 0) { cycles_after_flush += cycles; } // Do flush if starting playback, stopping playback, starting an interactive note etc. if (flushplayerthread) { SDL_LockMutex(flushmutex); if (HardSID_Flush) { HardSID_Flush(usehardsid-1); } // Can clear player suspend now (if set) suspendplayroutine = FALSE; flushplayerthread = FALSE; SDL_UnlockMutex(flushmutex); SDL_Delay(0); } if (!suspendplayroutine) playroutine(); interactive = !(boolean)recordmode /* jam mode */ || !(boolean)isplaying(); for (c = 0; c < NUMSIDREGS; c++) { unsigned o = sid_getorder(c); // Extra delay before loading the waveform (and mt_chngate,x) if ((o == 4) || (o == 11) || (o == 18)) { HardSID_Write(usehardsid-1, SIDWRITEDELAY+SIDWAVEDELAY, o, sidreg[o]); cycles -= SIDWRITEDELAY+SIDWAVEDELAY; } else { HardSID_Write(usehardsid-1, SIDWRITEDELAY, o, sidreg[o]); cycles -= SIDWRITEDELAY; } } // Now wait the rest of frame while (cycles) { unsigned runnow = cycles; if (runnow > 65535) runnow = 65535; HardSID_Delay(usehardsid-1, runnow); cycles -= runnow; } if ((flush_cycles_interactive>0 && interactive && cycles_after_flush>=flush_cycles_interactive) || (flush_cycles_playback>0 && !interactive && cycles_after_flush>=flush_cycles_playback)) { if (HardSID_SoftFlush) HardSID_SoftFlush(usehardsid-1); cycles_after_flush = 0; } } unsigned r; for (r = 0; r < NUMSIDREGS; r++) { HardSID_Write(usehardsid-1, SIDWRITEDELAY, r, 0); } if (HardSID_SoftFlush) HardSID_SoftFlush(usehardsid-1); return 0; }