Example #1
1
File: nMsg.c Project: zenbaku/nano
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;
}
Example #2
0
// 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;
}
Example #3
0
File: nMsg.c Project: zenbaku/nano
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;
}    
Example #4
0
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;
}
Example #5
0
File: nMsg.c Project: zenbaku/nano
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();
}
Example #6
0
File: nMain.c Project: zenbaku/nano
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 */
}
Example #7
0
// 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;
}