int nSend(nTask task, void *msg) { int rc; START_CRITICAL(); pending_sends++; { nTask this_task= current_task; if (task->status==WAIT_SEND || task->status==WAIT_SEND_TIMEOUT) { if (task->status==WAIT_SEND_TIMEOUT) CancelTask(task); task->status= READY; PushTask(ready_queue, task); /* En primer lugar en la cola */ } else if (task->status==ZOMBIE) nFatalError("nSend", "El receptor es un ``zombie''\n"); /* En nReply se coloca ``this_task'' en la cola de tareas ready */ PutTask(task->send_queue, this_task); this_task->send.msg= msg; this_task->status= WAIT_REPLY; ResumeNextReadyTask(); rc= this_task->send.rc; } pending_sends--; END_CRITICAL(); return rc; }
// Convert a multichannel sample to mono (currently only implemented for stereo) bool ConvertToMono(modplug::tracker::modsample_t *pSmp, module_renderer *pSndFile) //------------------------------------------------------- { if(pSmp->sample_data == nullptr || pSmp->length == 0 || pSmp->GetNumChannels() != 2) return false; // Note: Sample is overwritten in-place! Unused data is not deallocated! if(pSmp->GetElementarySampleSize() == 2) ConvertStereoToMonoImpl(reinterpret_cast<int16_t*>(pSmp->sample_data), pSmp->length); else if(pSmp->GetElementarySampleSize() == 1) ConvertStereoToMonoImpl(reinterpret_cast<int8_t*>(pSmp->sample_data), pSmp->length); else return false; BEGIN_CRITICAL(); pSmp->flags &= ~(CHN_STEREO); for (modplug::tracker::chnindex_t i = 0; i < MAX_VIRTUAL_CHANNELS; i++) { if(pSndFile->Chn[i].sample_data == pSmp->sample_data) { pSndFile->Chn[i].flags &= ~CHN_STEREO; } } END_CRITICAL(); AdjustEndOfSample(*pSmp, pSndFile); return true; }
void *nReceive(nTask *ptask, int timeout) { void *msg; nTask send_task; START_CRITICAL(); pending_receives++; { nTask this_task= current_task; if (EmptyQueue(this_task->send_queue) && timeout!=0) { if (timeout>0) { this_task->status= WAIT_SEND_TIMEOUT; ProgramTask(timeout); /* La tarea se despertara automaticamente despues de timeout */ } else this_task->status= WAIT_SEND; /* La tarea espera indefinidamente */ ResumeNextReadyTask(); /* Se suspende indefinidamente hasta un nSend */ } send_task= GetTask(this_task->send_queue); if (ptask!=NULL) *ptask= send_task; msg= send_task==NULL ? NULL : send_task->send.msg; } pending_receives--; END_CRITICAL(); return msg; }
bool AdjustEndOfSample(modplug::tracker::modsample_t& smp, module_renderer* pSndFile) //---------------------------------------------------------- { modplug::tracker::modsample_t* const pSmp = &smp; if ((!pSmp->length) || (!pSmp->sample_data)) return false; BEGIN_CRITICAL(); if (pSmp->GetElementarySampleSize() == 2) AdjustEndOfSampleImpl<int16_t>(*pSmp); else if(pSmp->GetElementarySampleSize() == 1) AdjustEndOfSampleImpl<int8_t>(*pSmp); // Update channels with new loop values if(pSndFile != nullptr) { module_renderer& rSndFile = *pSndFile; for (UINT i=0; i<MAX_VIRTUAL_CHANNELS; i++) if ((rSndFile.Chn[i].sample == pSmp) && (rSndFile.Chn[i].length)) { if ((pSmp->loop_start + 3 < pSmp->loop_end) && (pSmp->loop_end <= pSmp->length)) { rSndFile.Chn[i].loop_start = pSmp->loop_start; rSndFile.Chn[i].loop_end = pSmp->loop_end; rSndFile.Chn[i].length = pSmp->loop_end; if (rSndFile.Chn[i].sample_position > rSndFile.Chn[i].length) { rSndFile.Chn[i].sample_position = rSndFile.Chn[i].loop_start; rSndFile.Chn[i].flags &= ~CHN_PINGPONGFLAG; } uint32_t d = rSndFile.Chn[i].flags & ~(CHN_PINGPONGLOOP|CHN_LOOP); if (pSmp->flags & CHN_LOOP) { d |= CHN_LOOP; if (pSmp->flags & CHN_PINGPONGLOOP) d |= CHN_PINGPONGLOOP; } rSndFile.Chn[i].flags = d; } else if (!(pSmp->flags & CHN_LOOP)) { rSndFile.Chn[i].flags &= ~(CHN_PINGPONGLOOP|CHN_LOOP); } } } END_CRITICAL(); return true; }
void nReply(nTask task, int rc) { START_CRITICAL(); if (task->status!=WAIT_REPLY) nFatalError("nReply","Esta tarea no espera un ``nReply''\n"); PushTask(ready_queue, current_task); task->send.rc= rc; task->status= READY; PushTask(ready_queue, task); ResumeNextReadyTask(); END_CRITICAL(); }
int main(int argc, char **argv) { int rc; START_CRITICAL(); ProcessInit(); TimeInit(); IOInit(); #ifdef TRAPINTS TrapInts(); #endif END_CRITICAL(); { /* analisis de los argumentos */ int in; int out=1; int count=1; for (in=1; in<argc; in++) if (strcmp(argv[in],"-slice")==0 && ++in<argc) { char *pc; for (pc= argv[in]; *pc!='\0'; pc++) if (! ('0'<= *pc && *pc<='9')) nFatalError("main", "Invalid option -slice %s", argv[in]); nSetTimeSlice(atoi(argv[in])); } else if (strcmp(argv[in],"-noblocking")==0) nSetNonBlockingStdio(); else { argv[out++]= argv[in]; count++; } argc= count; } rc= nMain(argc, argv); nExitSystem(rc); return rc; /* nunca llega aca */ }
// Remove DC offset float RemoveDCOffset(modplug::tracker::modsample_t& smp, SmpLength iStart, SmpLength iEnd, const MODTYPE modtype, module_renderer* const pSndFile) //---------------------------------------------- { if(smp.sample_data == nullptr || smp.length < 1) return 0; modplug::tracker::modsample_t* const pSmp = &smp; if (iEnd > pSmp->length) iEnd = pSmp->length; if (iStart > iEnd) iStart = iEnd; if (iStart == iEnd) { iStart = 0; iEnd = pSmp->length; } iStart *= pSmp->GetNumChannels(); iEnd *= pSmp->GetNumChannels(); const double dMaxAmplitude = (pSmp->GetElementarySampleSize() == 2) ? GetMaxAmplitude<int16_t>() : GetMaxAmplitude<int8_t>(); // step 1: Calculate offset. OffsetData oData = {0,0,0}; if(pSmp->GetElementarySampleSize() == 2) oData = CalculateOffset(reinterpret_cast<int16_t*>(pSmp->sample_data) + iStart, iEnd - iStart); else if(pSmp->GetElementarySampleSize() == 1) oData = CalculateOffset(reinterpret_cast<int8_t*>(pSmp->sample_data) + iStart, iEnd - iStart); double dMin = oData.dMin, dMax = oData.dMax, dOffset = oData.dOffset; const float fReportOffset = (float)dOffset; if((int)(dOffset * dMaxAmplitude) == 0) return 0; // those will be changed... dMax += dOffset; dMin += dOffset; // ... and that might cause distortion, so we will normalize this. const double dAmplify = 1 / bad_max(dMax, -dMin); // step 2: centralize + normalize sample dOffset *= dMaxAmplitude * dAmplify; if(pSmp->GetElementarySampleSize() == 2) RemoveOffsetAndNormalize( reinterpret_cast<int16_t*>(pSmp->sample_data) + iStart, iEnd - iStart, dOffset, dAmplify); else if(pSmp->GetElementarySampleSize() == 1) RemoveOffsetAndNormalize( reinterpret_cast<int8_t*>(pSmp->sample_data) + iStart, iEnd - iStart, dOffset, dAmplify); // step 3: adjust global vol (if available) if((modtype & (MOD_TYPE_IT | MOD_TYPE_MPT)) && (iStart == 0) && (iEnd == pSmp->length * pSmp->GetNumChannels())) { BEGIN_CRITICAL(); pSmp->global_volume = bad_min((uint16_t)(pSmp->global_volume / dAmplify), 64); for (modplug::tracker::chnindex_t i = 0; i < MAX_VIRTUAL_CHANNELS; i++) { if(pSndFile->Chn[i].sample_data == pSmp->sample_data) { pSndFile->Chn[i].nGlobalVol = pSmp->global_volume; } } END_CRITICAL(); } AdjustEndOfSample(smp, pSndFile); return fReportOffset; }