#include #include #include #include struct Voice8Header { ULONG oneShotHiSamples, repeatHiSamples, samplesPerHiCycle; UWORD samplesPerSec; UBYTE ctOctave, sCompression; LONG volume; }; // This stuff is declared somewhere else extern struct IOAudio *PlaySound(); extern __far BYTE Cuckoo[]; extern void ToggleLED(void); extern BOOL GetLEDStatus(void); BOOL Find8SVXInformation(BYTE *buffer, BYTE **sample, ULONG *len, UWORD *rate); char txt[] = "$VER: Cuckoo 1.2 (6.10.93) by Anders Melchiorsen\n" "Cuckoo will, when started at ??:00 or ??:30, play a cuckoo sample.\n"; main() { UWORD cuck_rate; ULONG cuck_len,repeat; BYTE *cuck_start; struct IOAudio *id; struct DateStamp now; WORD hour, minute; BOOL ledon; // Just to make me famous: Write( Output(), &txt[6], strlen(&txt[6]) ); // Get current time DateStamp(&now); hour = now.ds_Minute/60; minute = now.ds_Minute%60; // Dicede how many times to call repeat = 0; if (minute == 0) repeat = ((hour % 12) ? (hour % 12) : 12); if (minute == 30) repeat = 1; // No call -> exit if (repeat == 0) return(0); // Find out where sample starts, how long it is, and how fast it should be // played if (!Find8SVXInformation(Cuckoo, &cuck_start, &cuck_len, &cuck_rate)) return(20); // Turn the low-pass filter off ledon = GetLEDStatus(); if (ledon) ToggleLED(); // Play sample the right number of times, delay for half a sec between // each cuckoo. while (repeat--) { ULONG signals = NULL; if (id = PlaySound(cuck_start, cuck_len, 1, 3579545/cuck_rate, 64)) { signals = Wait((1 << id->ioa_Request.io_Message.mn_ReplyPort->mp_SigBit) | SIGBREAKF_CTRL_C); StopSound(id); } // Don't repeat anymore if ^C was pressed if (signals & SIGBREAKF_CTRL_C) repeat = 0; if (repeat) Delay(25); } // Turn filter back on (if it was shut off) if (ledon) ToggleLED(); return(0); } // Finds out of certain 8SVX stuff from a buffer in memory // Returns TRUE on success // // Must be initialized // buffer = Pointer to complete 8SVX 'file' // // The following are filled in by this routine: // sample = Where actual sample starts // len = Length of sample // rate = The samples rate // // Don't get confused; it IS a weird pointer example :-) BOOL Find8SVXInformation(BYTE *buffer, BYTE **sample, ULONG *len, UWORD *rate) { LONG jump; BOOL foundVHDR = FALSE, foundBODY = FALSE; struct Voice8Header *Header; // Pass 'FORM....' buffer += 8; // Is this a 8SVX file? if ( strncmp(buffer, "8SVX", 4) != 0) return(FALSE); // Pass '....' (size of 8SVX; should perhaps use this. Oh well...) buffer += 4; // Find VHDR and BODY chunks and get the info needed from them // If one of them is missing I keep on searching forever ... not good :-( do { if (strncmp(buffer, "VHDR", 4) == 0) { Header = buffer + 8; *len = Header->oneShotHiSamples + Header->repeatHiSamples; *rate = Header->samplesPerSec; foundVHDR = TRUE; } if (strncmp(buffer, "BODY", 4) == 0) { *sample = buffer + 8; foundBODY = TRUE; } buffer += 4; // Pass chunk ID // Read chuck size jump = (*(buffer) << 24) + (*(buffer+1) << 16) + (*(buffer+2) << 8) + *(buffer+3); buffer += 4; // Pass chunk size information buffer += jump; // Pass rest of chunk (actual data) } while ( (foundVHDR==FALSE) || (foundBODY==FALSE) ); return(TRUE); }