/************* * FUNCTION: CreateRexxHost * VERSION: 0.1 08.03.1995 * DESCRIPTION: Creates a RexxHost (special MsgPort) with a given name. * Returns NULL if port already exists. * INPUT: HostName * OUTPUT: RexxHost * HISTORY: DATE NAME COMMENT * 08.03.95 ah first release *************/ struct MsgPort *CreateRexxHost(STRPTR HostName) { struct MsgPort *RexxHost; /* Valid name given? */ if(HostName && HostName[0]) { /* Already present? */ if(!FindPort((char *)HostName)) { /* Allocate the port body. */ RexxHost = (struct MsgPort *)AllocMem(sizeof(struct MsgPort),MEMF_PUBLIC | MEMF_CLEAR); if(RexxHost) { /* Allocate a signal bit. */ if((RexxHost->mp_SigBit = AllocSignal(-1)) != -1) { /* Initialize the MsgPort node head. */ RexxHost->mp_Node.ln_Type = NT_MSGPORT; RexxHost->mp_Node.ln_Pri = 0; /* Allocate memory for MsgPort name. */ RexxHost->mp_Node.ln_Name = (char *)AllocMem(strlen((char *)HostName)+1,MEMF_PUBLIC); if(RexxHost->mp_Node.ln_Name) { /* Copy the name. */ strcpy(RexxHost->mp_Node.ln_Name,(char *)HostName); /* Deal with the rest of the flags. */ RexxHost->mp_Flags = PA_SIGNAL; RexxHost->mp_SigTask = FindTask(NULL); /* Finally add it to the public port list. */ AddPort(RexxHost); /* And return it to the caller. */ return(RexxHost); } FreeSignal(RexxHost->mp_SigBit); } FreeMem(RexxHost,sizeof(struct MsgPort)); } } } return(NULL); }
struct MsgPort *CreatePort(CONST_STRPTR name,LONG pri) { APTR SysBase = *(APTR *)4L; struct MsgPort *port = NULL; UBYTE portsig; if ((BYTE)(portsig=AllocSignal(-1)) >= 0) { if (!(port=AllocMem(sizeof(*port),MEMF_CLEAR|MEMF_PUBLIC))) FreeSignal(portsig); else { port->mp_Node.ln_Type = NT_MSGPORT; port->mp_Node.ln_Pri = pri; port->mp_Node.ln_Name = name; /* done via AllocMem port->mp_Flags = PA_SIGNAL; */ port->mp_SigBit = portsig; port->mp_SigTask = FindTask(NULL); NEWLIST(&port->mp_MsgList); if (port->mp_Node.ln_Name) AddPort(port); } } return port; }
int AtaInitUnits (void) { int t; uint32 size; struct MountEnviron *me; struct Partition *partition_table; int p, hd_cnt, cd_cnt; uint16 general_config; KPRINTF ("AtaInitUnits()"); use_interrupts = FALSE; for (t=0; t<4; t++) { ata_drive[t].enabled = FALSE; ata_drive[t].config = ATA_CONFIG_NONE; ata_drive[t].reference_cnt = 0; switch (t) { case 0: ata_drive[t].ldhpref = LDH_DEFAULT | (0 << 4); break; case 1: ata_drive[t].ldhpref = LDH_DEFAULT | (1 << 4); break; case 2: ata_drive[t].ldhpref = LDH_DEFAULT | (0 << 4); break; case 3: ata_drive[t].ldhpref = LDH_DEFAULT | (1 << 4); break; } LIST_INIT (&ata_drive[t].callback_list); if (t <2) ata_drive[t].base = REG_BASE0; else ata_drive[t].base = REG_BASE1; } ata_drive[0].device[0] = &ata_drive[0]; ata_drive[0].device[1] = &ata_drive[1]; ata_drive[1].device[0] = &ata_drive[0]; ata_drive[1].device[1] = &ata_drive[1]; ata_drive[2].device[0] = &ata_drive[2]; ata_drive[2].device[1] = &ata_drive[3]; ata_drive[3].device[0] = &ata_drive[2]; ata_drive[3].device[1] = &ata_drive[3]; AtaDetect (&ata_drive[0], &ata_drive[1]); AtaDetect (&ata_drive[2], &ata_drive[3]); if (ata_drive[0].config != ATA_CONFIG_UNKNOWN || ata_drive[1].config != ATA_CONFIG_UNKNOWN) { if ((ata_isr14_signal = AllocSignal()) != -1) { if ((ata_isr14_handler = ISRHandlerInsert (14, AtaISRHandler, NULL)) != NULL) { ata_isr14_enabled = TRUE; ata_drive[0].isr_signal = ata_isr14_signal; ata_drive[1].isr_signal = ata_isr14_signal; } else FreeSignal (ata_isr14_signal); } } if (ata_drive[2].config != ATA_CONFIG_UNKNOWN || ata_drive[3].config != ATA_CONFIG_UNKNOWN) { if ((ata_isr15_signal = AllocSignal()) != -1) { if ((ata_isr15_handler = ISRHandlerInsert (15, AtaISRHandler, NULL)) != NULL) { ata_isr15_enabled = TRUE; ata_drive[2].isr_signal = ata_isr15_signal; ata_drive[3].isr_signal = ata_isr15_signal; } else FreeSignal (ata_isr15_signal); } } use_interrupts = TRUE; for (t=0; t<4; t++) { if (ata_drive[t].config == ATA_CONFIG_ATA) { KPRINTF ("ATA Drive (%d) is ATA", t); if (AtaIdentify (&ata_drive[t], ata_buffer) == 0) { ata_drive[t].pcylinders = id_word(1); ata_drive[t].pheads = id_word(3); ata_drive[t].psectors = id_word(6); size = (uint32) ata_drive[t].pcylinders * ata_drive[t].pheads * ata_drive[t].psectors; if ((id_byte(49)[1] & 0x02) && size > 512L*1024*2) { ata_drive[t].ldhpref |= LDH_LBA; size = id_longword(60); } ata_drive[t].sector_sz = 512; ata_drive[t].size = size; ata_drive[t].disk_state = ATA_MEDIA_PRESENT; ata_drive[t].diskchange_cnt = 0; ata_drive[t].enabled = TRUE; } } else if (ata_drive[t].config == ATA_CONFIG_ATAPI) { KPRINTF ("ata_isr15_cnt = %d", ata_isr15_cnt); KPRINTF ("ATA Drive (%d) is ATAPI, RESETTING", t); AtapiReset (&ata_drive[t]); KPRINTF ("ATAPI RESET complete"); KPRINTF ("ata_isr15_cnt = %d", ata_isr15_cnt); if (AtapiIdentify (&ata_drive[t], ata_buffer) == 0) { KPRINTF ("Atapi Identify OK on ATAPI device"); KPRINTF ("ata_isr15_cnt = %d", ata_isr15_cnt); general_config = id_word (0); ata_drive[t].atapi_protocol_type = (general_config & 0xC000) >> 14; ata_drive[t].atapi_type = (general_config & 0x1F00) >> 8; ata_drive[t].atapi_removable = (general_config & 0x0080) >> 7; ata_drive[t].atapi_cmd_drq_type = (general_config & 0x0060) >> 5; ata_drive[t].atapi_cmd_packet_size = ((general_config & 0x0001) == 1) ? 16 : 12; KPRINTF ("protocol_type = %d", ata_drive[t].atapi_protocol_type); KPRINTF ("atapi_type = %d", ata_drive[t].atapi_type); KPRINTF ("packet_size = %d", ata_drive[t].atapi_cmd_packet_size); if (ata_drive[t].atapi_protocol_type == ATAPI_PROTOCOL_ATAPI && ata_drive[t].atapi_type == ATAPI_TYPE_CDROM && ata_drive[t].atapi_cmd_packet_size == 12) { KPRINTF ("ATAPI CDROM DETECTED"); ata_drive[t].sector_sz = 2048; ata_drive[t].size = 0; ata_drive[t].enabled = TRUE; ata_drive[t].disk_state = AtapiMediaPresent (&ata_drive[t]); ata_drive[t].diskchange_cnt = 0; } } }
VOID DispatcherThread(struct MOSWriteHandle* h) { struct MsgPort* ahi_port = NULL; struct AHIRequest* ahi_request = NULL; struct AHIAudioCtrl*ahi_control = NULL; BYTE* sample_bufs = NULL; ULONG sample_size = 2; BYTE ahi_device = -1; LONG switch_sig_bit = -1; LONG locked_buf = -1; struct DispatcherStartupMsg *startup_msg; struct DispatcherInitReport *init_report; struct MsgPort *task_port = NULL; struct ExecBase *SysBase = *(struct ExecBase **) 4; init_report = (struct DispatcherInitReport *) AllocVec(sizeof (struct DispatcherInitReport), MEMF_PUBLIC | MEMF_CLEAR); if (init_report == NULL) return; NewGetTaskAttrsA(NULL, &task_port, sizeof (task_port), TASKINFOTYPE_TASKMSGPORT, NULL); NewGetTaskAttrsA(NULL, &startup_msg, sizeof (startup_msg), TASKINFOTYPE_STARTUPMSG, NULL); if (task_port == NULL || startup_msg == NULL) { FreeVec(init_report); return; } startup_msg->dsm_Result = -1; switch_sig_bit = AllocSignal(-1); if (switch_sig_bit != -1 && (ahi_port = CreateMsgPort())) { if ((ahi_request = (struct AHIRequest *) CreateIORequest(ahi_port, sizeof (struct AHIRequest)))) { ahi_request->ahir_Version = 4; if ((ahi_device = OpenDevice(AHINAME, AHI_NO_UNIT, (struct IORequest *) ahi_request, 0)) == 0) { AHIBase = (struct Library*) ahi_request->ahir_Std.io_Device; /*dprintf("AllocAudio with %d channels, %d sounds and frequency %d\n", h->wh_Channels, AHI_BUFFERS, h->wh_Frequency);*/ ahi_control = AHI_AllocAudio(AHIA_AudioID, AHI_DEFAULT_ID, AHIA_Channels, h->wh_Channels, AHIA_Sounds, AHI_BUFFERS, AHIA_MixFreq, h->wh_Frequency, AHIA_SoundFunc, (ULONG) &OpenAL_SoundHook, AHIA_UserData, (ULONG) h, TAG_DONE ); if (ahi_control) { ULONG buf_size; ULONG samples, fs, fm; AHI_GetAudioAttrs(AHI_INVALID_ID, ahi_control, AHIDB_MaxPlaySamples, (ULONG) &samples, TAG_DONE); AHI_ControlAudio(ahi_control, AHIC_MixFreq_Query, (ULONG) &fm, TAG_DONE); fs = h->wh_Frequency; buf_size = samples*fs/fm; /*dprintf("OpenAL: Minimum buffer size is %d, requested buffer size is %d\n", buf_size, h->wh_BufSize);*/ if (buf_size > h->wh_BufSize) h->wh_BufSize = buf_size; sample_bufs = AllocVec(h->wh_BufSize*AHI_BUFFERS, MEMF_PUBLIC | MEMF_CLEAR); if (sample_bufs) { struct Buffer* bn; ULONG buf; LONG err = AHIE_OK; sample_size = AHI_SampleFrameSize(h->wh_SampleType); for (buf = 0; buf < AHI_BUFFERS && err == AHIE_OK; buf++) { bn = &h->wh_Buffers[buf]; bn->bn_SampleNo = buf; bn->bn_SampleInfo.ahisi_Type = h->wh_SampleType; bn->bn_SampleInfo.ahisi_Address = &sample_bufs[buf*h->wh_BufSize]; bn->bn_SampleInfo.ahisi_Length = h->wh_BufSize/sample_size; InitSemaphore(&bn->bn_Semaphore); bn->bn_FillSize = 0; err = AHI_LoadSound(buf, AHIST_DYNAMICSAMPLE, &bn->bn_SampleInfo, ahi_control); } if (err != AHIE_OK) { FreeVec(sample_bufs); sample_bufs = NULL; } } } } } } if (sample_bufs) { BOOL dispatcher_running = TRUE; ULONG signal_mask = 1 << task_port->mp_SigBit; ULONG signal_set; struct MsgPort *reply_port; reply_port = CreateMsgPort(); if (reply_port == NULL) reply_port = task_port; if (startup_msg) startup_msg->dsm_Result = 0; init_report->dir_Msg.mn_Node.ln_Type = NT_MESSAGE; init_report->dir_Msg.mn_ReplyPort = reply_port; init_report->dir_Msg.mn_Length = sizeof (struct DispatcherInitReport); AHI_ControlAudio(ahi_control, AHIC_MixFreq_Query, (ULONG) &init_report->dir_RealFrequency, TAG_DONE); init_report->dir_RealBufSize = h->wh_BufSize; PutMsg(startup_msg->dsm_Msg.mn_ReplyPort, (struct Message*) init_report); WaitPort(reply_port); GetMsg(reply_port); FreeVec(init_report); init_report = NULL; if (reply_port != task_port) DeleteMsgPort(reply_port); h->wh_SwitchSignal = 1UL << switch_sig_bit; h->wh_ReadBuf = 0; while (dispatcher_running) { signal_set = Wait(signal_mask); if (signal_set & (1 << task_port->mp_SigBit)) { struct DispatcherMsg *msg; while ((msg = (struct DispatcherMsg *) GetMsg(task_port))) { if (msg->dm_Msg.mn_Length == sizeof (struct DispatcherMsg)) { switch (msg->dm_Command) { case DISPATCHER_CMD_START: { /* * First buffer has been filled and we were previously not * playing any sound yet */ ULONG chan; ULONG cur_buf; cur_buf = h->wh_ReadBuf; AHI_ControlAudio(ahi_control, AHIC_Play, TRUE, TAG_DONE); /* Lock first audio buffer */ ObtainSemaphore(&h->wh_Buffers[cur_buf].bn_Semaphore); locked_buf = cur_buf; for (chan = 0; chan < h->wh_Channels; chan++) { AHI_SetFreq(chan, h->wh_Frequency, ahi_control, AHISF_IMM); AHI_SetVol(chan, 0x10000L, -0x8000L, ahi_control, AHISF_IMM); AHI_SetSound(chan, cur_buf, 0, 0, ahi_control, AHISF_IMM); } Wait(1 << switch_sig_bit); cur_buf++; if (cur_buf >= AHI_BUFFERS) cur_buf = 0; h->wh_ReadBuf = cur_buf; signal_mask |= 1UL << switch_sig_bit; break; } case DISPATCHER_CMD_PAUSE: case DISPATCHER_CMD_RESUME: AHI_ControlAudio(ahi_control, AHIC_Play, msg->dm_Command == DISPATCHER_CMD_RESUME, TAG_DONE); break; case DISPATCHER_CMD_BREAK: /* Break requests and quit */ /*dprintf("Dispatcher thread: break requested\n");*/ AHI_ControlAudio(ahi_control, AHIC_Play, FALSE, TAG_DONE); dispatcher_running = FALSE; break; } } ReplyMsg((struct Message *) msg); } } if (signal_set & (1UL << switch_sig_bit)) { /* Switch to next read buffer */ ULONG cur_buf; cur_buf = h->wh_ReadBuf; /*dprintf("Dispatcher thread: buffer switch requested. Releasing lock on %d, locking %d\n", locked_buf, cur_buf);*/ memset(h->wh_Buffers[locked_buf].bn_SampleInfo.ahisi_Address, 0, h->wh_BufSize); ReleaseSemaphore(&h->wh_Buffers[locked_buf].bn_Semaphore); cur_buf++; if (cur_buf >= AHI_BUFFERS) cur_buf = 0; ObtainSemaphore(&h->wh_Buffers[cur_buf].bn_Semaphore); locked_buf = cur_buf; h->wh_ReadBuf = cur_buf; /*dprintf("Dispatcher thread: buffer switch done\n");*/ } } } /* Cleanup */ if (init_report) { FreeVec(init_report); init_report = NULL; } if (locked_buf != -1) { ReleaseSemaphore(&h->wh_Buffers[locked_buf].bn_Semaphore); locked_buf = -1; } if (switch_sig_bit != -1) { FreeSignal(switch_sig_bit); switch_sig_bit = -1; } if (ahi_control) { AHI_FreeAudio(ahi_control); /* Also unloads all sounds */ ahi_control = NULL; } if (ahi_request) { CloseDevice((struct IORequest*) ahi_request); DeleteIORequest((struct IORequest*) ahi_request); ahi_request = NULL; ahi_device = -1; } if (sample_bufs) { FreeVec(sample_bufs); sample_bufs = NULL; } if (ahi_port) { DeleteMsgPort(ahi_port); ahi_port = NULL; } }
void __asm __saveds SlaveTask(register __a2 struct AHIAudioCtrlDrv *AudioCtrl) // SlaveEntry() will set up register a2 and a6 for us. { struct EIGHTSVXheader EIGHTSVXheader = // All NULLs will be filled later. { ID_FORM, NULL, ID_8SVX, ID_VHDR, sizeof(Voice8Header), { NULL, 0, 0, NULL, 1, sCmpNone, 0x10000 }, ID_BODY, NULL }; struct AIFFheader AIFFheader = // All NULLs will be filled later. { ID_FORM, NULL, ID_AIFF, ID_COMM, sizeof(CommonChunk), { NULL, NULL, 16, { NULL } }, ID_SSND, NULL, { 0, 0 } }; struct AIFCheader AIFCheader = // All NULLs will be filled later. { ID_FORM, NULL, ID_AIFC, ID_FVER, sizeof(FormatVersionHeader), { AIFCVersion1 }, ID_COMM, sizeof(ExtCommonChunk), { NULL, NULL, 16, { NULL }, NO_COMPRESSION, sizeof("not compressed") - 1, 'n','o','t',' ','c','o','m','p','r','e','s','s','e','d' }, ID_SSND, NULL, { 0, 0 } }; struct STUDIO16FILE S16header = // All NULLs will be filled later. { S16FID, NULL, S16FINIT, S16_VOL_0, 0, 0, NULL, 0, 0, NULL, NULL, 0, NULL, 0, { 0 } }; struct EasyStruct req = { sizeof (struct EasyStruct), 0, _LibID, "Rendering finished.\nTo futher improve the quality of the sample,\n" "you can raise the volume to %ld%%%sand render again.", "OK", }; BPTR lock = NULL,cd = NULL,file = NULL, file2 = NULL; ULONG signals, i, maxVolume = 0, samplesAdd =0, samples = 0, length = 0; ULONG offset = 0, bytesInBuffer = 0, samplesWritten = 0, bytesWritten = 0; // We cannot handle stereo 8SVXs! if( (dd->fs_Format == FORMAT_8SVX) && (AudioCtrl->ahiac_Flags & AHIACF_STEREO) ) { goto quit; } if((dd->fs_DisableSignal = AllocSignal(-1)) == -1) { goto quit; } if((dd->fs_EnableSignal = AllocSignal(-1)) == -1) { goto quit; } if((dd->fs_SlaveSignal = AllocSignal(-1)) == -1) { goto quit; } if(!(lock = Lock(dd->fs_FileReq->fr_Drawer, ACCESS_READ))) { goto quit; } cd = CurrentDir(lock); switch(dd->fs_Format) { case FORMAT_8SVX: if(!(file = Open(dd->fs_FileReq->fr_File, MODE_NEWFILE))) goto quit; Write(file, &EIGHTSVXheader, sizeof EIGHTSVXheader); break; case FORMAT_AIFF: if(!(file = Open(dd->fs_FileReq->fr_File, MODE_NEWFILE))) goto quit; Write(file, &AIFFheader, sizeof AIFFheader); break; case FORMAT_AIFC: if(!(file = Open(dd->fs_FileReq->fr_File, MODE_NEWFILE))) goto quit; Write(file, &AIFCheader, sizeof AIFCheader); break; case FORMAT_S16: if (AudioCtrl->ahiac_Flags & AHIACF_STEREO) { char filename[256]; int len; strncpy (filename, dd->fs_FileReq->fr_File, sizeof(filename) - 3); len = strlen(filename); if(len >= 2 && filename[len - 2] == '_' && (filename[len - 1] == 'L' || filename[len - 1] == 'R')) { filename[len - 1] = 'L'; } else { strcat (filename, "_L"); } if(!(file = Open(filename, MODE_NEWFILE))) goto quit; filename[strlen(filename) - 1] = 'R'; if(!(file2 = Open(filename, MODE_NEWFILE))) goto quit; Write(file, &S16header, sizeof S16header); Write(file2, &S16header, sizeof S16header); } else { if(!(file = Open(dd->fs_FileReq->fr_File, MODE_NEWFILE))) goto quit; Write(file, &S16header, sizeof S16header); } break; } // Everything set up. Tell Master we're alive and healthy. Signal((struct Task *)dd->fs_MasterTask,1L<<dd->fs_MasterSignal); for(;;) { signals = SetSignal(0L,0L); if(signals & (SIGBREAKF_CTRL_C | 1L<<dd->fs_SlaveSignal)) { break; } if(signals & (1L<<dd->fs_EnableSignal | 1L<<dd->fs_DisableSignal) == 1L<<dd->fs_DisableSignal) { Wait(1L<<dd->fs_EnableSignal); } CallHookPkt(AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL); CallHookPkt(AudioCtrl->ahiac_MixerFunc, AudioCtrl, dd->fs_MixBuffer); samplesAdd = AudioCtrl->ahiac_BuffSamples; samples = samplesAdd; if(AudioCtrl->ahiac_Flags & AHIACF_STEREO) { samples <<= 1; } // Search for loudest part in sample if(AudioCtrl->ahiac_Flags & AHIACF_HIFI) { for(i = 0; i < samples; i++) if(abs(((LONG *)dd->fs_MixBuffer)[i]) > maxVolume) maxVolume = abs(((LONG *)dd->fs_MixBuffer)[i]); } else { for(i = 0; i< samples; i++) if(abs(((WORD *)dd->fs_MixBuffer)[i]) > maxVolume) maxVolume = abs(((WORD *)dd->fs_MixBuffer)[i]); } if((AudioCtrl->ahiac_Flags & AHIACF_STEREO) && dd->fs_Format == FORMAT_S16) { samples >>= 1; // Two buffers instead } if(offset+samples >= dd->fs_SaveBufferSize) { if(Write(file, dd->fs_SaveBuffer, bytesInBuffer) != bytesInBuffer) { break; } if(file2 != NULL) { if(Write(file2, dd->fs_SaveBuffer2, bytesInBuffer) != bytesInBuffer) { break; } } offset = 0; bytesInBuffer = 0; } switch(dd->fs_Format) { case FORMAT_8SVX: if(AudioCtrl->ahiac_Flags & AHIACF_HIFI) { BYTE *dest = &((BYTE *) dd->fs_SaveBuffer)[offset]; LONG *source = dd->fs_MixBuffer; for(i = 0; i < samples; i++) *dest++ = *source++ >> 24; } else {
ULONG __asm __saveds intAHIsub_AllocAudio( register __a1 struct TagItem *tagList, register __a2 struct AHIAudioCtrlDrv *AudioCtrl ) { char *ext = ""; if(AslBase == NULL) { return AHISF_ERROR; } if(AudioCtrl->ahiac_DriverData = AllocVec(sizeof(struct filesave),MEMF_CLEAR)) { dd->fs_AHIsubBase = AHIsubBase; dd->fs_DisableSignal = -1; dd->fs_EnableSignal = -1; dd->fs_SlaveSignal = -1; dd->fs_MasterSignal = AllocSignal(-1); dd->fs_MasterTask = (struct Process *) FindTask(NULL); dd->fs_RecSlaveSignal = -1; dd->fs_RecMasterSignal = AllocSignal(-1); } else { return AHISF_ERROR; } if((dd->fs_MasterSignal == -1) || (dd->fs_RecMasterSignal == -1)) { return AHISF_ERROR; } dd->fs_Format = GetTagData(AHIDB_FileSaveFormat, FORMAT_8SVX, tagList); switch(dd->fs_Format) { case FORMAT_8SVX: ext = ".8SVX"; break; case FORMAT_AIFF: ext = ".AIFF"; break; case FORMAT_AIFC: ext = ".AIFC"; break; case FORMAT_S16: break; default: break; } if(!(dd->fs_FileReq = AllocAslRequestTags(ASL_FileRequest, ASLFR_InitialFile, ext, ASLFR_DoSaveMode, TRUE, ASLFR_RejectIcons, TRUE, ASLFR_TitleText, _LibID, TAG_DONE))) { return AHISF_ERROR; } if(!(dd->fs_RecFileReq = AllocAslRequestTags(ASL_FileRequest, ASLFR_RejectIcons, TRUE, ASLFR_TitleText, "Select a sound sample", TAG_DONE))) { return AHISF_ERROR; } return AHISF_KNOWHIFI|AHISF_KNOWSTEREO|AHISF_CANRECORD|AHISF_MIXING|AHISF_TIMING; }
static void Slave( struct ExecBase* SysBase ) { struct AHIAudioCtrlDrv* AudioCtrl; struct DriverBase* AHIsubBase; struct DeviceBase* DeviceBase; BOOL running; ULONG signals; AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask( NULL )->tc_UserData; AHIsubBase = (struct DriverBase*) dd->ahisubbase; DeviceBase = (struct DeviceBase*) AHIsubBase; dd->slavesignal = AllocSignal( -1 ); if( dd->slavesignal != -1 ) { struct MsgPort* ahi_mp = NULL; struct AHIRequest* ahi_iorequest = NULL; APTR ahi_iocopy = NULL; BYTE ahi_device = -1; struct AHIRequest* ahi_io[ 2 ] = { NULL, NULL }; BOOL ahi_io_used[ 2 ] = { FALSE, FALSE }; ULONG frame_length = 0; ahi_mp = CreateMsgPort(); if( ahi_mp != NULL ) { ahi_iorequest = CreateIORequest( ahi_mp, sizeof( struct AHIRequest ) ); if( ahi_iorequest != NULL ) { ahi_iorequest->ahir_Version = 4; ahi_device = OpenDevice( AHINAME, dd->unit, (struct IORequest*) ahi_iorequest, 0 ); if( ahi_device == 0 ) { struct Library* AHIBase = (struct Library*) ahi_iorequest->ahir_Std.io_Device; ahi_iocopy = AllocVec( sizeof( *ahi_iorequest ), MEMF_ANY ); if( ahi_iocopy != NULL ) { bcopy( ahi_iorequest, ahi_iocopy, sizeof( *ahi_iorequest ) ); ahi_io[ 0 ] = ahi_iorequest; ahi_io[ 1 ] = ahi_iocopy; // Everything set up. Tell Master we're alive and healthy. Signal( (struct Task*) dd->mastertask, 1L << dd->mastersignal ); running = TRUE; // The main playback loop follow while( running ) { int skip_mix; APTR tmp_buff; struct AHIRequest* tmp_io; if( ahi_io_used[ 0 ] ) { LONG err; ULONG mask = ( SIGBREAKF_CTRL_C | (1L << dd->slavesignal) | (1L << ahi_mp->mp_SigBit) ); signals = Wait( mask ); if( signals & ( SIGBREAKF_CTRL_C | (1L << dd->slavesignal) ) ) { running = FALSE; break; } err = WaitIO( (struct IORequest*) ahi_io[ 0 ] ); if( err != 0 ) { KPrintF( DRIVER ": AHI device error %ld\n", err ); // running = FALSE; break; } } skip_mix = CallHookPkt( AudioCtrl->ahiac_PreTimerFunc, (Object*) AudioCtrl, 0 ); CallHookPkt( AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL ); if( ! skip_mix ) { CallHookPkt( AudioCtrl->ahiac_MixerFunc, AudioCtrl, dd->mixbuffers[ 0 ] ); } CallHookPkt( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 ); if( frame_length == 0 ) { frame_length = AHI_SampleFrameSize( AudioCtrl->ahiac_BuffType ); } ahi_io[ 0 ]->ahir_Std.io_Command = CMD_WRITE; ahi_io[ 0 ]->ahir_Std.io_Data = dd->mixbuffers[ 0 ]; ahi_io[ 0 ]->ahir_Std.io_Length = ( AudioCtrl->ahiac_BuffSamples * frame_length ); ahi_io[ 0 ]->ahir_Std.io_Offset = 0; ahi_io[ 0 ]->ahir_Frequency = AudioCtrl->ahiac_MixFreq; ahi_io[ 0 ]->ahir_Type = AudioCtrl->ahiac_BuffType; ahi_io[ 0 ]->ahir_Volume = 0x10000; ahi_io[ 0 ]->ahir_Position = 0x08000; ahi_io[ 0 ]->ahir_Link = ( ahi_io_used[ 1 ] ? ahi_io[ 1 ] : NULL ); SendIO( (struct IORequest*) ahi_io[ 0 ] ); tmp_io = ahi_io[ 0 ]; ahi_io[ 0 ] = ahi_io[ 1 ]; ahi_io[ 1 ] = tmp_io; tmp_buff = dd->mixbuffers[ 0 ]; dd->mixbuffers[ 0 ] = dd->mixbuffers[ 1 ]; dd->mixbuffers[ 1 ] = tmp_buff; ahi_io_used[ 0 ] = ahi_io_used[ 1 ]; ahi_io_used[ 1 ] = TRUE; } if( ahi_io_used[ 0 ] ) { AbortIO( (struct IORequest*) ahi_io[ 0 ] ); WaitIO( (struct IORequest*) ahi_io[ 0 ] ); } if( ahi_io_used[ 1 ] ) { AbortIO( (struct IORequest*) ahi_io[ 1 ] ); WaitIO( (struct IORequest*) ahi_io[ 1 ] ); } FreeVec( ahi_iocopy ); } CloseDevice( (struct IORequest*) ahi_iorequest ); } DeleteIORequest( (struct IORequest*) ahi_iorequest ); } DeleteMsgPort( ahi_mp ); } } FreeSignal( dd->slavesignal ); dd->slavesignal = -1; Forbid(); // Tell the Master we're dying Signal( (struct Task*) dd->mastertask, 1L << dd->mastersignal ); dd->slavetask = NULL; // Multitaking will resume when we are dead. }
ULONG _AHIsub_AllocAudio( struct TagItem *tagList, struct AHIAudioCtrlDrv *AudioCtrl, struct DriverBase* AHIsubBase ) { struct FilesaveBase* FilesaveBase = (struct FilesaveBase*) AHIsubBase; char *ext = ""; if(AslBase == NULL) { return AHISF_ERROR; } dd = AllocVec(sizeof(struct FilesaveData),MEMF_CLEAR); if( dd != NULL ) { dd->fs_AHIsubBase = AHIsubBase; dd->fs_SlaveSignal = -1; dd->fs_MasterSignal = AllocSignal(-1); dd->fs_MasterTask = (struct Process *) FindTask(NULL); dd->fs_RecSlaveSignal = -1; dd->fs_RecMasterSignal = AllocSignal(-1); } else { return AHISF_ERROR; } if((dd->fs_MasterSignal == -1) || (dd->fs_RecMasterSignal == -1)) { return AHISF_ERROR; } dd->fs_Format = GetTagData(AHIDB_FileSaveFormat, FORMAT_8SVX, tagList); switch(dd->fs_Format) { case FORMAT_8SVX: ext = ".8SVX"; break; case FORMAT_AIFF: ext = ".AIFF"; break; case FORMAT_AIFC: ext = ".AIFC"; break; case FORMAT_S16: break; case FORMAT_WAVE: ext = ".WAV"; break; default: break; } { struct TagItem playtags[] = { { ASLFR_InitialFile, (ULONG) ext }, { ASLFR_DoSaveMode, TRUE }, { ASLFR_RejectIcons, TRUE }, { ASLFR_TitleText, (ULONG) LibName }, { TAG_DONE, 0 } }; struct TagItem rectags[] = { { ASLFR_RejectIcons, TRUE }, { ASLFR_TitleText, (ULONG) "Select a sound sample" }, { TAG_DONE, 0 } }; if(!(dd->fs_FileReq = AllocAslRequest(ASL_FileRequest, playtags))) { return AHISF_ERROR; } if(!(dd->fs_RecFileReq = AllocAslRequest(ASL_FileRequest, rectags))) { return AHISF_ERROR; } } return AHISF_KNOWHIFI|AHISF_KNOWSTEREO|AHISF_CANRECORD|AHISF_MIXING|AHISF_TIMING; }
LONG launcher() { D(bug("launcher: Entered child launcher\n")); struct Task *this = FindTask(NULL); struct vfork_data *udata = this->tc_UserData; BYTE child_signal; struct Library *aroscbase = NULL; GetIntETask(this)->iet_startup = GetETask(this)->et_Result2 = AllocVec(sizeof(struct aros_startup), MEMF_ANY | MEMF_CLEAR); /* Allocate signal for parent->child communication */ child_signal = udata->child_signal = AllocSignal(-1); D(bug("launcher: Allocated child signal: %d\n", udata->child_signal)); if(udata->child_signal == -1) { /* Lie */ udata->child_errno = ENOMEM; Signal(udata->parent, 1 << udata->parent_signal); return -1; } if(__register_init_fdarray(udata->ppriv->acpd_fd_array, udata->ppriv->acpd_numslots)) aroscbase = OpenLibrary((STRPTR) "arosc.library", 0); if(!aroscbase) { FreeSignal(child_signal); udata->child_errno = ENOMEM; Signal(udata->parent, 1 << udata->parent_signal); return -1; } udata->cpriv = __get_arosc_privdata(); udata->cpriv->acpd_parent_does_upath = udata->ppriv->acpd_doupath; udata->cpriv->acpd_flags |= DO_NOT_CLONE_ENV_VARS; if(setjmp(__aros_startup_jmp_buf) == 0) { /* Setup complete, signal parent */ D(bug("launcher: Signaling parent that we finished setup\n")); Signal(udata->parent, 1 << udata->parent_signal); D(bug("launcher: Child waiting for exec or exit\n")); Wait(1 << udata->child_signal); if(udata->child_executed) { APTR exec_id; BPTR dir; D(bug("launcher: child executed\n")); /* Set current dir to parent's current dir */ dir = DupLock(((struct Process *)udata->parent)->pr_CurrentDir); UnLock(CurrentDir(dir)); /* Don't mind updating aroscbase->acb_startup_cd_changed as we will exit from process after __exec_do has finished */ /* Filenames passed from parent obey parent's __doupath */ __doupath = udata->cpriv->acpd_parent_does_upath; D(bug("launcher: __doupath == %d for __exec_prepare()\n", __doupath)); exec_id = udata->exec_id = __exec_prepare( udata->exec_filename, udata->exec_searchpath, udata->exec_argv, udata->exec_envp ); udata->child_errno = errno; /* Clear __doupath again, command will set it if wanted */ __doupath = 0; D(bug("launcher: informing parent that we have run __exec_prepare\n")); /* Inform parent that we have run __exec_prepare */ Signal(udata->parent, 1 << udata->parent_signal); /* Wait 'till __exec_do() is called on parent process */ D(bug("launcher: Waiting parent to get the result\n")); Wait(1 << udata->child_signal); D(bug("launcher: informing parent that we won't use udata anymore\n")); /* Inform parent that we won't use udata anymore */ Signal(udata->parent, 1 << udata->parent_signal); if (exec_id) { D(bug("launcher: executing command\n")); __exec_do(exec_id); assert(0); /* Should not be reached */ } else { D(bug("launcher: exit because execve returned with an error\n")); _exit(0); } } else { D(bug("launcher: informing parent that we won't use udata anymore\n")); /* Inform parent that we won't use udata anymore */ Signal(udata->parent, 1 << udata->parent_signal); } } else { D(bug("launcher: freeing child_signal\n")); FreeSignal(child_signal); CloseLibrary(aroscbase); } return 0; }
pid_t __vfork(jmp_buf env) { struct Task *this = FindTask(NULL); struct vfork_data *udata = AllocMem(sizeof(struct vfork_data), MEMF_ANY | MEMF_CLEAR); if(udata == NULL) { errno = ENOMEM; longjmp(env, -1); } D(bug("__vfork: allocated udata %p\n", udata)); bcopy(env, &udata->vfork_jump, sizeof(jmp_buf)); struct TagItem tags[] = { { NP_Entry, (IPTR) launcher }, { NP_CloseInput, (IPTR) FALSE }, { NP_CloseOutput, (IPTR) FALSE }, { NP_CloseError, (IPTR) FALSE }, { NP_Cli, (IPTR) TRUE }, { NP_Name, (IPTR) "vfork()" }, { NP_UserData, (IPTR) udata }, { NP_NotifyOnDeath, (IPTR) TRUE }, { TAG_DONE, 0 } }; udata->parent = this; struct arosc_privdata *ppriv = __get_arosc_privdata(); udata->ppriv = ppriv; /* Store parent's vfork_data to restore it later */ udata->prev = __get_arosc_privdata()->acpd_vfork_data; D(bug("__vfork: Saved old parent's vfork_data: %p\n", udata->prev)); D(bug("__vfork: backuping startup buffer\n")); /* Backup startup buffer */ CopyMem(&__aros_startup_jmp_buf, &udata->startup_jmp_buf, sizeof(jmp_buf)); D(bug("__vfork: Allocating parent signal\n")); /* Allocate signal for child->parent communication */ udata->parent_signal = AllocSignal(-1); if(udata->parent_signal == -1) { /* Couldn't allocate the signal, return -1 */ FreeMem(udata, sizeof(struct vfork_data)); errno = ENOMEM; longjmp(udata->vfork_jump, -1); } D(bug("__vfork: Creating child\n")); udata->child = (struct Task*) CreateNewProc(tags); if(udata->child == NULL) { /* Something went wrong, return -1 */ FreeMem(udata, sizeof(struct vfork_data)); errno = ENOMEM; /* Most likely */ longjmp(env, -1); } D(bug("__vfork: Child created %p, waiting to finish setup\n", udata->child)); udata->child_id = GetETaskID(udata->child); D(bug("__vfork: Got unique child id: %d\n", udata->child_id)); /* Wait for child to finish setup */ Wait(1 << udata->parent_signal); if(udata->child_errno) { /* An error occured during child setup */ errno = udata->child_errno; longjmp(env, -1); } D(bug("__vfork: Setting jmp_buf at %p in %p\n", __aros_startup, &__aros_startup_jmp_buf)); if(setjmp(__aros_startup_jmp_buf)) { D(bug("__vfork: child exited\n or executed\n")); if(!GETUDATA->child_executed) { D(bug("__vfork: not executed\n")); ((struct aros_startup*) GetIntETask(GETUDATA->child)->iet_startup)->as_startup_error = __aros_startup_error; D(bug("__vfork: Signaling child\n")); Signal(GETUDATA->child, 1 << GETUDATA->child_signal); } D(bug("__vfork: Waiting for child to finish using udata\n")); /* Wait for child to finish using GETUDATA */ Wait(1 << GETUDATA->parent_signal); D(bug("__vfork: fflushing\n")); fflush(NULL); D(bug("__vfork: restoring old fd_array\n")); /* Restore parent's old fd_array */ ((struct arosc_privdata *) GetIntETask(GETUDATA->parent)->iet_acpd)->acpd_fd_mempool = GETUDATA->parent_acpd_fd_mempool; ((struct arosc_privdata *) GetIntETask(GETUDATA->parent)->iet_acpd)->acpd_numslots = GETUDATA->parent_acpd_numslots; ((struct arosc_privdata *) GetIntETask(GETUDATA->parent)->iet_acpd)->acpd_fd_array = GETUDATA->parent_acpd_fd_array; D(bug("__vfork: restoring startup buffer\n")); /* Restore parent startup buffer */ CopyMem(&GETUDATA->startup_jmp_buf, &__aros_startup_jmp_buf, sizeof(jmp_buf)); D(bug("__vfork: freeing parent signal\n")); FreeSignal(GETUDATA->parent_signal); errno = GETUDATA->child_errno; FreeAndJump(GETUDATA); assert(0); /* not reached */ return (pid_t) 1; } /* Remember parent fd descriptor table */ udata->parent_acpd_fd_mempool = ppriv->acpd_fd_mempool; udata->parent_acpd_numslots = ppriv->acpd_numslots; udata->parent_acpd_fd_array = ppriv->acpd_fd_array; /* Pretend to be running as the child created by vfork */ ppriv->acpd_vfork_data = udata; ppriv->acpd_flags |= PRETEND_CHILD; ppriv->acpd_fd_mempool = udata->cpriv->acpd_fd_mempool; ppriv->acpd_numslots = udata->cpriv->acpd_numslots; ppriv->acpd_fd_array = udata->cpriv->acpd_fd_array; D(bug("__vfork: Jumping to jmp_buf %p\n", &udata->vfork_jump)); D(bug("__vfork: ip: %p, stack: %p\n", udata->vfork_jump[0].retaddr, udata->vfork_jump[0].regs[_JMPLEN - 1])); vfork_longjmp(udata->vfork_jump, 0); assert(0); /* not reached */ return (pid_t) 0; }
// USER int emulator::setUpEmulator() { DEBUG(3) dprintf("emulator::setUpEmulator() called. this=%p\n", this); int retc; // Internal module int_module = new internal_module(); if(!int_module) return ENOMEM; retc = int_module->init(); if(retc) return retc; // Exec module exec_module = new exec::main(); if(!exec_module) return ENOMEM; retc = exec_module->init(); if(retc) return retc; // Dos module dos_module = new dos::main(); if(!dos_module) return ENOMEM; retc = dos_module->init(); if(retc) return retc; // Bootstrap bootstrap_mapping = new rom_mapping(sizeof(bootstrap_data), bootstrap_data); if(!bootstrap_mapping) return ENOMEM; if(v_space.add_mapping(bootstrap_mapping) == 0xFFFFFFFF) return ENOMEM; // Spawn emulation process char this_hex[17]; sprintf(this_hex, "%p", this); // Set environment variable with "this" pointer. // It is inherited by the new process if(!SetVar("EMUMIGA_CREATOR", this_hex, -1, GVF_LOCAL_ONLY)) return ENOMEM; creatorProc = (struct Process *)FindTask(0); creatorSigNo = AllocSignal(-1); if(creatorSigNo == -1) return ENOMEM; SetSignal(0, 1 << creatorSigNo); struct TagItem tags[] = { { NP_Entry, (IPTR)processEntry }, { TAG_DONE, 0 } }; struct Process *new_proc = CreateNewProcTagList(tags); if(!new_proc) { FreeSignal(creatorSigNo); return ENOMEM; } Wait(1 << creatorSigNo); FreeSignal(creatorSigNo); DeleteVar("EMUMIGA_CREATOR", GVF_LOCAL_ONLY); return 0; }
// Create a global memory pool and GUI structure void startup_init_gui() { short a,proc=0; // Create a global memory pool and GUI structure if (!(global_memory_pool=NewMemHandle(1024,512,MEMF_CLEAR|MEMF_PUBLIC)) || !(GUI=AllocMemH(global_memory_pool,sizeof(GUI_Glue))) || !(GUI->screen_title=AllocMemH(global_memory_pool,256)) || !(GUI->filter_string=AllocMemH(global_memory_pool,256))) quit(0); // Initialise lists InitListLock(&GUI->lister_list,0); InitListLock(&GUI->buffer_list,0); InitListLock(&GUI->buttons_list,0); InitListLock(&GUI->process_list,0); InitListLock(&GUI->group_list,0); InitListLock(&GUI->filetypes,0); InitListLock(&GUI->notify_process_list,0); InitListLock(&GUI->function_traps,0); InitListLock(&GUI->positions,0); InitListLock(&GUI->rexx_readers,0); InitListLock(&GUI->function_list,0); InitListLock(&GUI->rexx_apps,0); InitListLock(&GUI->command_list,0); #ifdef __AROS__ GUI->command_list.list.lh_Type = 255; // requires special handling #endif InitListLock(&GUI->original_cmd_list,0); InitListLock(&GUI->modules_list,0); InitListLock(&GUI->popupext_list,0); InitListLock(&GUI->iconpos_list,0); InitListLock(&GUI->startmenu_list,0); InitListLock(&GUI->open_with_list,0); GUI->command_history=Att_NewList(LISTF_POOL|LISTF_LOCK); // Initialise locks InitSemaphore(&GUI->select_lock); InitSemaphore(&GUI->req_lock); InitSemaphore(&GUI->lister_menu_lock); InitSemaphore(&GUI->hotkeys_lock); InitSemaphore(&GUI->findfile_lock); InitSemaphore(&GUI->filter_lock); InitSemaphore(&GUI->scripts_lock); InitSemaphore(&GUI->user_menu_lock); InitSemaphore(&GUI->custom_pen_lock); // Signal for getting screen close GUI->screen_signal=AllocSignal(-1); // This pointer is cleared by the registration module; big crashes if that doesn't happen #if 0 GUI->screen=(struct Screen *)1; #endif GUI->def_filename_length=FILENAME_LEN; // Initialise filter string strcpy(GUI->filter_string,"#?"); // Initial requester coordinates GUI->req_coords.Left=64; GUI->req_coords.Top=32; GUI->req_coords.Width=320; GUI->req_coords.Height=200; // Initialise selection data GUI->select_data.type=SELECT_SIMPLE; GUI->select_data.entry_type=SELECT_ENTRY_BOTH; strcpy(GUI->select_data.name,"*"); GUI->select_data.name_match=SELECT_MATCH_MATCH; GUI->select_data.date_from[0]=0; GUI->select_data.date_to[0]=0; GUI->select_data.date_match=SELECT_MATCH_IGNORE; GUI->select_data.bits=0; GUI->select_data.bits_match=SELECT_MATCH_IGNORE; GUI->select_data.compare=0; GUI->select_data.compare_match=SELECT_MATCH_IGNORE; GUI->select_data.include=SELECT_INCLUDE; // Get decimal separator GUI->decimal_sep=(locale.li_Locale)?locale.li_Locale->loc_GroupSeparator[0]:','; // Locale patches installed? if (locale.li_LocaleBase && ((struct LocaleBase *)locale.li_LocaleBase)->lb_SysPatches) GUI->flags|=GUIF_LOCALE_OK; // Calculate width of date field if (locale.li_LocaleBase) { char *str; short day,len; #define LocaleBase locale.li_LocaleBase // Get lengths of days of the week for (day=DAY_1; day<=DAY_7; day++) { if ((str=(char *)GetLocaleStr(locale.li_Locale,day)) && (len=strlen(str))>GUI->date_length) GUI->date_length=len; } // Yesterday, etc for (day=YESTERDAYSTR; day<=FUTURESTR; day++) { if ((str=(char *)GetLocaleStr(locale.li_Locale,day)) && (len=strlen(str))>GUI->date_length) GUI->date_length=len; } } // Otherwise, use default (Yesterday) else GUI->date_length=9; // See if SysIHack is running if (FindTask("« sysihack »")) GUI->flags|=GUIF_SYSIHACK; // Allocate a string for spaces, and the global undo buffer if (!(str_space_string=AllocMemH(global_memory_pool,MAXDISPLAYLENGTH)) || !(GUI->global_undo_buffer=AllocMemH(global_memory_pool,1024))) quit(0); for (a=0; a<MAXDISPLAYLENGTH-1; a++) str_space_string[a]=' '; // Allocate backdrop patterns if (!(GUI->pattern=AllocMemH(global_memory_pool,sizeof(PatternData)*3))) quit(0); // Initialise requester pattern #if defined(__MORPHOS__) GUI->req_pattern.hook.h_Entry = (HOOKFUNC)HookEntry; GUI->req_pattern.hook.h_SubEntry=(ULONG (*)())PatternBackfill; #else GUI->req_pattern.hook.h_Entry=(ULONG (*)())PatternBackfill; #endif GUI->req_pattern.hook.h_Data=0; GUI->req_pattern.pattern=&GUI->pattern[PATTERN_REQ]; GUI->req_pattern.disabled=FALSE; // Set requester pattern hook in library SetReqBackFill(&GUI->req_pattern.hook,&GUI->screen_pointer); GUI->flags2|=GUIF2_BACKFILL_SET; // Build kickstart version string if (GetVar("Kickstart",GUI->ver_kickstart,15,GVF_GLOBAL_ONLY)<1) { char *ptr3; ULONG ptr,*ptr2; UWORD ver,rev; #ifdef __AROS__ ver = ((struct Library *)SysBase)->lib_Version; rev = ((struct Library *)SysBase)->lib_Revision; #else ptr2=(ULONG *)0xffffec; ptr=0x1000000-(*ptr2); ptr3=(char *)ptr+12; ptr2=(ULONG *)ptr3; ptr=*ptr2; ver=ptr>>16; rev=ptr&(((1<<32)-(1<<16))-1); #endif lsprintf(GUI->ver_kickstart,"%ld.%ld",ver,rev); }
void RecSlaveEntry(void) { struct AHIAudioCtrlDrv* AudioCtrl; struct DriverBase* AHIsubBase; struct FilesaveBase* FilesaveBase; ULONG signals; BPTR lock = NULL,cd=0,file = NULL; Object *o = NULL; BYTE *samples = NULL; ULONG length = NULL; ULONG count = 0,offs = 0,i; struct AHIRecordMessage RecordMessage = { AHIST_S16S, NULL, RECBUFFERSIZE }; AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask( NULL )->tc_UserData; AHIsubBase = (struct DriverBase*) dd->fs_AHIsubBase; FilesaveBase = (struct FilesaveBase*) AHIsubBase; RecordMessage.ahirm_Buffer = dd->fs_RecBuffer; if(!(lock = Lock(dd->fs_RecFileReq->fr_Drawer,ACCESS_READ))) goto quit; cd = CurrentDir(lock); if(DataTypesBase) { struct TagItem newtags[] = { { DTA_GroupID, GID_SOUND }, { TAG_DONE, 0 } }; struct TagItem attrtags[] = { { SDTA_Sample, (ULONG) &samples }, { SDTA_SampleLength, (ULONG) &length }, { TAG_DONE, 0 } }; if (!(o = NewDTObjectA (dd->fs_RecFileReq->fr_File, newtags))) goto quit; GetDTAttrsA(o, attrtags ); } else // datatypes.library not open. Open the selected file as raw 8 bit signed instead. { if(!(file = Open(dd->fs_RecFileReq->fr_File,MODE_OLDFILE))) goto quit; Seek(file,0,OFFSET_END); length = Seek(file,0,OFFSET_BEGINNING); if(!(samples = AllocVec(length,MEMF_ANY))) goto quit; if(length != (ULONG) Read(file,samples,length)) goto quit; } if(!samples || !length ) goto quit; if((dd->fs_RecSlaveSignal = AllocSignal(-1)) == -1) goto quit; // Everything set up. Tell Master we're alive and healthy. Signal((struct Task *)dd->fs_MasterTask,1L<<dd->fs_RecMasterSignal); for(;;) { signals = SetSignal(0L,0L); if(signals & (SIGBREAKF_CTRL_C | 1L<<dd->fs_RecSlaveSignal)) break; for(;;) { if(count+RECBUFFERSIZE-offs < length) { // End of sample will not be reached; just fill to the end of dd->fs_RecBuffer. for(i = RECBUFFERSIZE-offs;i>0;i--) { dd->fs_RecBuffer[(offs)<<1] = dd->fs_RecBuffer[((offs++)<<1)+1] = samples[count++]<<8; } offs = 0; break; } else { // End of sample will be reached. Fill part of buffer, and iterate (== don't break). for(i = length-count;i>0;i--) { dd->fs_RecBuffer[(offs)<<1] = dd->fs_RecBuffer[((offs++)<<1)+1] = samples[count++]<<8; } count = 0; } } CallHookPkt(AudioCtrl->ahiac_SamplerFunc,AudioCtrl,&RecordMessage); Delay(50*RECBUFFERSIZE/AudioCtrl->ahiac_MixFreq); } quit: // Get rid of object if(DataTypesBase) { if(o) DisposeDTObject (o); } else // datatypes.library not open. { if(samples) FreeVec(samples); if(file) Close(file); } CurrentDir(cd); if(lock) UnLock(lock); Forbid(); dd->fs_RecSlaveTask = NULL; FreeSignal(dd->fs_RecSlaveSignal); dd->fs_RecSlaveSignal = -1; // Tell the Master we're dying Signal((struct Task *)dd->fs_MasterTask,1L<<dd->fs_RecMasterSignal); // Multitaking will resume when we are dead. }
SAVEDS void CamdTimerProc(void){ struct timerequest *TimerIO; struct MsgPort *TimerMP; ULONG sig; int error; D(bug("camdtimerproc1\n")); camdwaitsig=AllocSignal(-1); if(camdwaitsig==-1){ camdwaitprocstatus=2; return; } D(bug("camdtimerproc2\n")); camdwaitsig2=AllocSignal(-1); if(camdwaitsig2==-1){ FreeSignal(1L<<camdwaitsig); camdwaitprocstatus=2; return; } D(bug("camdtimerproc3\n")); TimerMP=CreateMsgPort(); if(TimerMP==NULL){ FreeSignal(1L<<camdwaitsig2); FreeSignal(1L<<camdwaitsig); camdwaitprocstatus=2; return; } D(bug("camdtimerproc4\n")); TimerIO=(struct timerequest *)AllocMem(sizeof(struct timerequest),MEMF_ANY|MEMF_CLEAR|MEMF_PUBLIC); D(bug("camdtimerproc5\n")); if(TimerIO==NULL){ FreeSignal(1L<<camdwaitsig2); FreeSignal(1L<<camdwaitsig); DeleteMsgPort(TimerMP); camdwaitprocstatus=2; return; } D(bug("camdtimerproc6\n")); TimerIO->tr_node.io_Message.mn_Node.ln_Type=NT_MESSAGE; TimerIO->tr_node.io_Message.mn_ReplyPort=TimerMP; TimerIO->tr_node.io_Message.mn_Length=sizeof(struct timerequest); /* No support for eclock in AROS. */ #ifndef _AROS if((error=OpenDevice( TIMERNAME,UNIT_ECLOCK,(struct IORequest *)TimerIO,0L ))!=0){ #else D(bug("camdtimerproc7\n")); if((error=OpenDevice( TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimerIO,0L ))!=0){ #endif D(bug("camdtimerproc7.1\n")); FreeSignal(1L<<camdwaitsig2); FreeSignal(1L<<camdwaitsig); TimerIO->tr_node.io_Message.mn_Node.ln_Type=(UBYTE)-1; TimerIO->tr_node.io_Device=(struct Device *)-1L; TimerIO->tr_node.io_Unit=(struct Unit *)-1L; FreeMem(TimerIO,sizeof(struct timerequest)); DeleteMsgPort(TimerMP); D(bug("failed camdtimerproc11, error: %ld\n",error)); camdwaitprocstatus=2; return; } D(bug("camdtimerproc8\n")); ObtainSemaphore(&camdwaitsemaphore); D(bug("camdtimerproc9\n")); camdwaittask=FindTask(0L); camdwaitprocstatus=1; for(;;){ sig=Wait( 1L<<camdwaitsig | SIGBREAKF_CTRL_C ); if(sig&SIGBREAKF_CTRL_C) break; if(sig & 1L<<camdwaitsig){ // Someone wants to obtain the semaphore? TimerIO->tr_node.io_Command=TR_ADDREQUEST; TimerIO->tr_time.tv_secs=0; TimerIO->tr_time.tv_micro=10; DoIO((struct IORequest *)TimerIO); // ..Better let them wait. ReleaseSemaphore(&camdwaitsemaphore); // Well, okey then. Wait(1L<<camdwaitsig2); // Finished soon? ObtainSemaphore(&camdwaitsemaphore); // But I want it back! } } ReleaseSemaphore(&camdwaitsemaphore); FreeSignal(1L<<camdwaitsig2); FreeSignal(1L<<camdwaitsig); CloseDevice((struct IORequest *)TimerIO); TimerIO->tr_node.io_Message.mn_Node.ln_Type=(UBYTE)-1; TimerIO->tr_node.io_Device=(struct Device *)-1L; TimerIO->tr_node.io_Unit=(struct Unit *)-1L; FreeMem(TimerIO,sizeof(struct timerequest)); DeleteMsgPort(TimerMP); camdwaitprocstatus=3; return; } BOOL InitCamdTimer(void){ struct Process *process; InitSemaphore(&camdwaitsemaphore); InitSemaphore(&camdwaitsemaphore2); process=CreateNewProcTags( NP_Entry,CamdTimerProc, NP_Name,"Camd Wait Proc", NP_Priority,5, TAG_END ); if(process==NULL) return FALSE; D(bug("4.7\n")); while(camdwaitprocstatus==0) Delay(1); D(bug("4.8\n")); if(camdwaitprocstatus==2) return FALSE; return TRUE; } void UninitCamdTimer(void){ if(camdwaitprocstatus==2) return; Signal(camdwaittask,SIGBREAKF_CTRL_C); while(camdwaitprocstatus!=3) Delay(1); } /* * When a hardware-sender buffer is full, or we are sending a sysex-message * to hardware, we need to wait for small amounts of time. That is what * this function tries to do. * */ void CamdWait(void){ static BOOL iswaiting=FALSE; BOOL imjustgoingtoreturnsoon=iswaiting; ObtainSemaphore(&camdwaitsemaphore2); if(imjustgoingtoreturnsoon==TRUE){ // No big point having more than one visitor to wait. ReleaseSemaphore(&camdwaitsemaphore2); return; } iswaiting=TRUE; Signal(camdwaittask,1L<<camdwaitsig); // Give me the semaphore! ObtainSemaphore(&camdwaitsemaphore); // This should take some time. Signal(camdwaittask,1L<<camdwaitsig2); // Okey, I've got it. ReleaseSemaphore(&camdwaitsemaphore); // You're welcome. iswaiting=FALSE; ReleaseSemaphore(&camdwaitsemaphore2); return; }
// Initialise a new lister IPC_StartupCode(lister_init, Lister *, lister, static) { // Store IPC and lister pointers lister->ipc=ipc; ipc->userdata=lister; // Store IPC pointer in backdrop info lister->backdrop_info->ipc=ipc; // Path history list lister->path_history=Att_NewList(LISTF_LOCK); // Initialise reselection InitReselect(&lister->reselect); lister->abort_signal=-1; // Create message ports and signals if (!(lister->app_port=CreateMsgPort()) || !(lister->timer_port=CreateMsgPort()) || (lister->hot_name_bit=AllocSignal(-1))==-1 || (lister->abort_signal=AllocSignal(-1))==-1) return 0; // Allocate some timers if (!(lister->busy_timer=AllocTimer(UNIT_VBLANK,lister->timer_port)) || !(lister->scroll_timer=AllocTimer(UNIT_VBLANK,lister->timer_port)) || !(lister->edit_timer=AllocTimer(UNIT_VBLANK,lister->timer_port)) || !(lister->foo_timer=AllocTimer(UNIT_VBLANK,lister->timer_port))) return 0; StartTimer(lister->foo_timer,5,0); // Create regions if (!(lister->title_region=NewRegion()) || !(lister->refresh_extra=NewRegion())) return 0; // Lock buffer list lock_listlock(&GUI->buffer_list,TRUE); // Allocate initial buffer if (!(lister->cur_buffer=lister_get_empty_buffer()) && !(lister->cur_buffer=lister_new_buffer(lister))) return 0; lister->cur_buffer->buf_CurrentLister=lister; // Unlock buffer list unlock_listlock(&GUI->buffer_list); // Allocate "special" buffer if (!(lister->special_buffer=buffer_new())) return 0; // Build popup menu lister_build_menu(lister); // Initialise flags lister->flags|=LISTERF_FIRST_TIME; lister->flags2|=LISTERF2_UNAVAILABLE; lister->tool_sel=-1; lister->toolbar_offset=0; // Fix priority lister->normal_pri=environment->env->settings.pri_lister[0]; lister->busy_pri=environment->env->settings.pri_lister[1]; SetTaskPri((struct Task *)lister->ipc->proc,lister->normal_pri); // Get font to use lister->lister_font.ta_Name=lister->font_name; lister->lister_font.ta_YSize=lister->font_size; lister->lister_font.ta_Flags=0; lister->lister_font.ta_Style=0; // Open font if ((lister->font=OpenDiskFont(&lister->lister_font))) { // Proportional font? if (lister->font->tf_Flags&FPF_PROPORTIONAL) lister->more_flags|=LISTERF_PROP_FONT; // Set font in text area InitRastPort(&lister->text_area.rast); SetFont(&lister->text_area.rast,lister->font); } return 1; }
static void Slave( struct ExecBase* SysBase ) { struct AHIAudioCtrlDrv* AudioCtrl; struct DriverBase* AHIsubBase; struct AROSBase* AROSBase; BOOL running; ULONG signals; int bytes_in_buffer = 0; int offset_in_buffer = 0; AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask( NULL )->tc_UserData; AHIsubBase = (struct DriverBase*) dd->ahisubbase; AROSBase = (struct AROSBase*) AHIsubBase; dd->slavesignal = AllocSignal( -1 ); if( dd->slavesignal != -1 ) { // Everything set up. Tell Master we're alive and healthy. Signal( (struct Task*) dd->mastertask, 1L << dd->mastersignal ); running = TRUE; // The main playback loop follow while( running ) { signals = SetSignal(0L,0L); // KPrintF("++++ arosdriver_after signal checking\n"); if( signals & ( SIGBREAKF_CTRL_C | (1L << dd->slavesignal) ) ) { running = FALSE; } else { int skip_mix; int bytes_avail; // First Delay() until there is at least one fragment free while( TRUE ) { int frag_avail, frag_alloc, frag_size; OSS_GetOutputInfo( &frag_avail, &frag_alloc, &frag_size, &bytes_avail ); // KPrintF( "%ld fragments available, %ld alloced (%ld bytes each). %ld bytes total\n", frag_avail, frag_alloc, frag_size, bytes_avail ); if( frag_avail == 0 ) { // This is actually quite a bit too long delay :-( For // comparison, the SB Live/Audigy driver uses 1/1000 s // polling ... // KPrintF("Delay\n"); #if USE_TIMERTICK SmallDelay(SysBase); #else Delay( 1 ); #endif } else { break; } } skip_mix = 0;/*CallHookA( AudioCtrl->ahiac_PreTimerFunc, (Object*) AudioCtrl, 0 );*/ while( bytes_avail > 0 ) { // KPrintF( "%ld bytes in current buffer.\n", bytes_in_buffer ); if( bytes_in_buffer == 0 ) { int skip = 0; int offset = 0; int samples = 0; int bytes = 0; int i; WORD* src; WORD* dst; CallHookPkt( AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL ); samples = AudioCtrl->ahiac_BuffSamples; bytes = samples * 2; // one 16 bit sample is 2 bytes switch( AudioCtrl->ahiac_BuffType ) { case AHIST_M16S: skip = 1; offset = 0; break; case AHIST_M32S: skip = 2; offset = 1; break; case AHIST_S16S: skip = 1; offset = 0; samples *= 2; bytes *= 2; break; case AHIST_S32S: skip = 2; offset = 1; samples *= 2; bytes *= 2; break; } bytes_in_buffer = bytes; offset_in_buffer = 0; if( ! skip_mix ) { CallHookPkt( AudioCtrl->ahiac_MixerFunc, AudioCtrl, dd->mixbuffer ); } src = ((WORD*) dd->mixbuffer) + offset; dst = dd->mixbuffer; for( i = 0; i < samples; ++i ) { *dst++ = *src; src += skip; } // KPrintF( "Mixed %ld/%ld new bytes/samples\n", bytes, samples ); } while( bytes_in_buffer > 0 && bytes_avail > 0 ) { int written; int counter = 0; do { written = OSS_Write( dd->mixbuffer + offset_in_buffer, min( bytes_in_buffer, bytes_avail ) ); if (counter > 10) { if (written < 0) written = 0; break; } if (written < 0) KPrintF("OSS_Write returned %ld. counter %ld bytes_in_buffer %ld bytes_avail %ld\n", written, counter, bytes_in_buffer, bytes_avail); counter++; } while (written < 0); bytes_in_buffer -= written; offset_in_buffer += written; bytes_avail -= written; // KPrintF( "Wrote %ld bytes (%ld bytes in buffer, offset=%ld, %ld bytes available in OSS buffers\n", // written, bytes_in_buffer, offset_in_buffer, bytes_avail ); } } CallHookA( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 ); } } } FreeSignal( dd->slavesignal ); dd->slavesignal = -1; Forbid(); // Tell the Master we're dying Signal( (struct Task*) dd->mastertask, 1L << dd->mastersignal ); dd->slavetask = NULL; // Multitaking will resume when we are dead. }
int par_init(UBYTE useCRC) { int result = PAR_INIT_OK; /* allocate signal for interrupt */ intSig = AllocSignal(-1); if(intSig == -1) { return PAR_INIT_NO_SIGNAL; } alloc_flags |= 8; /* setup state structure */ state.s_Flags = 0; state.s_IntSigMask = 1UL << intSig; state.s_SysBase = SysBase; state.s_ServerTask = FindTask(NULL); state.s_UseCRC = useCRC; /* register our time out flag */ timer_timeout_set_flag_ptr(&state.s_TimeOut); if (MiscBase = OpenResource("misc.resource")) { if (cia_base = OpenResource("ciaa.resource")) { /* obtain exclusive access to the parallel hardware */ if (!AllocMiscResource(MR_PARALLELPORT, name)) { alloc_flags |= 1; if (!AllocMiscResource(MR_PARALLELBITS, name)) { BOOL ok = FALSE; alloc_flags |= 2; /* allocate irq */ irq.is_Node.ln_Type = NT_INTERRUPT; irq.is_Node.ln_Pri = 127; irq.is_Node.ln_Name = name; irq.is_Data = (APTR)&state; irq.is_Code = (VOID (*)())&interrupt; Disable(); /* add an interrupt handler for FLAG = ACK */ if (!AddICRVector(cia_base, CIAICRB_FLG, &irq)) { DISABLEINT; ok = TRUE; } Enable(); /* finish setting up interrupt handler */ if (ok) { alloc_flags |= 4; /* setup line */ PARINIT; CLEARREQUEST; /* irq setup */ CLEARINT; ENABLEINT; } else { result = PAR_INIT_NO_CIA_IRQ; } } else { result = PAR_INIT_NO_PARBITS_RES; } } else { result = PAR_INIT_NO_PARPORT_RES; } } } return result; }
/************* * FUNCTION: SendRexxMsg * VERSION: 0.1 08.03.1995 * DESCRIPTION: Sends a single (or a list of) command(s) to Rexx host * and returns the secondary result * INPUT: HostName name of host * MsgList messagelist (SingleMsg must be NULL) * SingleMsg single message (MsgList must be NULL) * GetResult TRUE: get results * OUTPUT: secondary result * HISTORY: DATE NAME COMMENT * 08.03.95 ah first release *************/ ULONG SendRexxMsg(STRPTR HostName,STRPTR *MsgList,STRPTR SingleMsg,LONG GetResult) { struct RexxMsg *RexxMessage; struct MsgPort *HostPort,*ReplyPort; ULONG Result = 0; SHORT i; /* Valid pointers given? */ if(HostName && (MsgList || SingleMsg)) { /* Can we find the host? */ HostPort = (struct MsgPort *)FindPort((char *)HostName); if(HostPort) { /* Allocate a reply port. */ ReplyPort = (struct MsgPort *)AllocMem(sizeof(struct MsgPort),MEMF_PUBLIC | MEMF_CLEAR); if(ReplyPort) { ReplyPort->mp_SigBit = AllocSignal(-1); if(ReplyPort->mp_SigBit != -1) { ReplyPort->mp_Node.ln_Type = NT_MSGPORT; ReplyPort->mp_Flags = PA_SIGNAL; ReplyPort->mp_SigTask = FindTask(NULL); ReplyPort->mp_MsgList.lh_Head = (struct Node *)&ReplyPort->mp_MsgList.lh_Tail; ReplyPort->mp_MsgList.lh_Tail = 0; ReplyPort->mp_MsgList.lh_TailPred = (struct Node *)&ReplyPort->mp_MsgList.lh_Head; /* Create a Rexx message. */ RexxMessage = (struct RexxMsg *)CreateRexxMsg(ReplyPort,"",(char *)HostName); if(RexxMessage) { /* A list of arguments or only a single arg? */ if(MsgList) { for(i=0 ; i<16 ; i++) RexxMessage->rm_Args[i] = MsgList[i]; } else RexxMessage->rm_Args[0] = SingleMsg; /* Do we want result codes? */ if(GetResult) RexxMessage->rm_Action = RXFF_RESULT; /* Send packet and wait for the reply. */ PutMsg(HostPort,(struct Message *)RexxMessage); WaitPort(ReplyPort); /* Remember result. */ if(GetResult && !RexxMessage->rm_Result1) Result = RexxMessage->rm_Result2; /* Remove Rexx message. */ DeleteRexxMsg(RexxMessage); } /* Free reply port signal bit. */ FreeSignal(ReplyPort->mp_SigBit); } /* Free the replyport itself. */ FreeMem(ReplyPort,sizeof(struct MsgPort)); } } } /* Return the result. */ return(Result); }
int main(int argc, char **argv) { struct IntuitionBase *ibase; struct InputEvent *iev; struct IOStdReq *ioreq = 0; struct MsgPort *port; struct timerequest *timereq = 0; struct MsgPort *timeport; int oldx = 0, oldy = 0; int i; i = (*calltrap) (0); if (i == 0) { fprintf(stderr, "mousehack not needed for this version of UAE.\n"); exit (0); } if (i == -1) { fprintf(stderr, "mousehack already running.\n"); exit (5); } i = AllocSignal (-1); if (i < 0) goto fail; foo.sigbit = 1 << i; port = CreatePort(0, 0); timeport = CreatePort (0, 0); if (port) ioreq = CreateStdIO(port); if (timeport) timereq = CreateStdIO(timeport); if (ioreq == 0) goto fail; if (timereq == 0) goto fail; iev = AllocMem (sizeof (struct InputEvent), MEMF_CLEAR + MEMF_PUBLIC); if (iev == 0) goto fail; if (OpenDevice ("input.device", 0, ioreq, 0) != 0) goto fail; if (OpenDevice ("timer.device", 0, timereq, 0) != 0) goto fail; foo.mx = (ULONG)-1; foo.my = (ULONG)-1; foo.mt = FindTask (0); AddIntServer(INTB_VERTB, &myint); ibase = OpenLibrary ("intuition.library", 0); SetTaskPri (foo.mt, 20); /* same as input.device */ for (;;) { int newx, newy; Wait (foo.sigbit); ioreq->io_Command = IND_WRITEEVENT; ioreq->io_Length = sizeof (struct InputEvent); ioreq->io_Data = iev; ioreq->io_Flags = IOF_QUICK; iev->ie_Class = IECLASS_POINTERPOS; iev->ie_SubClass = 0; iev->ie_Code = 0; iev->ie_Qualifier = 0; #if 0 newx = (*calltrap) (1); newy = (*calltrap) (2); if (oldy != newy || oldx != newx) #endif { timereq->tr_node.io_Flags = IOF_QUICK; timereq->tr_node.io_Command = TR_GETSYSTIME; DoIO (timereq); iev->ie_TimeStamp = timereq->tr_time; /* Those are signed, so I hope negative values are OK... */ /* I wonder why I have to multiply those by 2... but it works, * at least for me. */ iev->ie_position.ie_xy.ie_x = foo.mx - ibase->ViewLord.DxOffset*2; iev->ie_position.ie_xy.ie_y = foo.my - ibase->ViewLord.DyOffset*2; oldx = newx; oldy = newy; DoIO(ioreq); } #if 0 timereq->tr_node.io_Flags = IOF_QUICK; timereq->tr_time.tv_secs = 0; timereq->tr_time.tv_micro = 20000; timereq->tr_node.io_Command = TR_ADDREQUEST; DoIO(timereq); #endif } fail: fprintf (stderr, "Couldn't start mousehack (that's bad!)\n"); exit (5); }
void SlaveEntry(void) { struct AHIAudioCtrlDrv* AudioCtrl; struct DriverBase* AHIsubBase; struct FilesaveBase* FilesaveBase; struct EIGHTSVXheader EIGHTSVXheader = // All 0s will be filled later. { __htobe_long(ID_FORM), 0, __htobe_long(ID_8SVX), __htobe_long(ID_VHDR), __htobe_long(sizeof(Voice8Header)), { 0, 0, 0, 0, 1, sCmpNone, __htobe_long(0x10000) }, __htobe_long(ID_BODY), 0 }; struct AIFFheader AIFFheader = // All 0s will be filled later. { __htobe_long(ID_FORM), 0, __htobe_long(ID_AIFF), __htobe_long(ID_COMM), __htobe_long(sizeof(CommonChunk)), { 0, 0, __htobe_short(16), { 0, { 0, 0 } } }, __htobe_long(ID_SSND), 0, { 0, 0 } }; struct AIFCheader AIFCheader = // All 0s will be filled later. { __htobe_long(ID_FORM), 0, __htobe_long(ID_AIFC), __htobe_long(ID_FVER), __htobe_long(sizeof(FormatVersionHeader)), { __htobe_long(AIFCVersion1) }, __htobe_long(ID_COMM), __htobe_long(sizeof(ExtCommonChunk)), { 0, 0, __htobe_short(16), { 0, { 0, 0 } }, __htobe_long(NO_COMPRESSION), { sizeof("not compressed") - 1, 'n','o','t',' ','c','o','m','p','r','e','s','s','e','d' } }, __htobe_long(ID_SSND), 0, { 0, 0 } }; struct STUDIO16FILE S16header = // All 0s will be filled later. { __htobe_long(S16FID), 0, __htobe_long(S16FINIT), __htobe_short(S16_VOL_0), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 } }; struct WAVEheader WAVEheader = // All 0s will be filled later. { __htobe_long(ID_RIFF), 0, __htobe_long(ID_WAVE), __htobe_long(ID_fmt), __htole_long( sizeof(FormatChunk) ), { __htole_short( WAVE_PCM ), 0, 0, 0, 0, __htole_short( 16 ) }, __htobe_long(ID_data), 0 }; BPTR lock = 0,cd = 0,file = 0, file2 = 0; LONG maxVolume = 0; ULONG signals, i, samplesAdd =0, samples = 0, length = 0; ULONG offset = 0, bytesInBuffer = 0, samplesWritten = 0, bytesWritten = 0; AudioCtrl = (struct AHIAudioCtrlDrv*) FindTask( NULL )->tc_UserData; AHIsubBase = (struct DriverBase*) dd->fs_AHIsubBase; FilesaveBase = (struct FilesaveBase*) AHIsubBase; // We cannot handle stereo 8SVXs! if( (dd->fs_Format == FORMAT_8SVX) && (AudioCtrl->ahiac_Flags & AHIACF_STEREO) ) { goto quit; } if((dd->fs_SlaveSignal = AllocSignal(-1)) == -1) { goto quit; } if(!(lock = Lock(dd->fs_FileReq->fr_Drawer, ACCESS_READ))) { goto quit; } cd = CurrentDir(lock); switch(dd->fs_Format) { case FORMAT_8SVX: if(!(file = Open(dd->fs_FileReq->fr_File, MODE_NEWFILE))) goto quit; Write(file, &EIGHTSVXheader, sizeof EIGHTSVXheader); break; case FORMAT_AIFF: if(!(file = Open(dd->fs_FileReq->fr_File, MODE_NEWFILE))) goto quit; Write(file, &AIFFheader, sizeof AIFFheader); break; case FORMAT_AIFC: if(!(file = Open(dd->fs_FileReq->fr_File, MODE_NEWFILE))) goto quit; Write(file, &AIFCheader, sizeof AIFCheader); break; case FORMAT_S16: if (AudioCtrl->ahiac_Flags & AHIACF_STEREO) { char filename[256]; int len; strncpy (filename, dd->fs_FileReq->fr_File, sizeof(filename) - 3); len = strlen(filename); if(len >= 2 && filename[len - 2] == '_' && (filename[len - 1] == 'L' || filename[len - 1] == 'R')) { filename[len - 1] = 'L'; } else { strcat (filename, "_L"); } if(!(file = Open(filename, MODE_NEWFILE))) goto quit; filename[strlen(filename) - 1] = 'R'; if(!(file2 = Open(filename, MODE_NEWFILE))) goto quit; Write(file, &S16header, sizeof S16header); Write(file2, &S16header, sizeof S16header); } else { if(!(file = Open(dd->fs_FileReq->fr_File, MODE_NEWFILE))) goto quit; Write(file, &S16header, sizeof S16header); } break; case FORMAT_WAVE: if(!(file = Open(dd->fs_FileReq->fr_File, MODE_NEWFILE))) goto quit; Write(file, &WAVEheader, sizeof WAVEheader); break; } // Everything set up. Tell Master we're alive and healthy. Signal((struct Task *)dd->fs_MasterTask,1L<<dd->fs_MasterSignal); for(;;) { signals = SetSignal(0L,0L); if(signals & (SIGBREAKF_CTRL_C | 1L<<dd->fs_SlaveSignal)) { break; } CallHookPkt(AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL); CallHookPkt(AudioCtrl->ahiac_MixerFunc, AudioCtrl, dd->fs_MixBuffer); samplesAdd = AudioCtrl->ahiac_BuffSamples; samples = samplesAdd; if(AudioCtrl->ahiac_Flags & AHIACF_STEREO) { samples <<= 1; } // Search for loudest part in sample if(AudioCtrl->ahiac_Flags & AHIACF_HIFI) { for(i = 0; i < samples; i++) if(abs(((LONG *)dd->fs_MixBuffer)[i]) > maxVolume) maxVolume = abs(((LONG *)dd->fs_MixBuffer)[i]); } else { for(i = 0; i< samples; i++) if(abs(((WORD *)dd->fs_MixBuffer)[i]) > maxVolume) maxVolume = abs(((WORD *)dd->fs_MixBuffer)[i]); } if((AudioCtrl->ahiac_Flags & AHIACF_STEREO) && dd->fs_Format == FORMAT_S16) { samples >>= 1; // Two buffers instead } if(offset+samples >= dd->fs_SaveBufferSize) { if((ULONG) Write(file, dd->fs_SaveBuffer, bytesInBuffer) != bytesInBuffer) { break; } if(file2 != 0) { if((ULONG) Write(file2, dd->fs_SaveBuffer2, bytesInBuffer) != bytesInBuffer) { break; } } offset = 0; bytesInBuffer = 0; } switch(dd->fs_Format) { case FORMAT_8SVX: if(AudioCtrl->ahiac_Flags & AHIACF_HIFI) { BYTE *dest = &((BYTE *) dd->fs_SaveBuffer)[offset]; LONG *source = dd->fs_MixBuffer; for(i = 0; i < samples; i++) *dest++ = *source++ >> 24; } else {