示例#1
0
static void GetSliderAttrs(struct AHIAudioModeRequesterExt *req, LONG *levels, LONG *level)
{
  *levels=0;
  *level=0;
  
  AHI_GetAudioAttrs(req->tempAudioID, NULL,
      AHIDB_Frequencies,  (ULONG) levels,
      AHIDB_IndexArg,     (req->tempAudioID == AHI_DEFAULT_ID ? 
                              AHIBase->ahib_Frequency : req->tempFrequency),
      AHIDB_Index,        (ULONG) level,
      TAG_DONE);

  if(*level >= *levels)
    *level = *levels-1;

  AHI_GetAudioAttrs(req->tempAudioID, NULL,
      AHIDB_FrequencyArg, *level,
      AHIDB_Frequency,    (ULONG) &req->tempFrequency,
      TAG_DONE);
}
示例#2
0
void FillUnit() {
  struct UnitNode *unit = NULL;
  struct ModeNode *mode = NULL;
  ULONG id;
  double db;

  unit = (struct UnitNode *) GetNode(state.UnitSelected, UnitList);

  if(unit->prefs.ahiup_Unit != AHI_NO_UNIT) {
    unit->prefs.ahiup_Channels    = state.ChannelsSelected;
    unit->prefs.ahiup_ScaleMode   = state.ScaleModeSelected;
  }
  else {
    unit->prefs.ahiup_Channels    = 0;
    unit->prefs.ahiup_ScaleMode   = 0;
  }

  if( state.ModeSelected != ~0 )
  {
    mode = (struct ModeNode *) GetNode(state.ModeSelected, ModeList);
  }

  if( mode != NULL )
  {
    unit->prefs.ahiup_AudioMode = mode->ID;

    AHI_GetAudioAttrs(mode->ID, NULL,
		      AHIDB_FrequencyArg, state.FreqSelected,
		      AHIDB_Frequency,    (ULONG) &unit->prefs.ahiup_Frequency,
		      TAG_DONE);
  }

  db = state.OutVolOffset + DBSTEP * 
      (state.OutVolSelected - (state.OutVolMute ? 1 : 0) );
  unit->prefs.ahiup_OutputVolume = pow(10.0, db/20) * 65536 + 0.5;
  if(state.OutVolMute && (state.OutVolSelected == 0))
    unit->prefs.ahiup_OutputVolume = 0;

  db = state.MonVolOffset + DBSTEP * 
      (state.MonVolSelected - (state.MonVolMute ? 1 : 0) );
  unit->prefs.ahiup_MonitorVolume = pow(10.0, db/20) * 65536 + 0.5;
  if(state.MonVolMute && (state.MonVolSelected == 0))
    unit->prefs.ahiup_MonitorVolume = 0;

  db = state.GainOffset + DBSTEP * 
      (state.GainSelected - (state.GainMute ? 1 : 0) );
  unit->prefs.ahiup_InputGain = pow(10.0, db/20) * 65536 + 0.5;
  if(state.GainMute && (state.GainSelected == 0))
    unit->prefs.ahiup_InputGain = 0;

  unit->prefs.ahiup_Input         = state.InputSelected;
  unit->prefs.ahiup_Output        = state.OutputSelected;
}
示例#3
0
struct List *GetModes(struct AHIUnitPrefs *prefs) {
  struct List *list;

  list = AllocVec(sizeof(struct List), MEMF_CLEAR);
  
  if(list) {
    ULONG id = AHI_NextAudioID(AHI_INVALID_ID);

    NewList(list);

    while(id != AHI_INVALID_ID) {
      struct ModeNode *t;
      struct Node     *node;
      
      t = AllocVec( sizeof(struct ModeNode), MEMF_CLEAR);

      if( t != NULL ) {
        LONG realtime;

        t->node.ln_Name = t->name;
        t->ID = id;
        
        realtime = FALSE;
        
        AHI_GetAudioAttrs(id, NULL,
            AHIDB_BufferLen,  80,
            AHIDB_Name,       (ULONG) t->node.ln_Name,
            AHIDB_Realtime,   (ULONG) &realtime,
            TAG_DONE);

        if((prefs->ahiup_Unit == AHI_NO_UNIT) || realtime ) {
          // Insert node alphabetically
          for(node = list->lh_Head;
              node->ln_Succ;
              node = node->ln_Succ) {
            if(Stricmp(t->node.ln_Name,node->ln_Name) < 0)
              break;
          }
          Insert(list, (struct Node *) t, node->ln_Pred);
        }
        else {
          FreeVec(t);
        }
      }
      id = AHI_NextAudioID(id);
    }
  }
  return list;
}
示例#4
0
LONG IndexToFrequency( struct Gadget *gad, WORD level )
{
  LONG  freq = 0;
  ULONG id;

  id = ((struct AHIAudioModeRequesterExt *)gad->UserData)->tempAudioID;

  if(id != AHI_DEFAULT_ID)
  {
    AHI_GetAudioAttrs( id, NULL,
                       AHIDB_FrequencyArg, level,
                       AHIDB_Frequency,    (ULONG) &freq,
                       TAG_DONE );
  }
  else
  {
    freq = AHIBase->ahib_Frequency;
  }
  return freq;
}
示例#5
0
char *getRecord(void) {
  ULONG record = FALSE, fullduplex = FALSE;
  struct ModeNode *mode = NULL;

  if( state.ModeSelected != ~0 )
  {
    mode = (struct ModeNode *) GetNode(state.ModeSelected, ModeList);
  }

  if( mode != NULL )
  {
    AHI_GetAudioAttrs(
      mode->ID, NULL,
      AHIDB_Record,     (ULONG) &record,
      AHIDB_FullDuplex, (ULONG) &fullduplex,
      TAG_DONE);
  }
  
  return (char *) (record ? (fullduplex ? msgPropRecordFull : msgPropRecordHalf )
                          : msgPropRecordNone);
}
示例#6
0
char *getFreq(void) {
  LONG freq = 0;
  struct ModeNode *mode = NULL;

  if( state.ModeSelected != ~0 )
  {
    mode = (struct ModeNode *) GetNode(state.ModeSelected, ModeList);
  }

  if( mode != NULL )
  {
    AHI_GetAudioAttrs(
      mode->ID, NULL,
      AHIDB_FrequencyArg, state.FreqSelected,
      AHIDB_Frequency,    (ULONG) &freq,
      TAG_DONE);
  }

  sprintf(freqBuffer, "%ld Hz", freq);
  return freqBuffer;
}
static int
MaxPlaySamples(ULONG mode_id, ULONG mix_freq, ULONG player_freq) {
  int rc = RETURN_OK;

  struct AHIAudioCtrl* actrl = AHI_AllocAudio(AHIA_AudioID,       mode_id,
					      AHIA_MixFreq,       mix_freq,
					      AHIA_PlayerFreq,    player_freq << 16,
					      AHIA_MinPlayerFreq, player_freq << 16,
					      AHIA_MaxPlayerFreq, player_freq << 16,
					      AHIA_Channels,      1,
					      AHIA_Sounds,        1,
					      TAG_DONE);

  if (actrl != NULL) {
    ULONG max_play_samples = 0;

    if (AHI_GetAudioAttrs(AHI_INVALID_ID, actrl,
			  AHIDB_MaxPlaySamples, &max_play_samples,
			  TAG_DONE)) {
      fprintf(stderr, 
	      "MaxPlaySamples for mode 0x%08lx (Fsample = %ld Hz, Fplayer = %ld Hz) is %ld\n",
	      mode_id, mix_freq, player_freq, max_play_samples);
    }
    else {
      fprintf(stderr, "Unable to get MaxPlaySamples.\n");
      rc = RETURN_ERROR;
    }
    AHI_FreeAudio(actrl);
  }
  else {
    fprintf(stderr, "Unable to allocate audio.\n");
    rc = RETURN_ERROR;
  }

  return rc;
}
示例#8
0
static BOOL HandleReq( struct AHIAudioModeRequesterExt *req )

// Returns FALSE if requester was cancelled

{
  BOOL done=FALSE,rc=TRUE;
  ULONG class,sec,oldsec=0,micro,oldmicro=0,oldid=AHI_INVALID_ID;
  UWORD code;
  UWORD qual;
  struct Gadget *pgsel;
  struct IntuiMessage *imsg;
  struct IDnode *idnode;
  LONG   sliderlevels,sliderlevel,i,selected;
  struct MenuItem *item;

  while(!done)
  {
    Wait(1L << req->Window->UserPort->mp_SigBit);

    while ((imsg=GT_GetIMsg(req->Window->UserPort)) != NULL )
    {

      if(imsg->IDCMPWindow == req->InfoWindow)
      {
        class = imsg->Class;
        GT_ReplyIMsg(imsg);

        switch(class)
        {
        case IDCMP_CLOSEWINDOW:
          CloseInfoWindow(req);
          break;
        case IDCMP_REFRESHWINDOW :
          GT_BeginRefresh(req->InfoWindow);
          GT_EndRefresh(req->InfoWindow,TRUE);
          break;
        }
        continue; // Get next IntuiMessage
      }

      else if(imsg->IDCMPWindow != req->Window) // Not my window!
      {
        if(req->IntuiMsgFunc)
          CallHookPkt(req->IntuiMsgFunc,req,imsg);
        // else what to do??? Reply and forget? FIXIT!
        continue;
      }

      sec=imsg->Seconds;
      micro=imsg->Micros;
      qual=imsg->Qualifier;
      class=imsg->Class;
      code=imsg->Code;
      pgsel=(struct Gadget *)imsg->IAddress; // pgsel illegal if not gadget
      GT_ReplyIMsg(imsg);

      switch ( class )
      {
      case IDCMP_RAWKEY:
        switch (code)
        {
        case 0x4c: // Cursor Up
          selected=GetSelected(req);
          if(selected == ~0)
            selected=0;
          if(selected > 0)
            selected--;
          idnode=(struct IDnode *)req->list->mlh_Head;
          for(i=0;i<selected;i++)
            idnode=(struct IDnode *)idnode->node.ln_Succ;
          req->tempAudioID=idnode->ID;
          SetSelected(req,TRUE);
          break;
        case 0x4d: // Cursor Down
          selected=GetSelected(req);
          selected++; // ~0 => 0
          idnode=(struct IDnode *)req->list->mlh_Head;
          for(i=0;i<selected;i++)
            if(idnode->node.ln_Succ->ln_Succ)
              idnode=(struct IDnode *)idnode->node.ln_Succ;
          req->tempAudioID=idnode->ID;
          SetSelected(req,TRUE);
          break;
        case 0x4e: // Cursor Right
          GetSliderAttrs(req,&sliderlevels,&sliderlevel);
          sliderlevel += (qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) ? 10 :1);
          if(sliderlevel >= sliderlevels)
            sliderlevel=sliderlevels-1;
          AHI_GetAudioAttrs(req->tempAudioID, NULL,
              AHIDB_FrequencyArg,sliderlevel,
              AHIDB_Frequency, (ULONG) &req->tempFrequency,
              TAG_DONE);
          SetSelected(req,FALSE);
          break;
        case 0x4f: // Cursor Left
          GetSliderAttrs(req,&sliderlevels,&sliderlevel);
          sliderlevel -= (qual & (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT) ? 10 :1);
          if(sliderlevel < 0)
            sliderlevel=0;
          AHI_GetAudioAttrs(req->tempAudioID, NULL,
              AHIDB_FrequencyArg,sliderlevel,
              AHIDB_Frequency, (ULONG) &req->tempFrequency,
              TAG_DONE);
          SetSelected(req,FALSE);
          break;
        }
        break;
      case IDCMP_GADGETUP :
        switch ( pgsel->GadgetID )
        {
        case OKBUTTON:
          done=TRUE;
          break;
        case CANCELBUTTON:
          done=TRUE;
          rc=FALSE;
          break;
        case FREQSLIDER:
          AHI_GetAudioAttrs(req->tempAudioID, NULL,
              AHIDB_FrequencyArg,code,
              AHIDB_Frequency, (ULONG) &req->tempFrequency,
              TAG_DONE);
          break;
        case LISTVIEW:
          idnode=(struct IDnode *)req->list->mlh_Head;
          for(i=0;i<code;i++)
            idnode=(struct IDnode *)idnode->node.ln_Succ;
          req->tempAudioID=idnode->ID;
          SetSelected(req,FALSE);
          // Test doubleclick and save timestamp
          if( (oldid == req->tempAudioID) && DoubleClick(oldsec,oldmicro,sec,micro))
            done=TRUE;
          oldsec=sec;
          oldmicro=micro;
          oldid=req->tempAudioID;

          break;
        }
        break;

      case IDCMP_NEWSIZE:
        if(!(LayOutReq(req,req->TextAttr)))
          if(!(LayOutReq(req,&Topaz80)))
          {
            // ERROR! Quit.
            done=TRUE;
            break;
          }
        break;
      case IDCMP_CLOSEWINDOW:
        done=TRUE;
        rc=FALSE;
        break;
      case IDCMP_REFRESHWINDOW :
        GT_BeginRefresh(req->Window);
        GT_EndRefresh(req->Window,TRUE);
        break;
      case IDCMP_SIZEVERIFY:
        break;
      case IDCMP_MENUPICK:
        while((code != MENUNULL) && !done)
        {
          item=ItemAddress(req->Menu, code);
          switch((ULONG)GTMENUITEM_USERDATA(item))
          {
          case LASTMODEITEM:
            selected=GetSelected(req);
            if(selected == ~0)
              selected=0;
            if(selected > 0)
              selected--;
            idnode=(struct IDnode *)req->list->mlh_Head;
            for(i=0;i<selected;i++)
              idnode=(struct IDnode *)idnode->node.ln_Succ;
            req->tempAudioID=idnode->ID;
            SetSelected(req,TRUE);
            break;
          case NEXTMODEITEM:
            selected=GetSelected(req);
            selected++; // ~0 => 0
            idnode=(struct IDnode *)req->list->mlh_Head;
            for(i=0;i<selected;i++)
              if(idnode->node.ln_Succ->ln_Succ)
                idnode=(struct IDnode *)idnode->node.ln_Succ;
            req->tempAudioID=idnode->ID;
            SetSelected(req,TRUE);
            break;
          case PROPERTYITEM:
            OpenInfoWindow(req);
            break;
          case RESTOREITEM:
            req->tempAudioID=req->Req.ahiam_AudioID;
            req->tempFrequency=req->Req.ahiam_MixFreq;
            SetSelected(req,TRUE);
            break;
          case OKITEM:
            done=TRUE;
            break;
          case CANCELITEM:
            done=TRUE;
            rc=FALSE;
            break;
          }
          code = item->NextSelect;
        }
        break;
      }
    }
  }
示例#9
0
Fixed DizzyTestAudioID(ULONG id, struct TagItem *tags )
{
  ULONG volume=0,stereo=0,panning=0,hifi=0,pingpong=0,record=0,realtime=0,
        fullduplex=0,bits=0,channels=0,minmix=0,maxmix=0;
  ULONG total=0,hits=0;
  struct TagItem *tstate, *tag;
  
  if(tags == NULL)
  {
    return (Fixed) 0x10000;
  }

  if(id == AHI_DEFAULT_ID)
  {
    id = AHIBase->ahib_AudioMode;
  }

  AHI_GetAudioAttrs( id, NULL,
                     AHIDB_Volume,      (ULONG) &volume,
                     AHIDB_Stereo,      (ULONG) &stereo,
                     AHIDB_Panning,     (ULONG) &panning,
                     AHIDB_HiFi,        (ULONG) &hifi,
                     AHIDB_PingPong,    (ULONG) &pingpong,
                     AHIDB_Record,      (ULONG) &record,
                     AHIDB_Bits,        (ULONG) &bits,
                     AHIDB_MaxChannels, (ULONG) &channels,
                     AHIDB_MinMixFreq,  (ULONG) &minmix,
                     AHIDB_MaxMixFreq,  (ULONG) &maxmix,
                     AHIDB_Realtime,    (ULONG) &realtime,
                     AHIDB_FullDuplex,  (ULONG) &fullduplex,
                     TAG_DONE );

  tstate = tags;

  while ((tag = NextTagItem(&tstate)))
  {
    switch (tag->ti_Tag)
    {
      // Check source mode

      case AHIDB_AudioID:    
        total++;
        if( ((tag->ti_Data)&0xffff0000) == (id & 0xffff0000) )
          hits++;
        break;

      // Boolean tags

      case AHIDB_Volume:
        total++;
        if(XNOR(tag->ti_Data, volume))
          hits++;
        break;

      case AHIDB_Stereo:
        total++;
        if(XNOR(tag->ti_Data, stereo))
          hits++;
        break;
      case AHIDB_Panning:
        total++;
        if(XNOR(tag->ti_Data, panning))
          hits++;
        break;
      case AHIDB_HiFi:
        total++;
        if(XNOR(tag->ti_Data, hifi))
          hits++;
        break;
      case AHIDB_PingPong:
        total++;
        if(XNOR(tag->ti_Data, pingpong))
          hits++;
        break;
      case AHIDB_Record:
        total++;
        if(XNOR(tag->ti_Data, record))
          hits++;
        break;
      case AHIDB_Realtime:
        total++;
        if(XNOR(tag->ti_Data, realtime))
          hits++;
        break;
      case AHIDB_FullDuplex:
        total++;
        if(XNOR(tag->ti_Data, fullduplex))
          hits++;
        break;

      // The rest

      case AHIDB_Bits:
        total++;
        if(tag->ti_Data <= bits)
          hits++;
        break;
      case AHIDB_MaxChannels:
        total++;
        if(tag->ti_Data <= channels )
          hits++;
        break;
      case AHIDB_MinMixFreq:
        total++;
        if(tag->ti_Data >= minmix)
          hits++;
        break;
      case AHIDB_MaxMixFreq:
        total++;
        if(tag->ti_Data <= maxmix)
          hits++;
        break;
    } /* switch */
  } /* while */


  if(total)
    return (Fixed) ((hits<<16)/total);
  else
    return (Fixed) 0x10000;
}
示例#10
0
void NewMode(int selectedmode) {
  struct UnitNode *unit = NULL;
  struct ModeNode *mode = NULL;
  ULONG id = AHI_INVALID_ID;
  Fixed MinOutVol = 0, MaxOutVol = 0, MinMonVol = 0, MaxMonVol = 0;
  Fixed MinGain = 0, MaxGain = 0;
  double Min, Max, Current;
  int offset;

  state.ModeSelected = selectedmode;

  unit = (struct UnitNode *) GetNode(state.UnitSelected, UnitList);

  if( selectedmode != ~0 )
  {
    mode = (struct ModeNode *) GetNode(selectedmode, ModeList);
  }

  if( mode != NULL )
  {
    id = mode->ID;
    
    AHI_GetAudioAttrs(id, NULL,
		      AHIDB_IndexArg,         unit->prefs.ahiup_Frequency,
		      AHIDB_Index,            (ULONG) &state.FreqSelected,
		      AHIDB_Frequencies,      (ULONG) &state.Frequencies,
		      AHIDB_MaxChannels,      (ULONG) &state.Channels,
		      AHIDB_Inputs,           (ULONG) &state.Inputs,
		      AHIDB_Outputs,          (ULONG) &state.Outputs,
		      AHIDB_MinOutputVolume,  (ULONG) &MinOutVol,
		      AHIDB_MaxOutputVolume,  (ULONG) &MaxOutVol,
		      AHIDB_MinMonitorVolume, (ULONG) &MinMonVol,
		      AHIDB_MaxMonitorVolume, (ULONG) &MaxMonVol,
		      AHIDB_MinInputGain,     (ULONG) &MinGain,
		      AHIDB_MaxInputGain,     (ULONG) &MaxGain,

		      AHIDB_BufferLen,        128,
		      AHIDB_Author,           (ULONG) authorBuffer,
		      AHIDB_Copyright,        (ULONG) copyrightBuffer,
		      AHIDB_Driver,           (ULONG) driverBuffer,
		      AHIDB_Version,          (ULONG) versionBuffer,
		      AHIDB_Annotation,       (ULONG) annotationBuffer,
		      TAG_DONE);
  }

  state.ChannelsSelected = unit->prefs.ahiup_Channels;
  state.ScaleModeSelected = unit->prefs.ahiup_ScaleMode;
  state.InputSelected    = unit->prefs.ahiup_Input;
  state.OutputSelected   = unit->prefs.ahiup_Output;

  // Limit channels
  state.Channels = min(state.Channels, 32);

  if(unit->prefs.ahiup_Unit == AHI_NO_UNIT) {
    state.ChannelsDisabled = TRUE;
  }
  else {
    state.ChannelsDisabled = FALSE;
  }

  if(MinOutVol == 0) {
    MinOutVol = 1;
    state.OutVolMute = TRUE;
    state.OutVols    = 1;
  }
  else {
    state.OutVolMute = FALSE;
    state.OutVols    = 0;
  }

  if(MinMonVol == 0) {
    MinMonVol = 1;
    state.MonVolMute = TRUE;
    state.MonVols    = 1;
  }
  else {
    state.MonVolMute = FALSE;
    state.MonVols    = 0;
  }


  if(MinGain == 0) {
    MinGain = 1;
    state.GainMute = TRUE;
    state.Gains    = 1;
  }
  else {
    state.GainMute = FALSE;
    state.Gains    = 0;
  }

  if(MaxOutVol == 0) {
    state.OutVolSelected = 0;
    state.OutVolOffset   = 0;
  }
  else {
    Current = 20 * log10( unit->prefs.ahiup_OutputVolume / 65536.0 );
    Min = floor(20 * log10( MinOutVol / 65536.0 ) / DBSTEP + 0.5) * DBSTEP;
    Max = floor(20 * log10( MaxOutVol / 65536.0 ) / DBSTEP + 0.5) * DBSTEP;
    state.OutVolSelected = (Current - Min) / DBSTEP + 0.5 + state.OutVols;
    state.OutVols += ((Max - Min) / DBSTEP) + 1;
    state.OutVolOffset = Min;
  }

  if(MaxMonVol == 0) {
    state.MonVolSelected = 0;
    state.MonVolOffset   = 0;
  }
  else {
    Current = 20 * log10( unit->prefs.ahiup_MonitorVolume / 65536.0 );
    Min = floor(20 * log10( MinMonVol / 65536.0 ) / DBSTEP + 0.5) * DBSTEP;
    Max = floor(20 * log10( MaxMonVol / 65536.0 ) / DBSTEP + 0.5) * DBSTEP;
    state.MonVolSelected = (Current - Min) / DBSTEP + 0.5 + state.MonVols;
    state.MonVols += ((Max - Min) / DBSTEP) + 1;
    state.MonVolOffset = Min;
  }

  if(MaxGain == 0) {
    state.GainSelected = 0;
    state.GainOffset   = 0;
  }
  else {
    Current = 20 * log10( unit->prefs.ahiup_InputGain / 65536.0 );
    Min = floor(20 * log10( MinGain / 65536.0 ) / DBSTEP + 0.5) * DBSTEP;
    Max = floor(20 * log10( MaxGain / 65536.0 ) / DBSTEP + 0.5) * DBSTEP;
    state.GainSelected = (Current - Min) / DBSTEP + 0.5 + state.Gains;
    state.Gains += ((Max - Min) / DBSTEP) + 1;
    state.GainOffset = Min;
  }

  // Make sure everything is within bounds!

  state.FreqSelected = max(state.FreqSelected, 0);  
  state.FreqSelected = min(state.FreqSelected, state.Frequencies);

  state.ChannelsSelected = max(state.ChannelsSelected, 1);
  state.ChannelsSelected = min(state.ChannelsSelected, state.Channels);
  
  state.ScaleModeSelected = max(state.ScaleModeSelected, 0);
  state.ScaleModeSelected = min(state.ScaleModeSelected, AHI_SCALE_FIXED_6_DB);
  
  state.OutVolSelected = max(state.OutVolSelected, 0);
  state.OutVolSelected = min(state.OutVolSelected, state.OutVols);
  
  state.MonVolSelected = max(state.MonVolSelected, 0);
  state.MonVolSelected = min(state.MonVolSelected, state.MonVols);
  
  state.GainSelected = max(state.GainSelected, 0);
  state.GainSelected = min(state.GainSelected, state.Gains);

  state.InputSelected = max(state.InputSelected, 0);
  state.InputSelected = min(state.InputSelected, state.Inputs);

  state.OutputSelected = max(state.OutputSelected, 0);
  state.OutputSelected = min(state.OutputSelected, state.Outputs);

  // Remove any \r's or \n's from version string

  offset = strlen(versionBuffer);
  while((offset > 0) &&
        ((versionBuffer[offset-1] == '\r') ||
         (versionBuffer[offset-1] == '\n'))) {
    versionBuffer[offset-1] = '\0';
    offset--;
  }

  FreeVec(Inputs);
  FreeVec(Outputs);
  Inputs   = GetInputs(id);
  Outputs  = GetOutputs(id);
}
示例#11
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;
	}
}
int
PlaySineEverywhere( void ) {
  int   rc = RETURN_OK;
  int   sine_length = 44100 / 100;
  BYTE* sine_m8s;
  BYTE* sine_s8s;
  WORD* sine_s16s;
  WORD* sine_m16s;
  LONG* sine_s32s;
  LONG* sine_m32s;

  sine_m8s  = AllocVec( 1 * sizeof( BYTE ) * sine_length, MEMF_ANY | MEMF_PUBLIC );
  sine_s8s  = AllocVec( 2 * sizeof( BYTE ) * sine_length, MEMF_ANY | MEMF_PUBLIC );
  sine_m16s = AllocVec( 1 * sizeof( WORD ) * sine_length, MEMF_ANY | MEMF_PUBLIC );
  sine_s16s = AllocVec( 2 * sizeof( WORD ) * sine_length, MEMF_ANY | MEMF_PUBLIC );
  sine_m32s = AllocVec( 1 * sizeof( LONG ) * sine_length, MEMF_ANY | MEMF_PUBLIC );
  sine_s32s = AllocVec( 2 * sizeof( LONG ) * sine_length, MEMF_ANY | MEMF_PUBLIC );
  
  if( sine_m8s != NULL &&
      sine_s8s != NULL &&
      sine_m16s != NULL &&
      sine_s16s != NULL &&
      sine_m32s != NULL &&
      sine_s32s != NULL ) {
    ULONG mode = AHI_INVALID_ID;
    int   i;

    for( i = 0; i < sine_length; ++i ) {
      double value = sin( i * 2 * M_PI / sine_length );

      sine_m8s[ i ] = (BYTE) ( SCHAR_MAX * value );
      sine_m16s[ i ] = (WORD) ( SHRT_MAX * value );
      sine_m32s[ i ] = (LONG) ( LONG_MAX * value );

      sine_s8s[ i * 2 + 0 ] = (BYTE) ( SCHAR_MAX * value );
      sine_s8s[ i * 2 + 1 ] = (BYTE) ( SCHAR_MAX * value );
      sine_s16s[ i * 2 + 0 ] = (WORD) ( SHRT_MAX * value );
      sine_s16s[ i * 2 + 1 ] = (WORD) ( SHRT_MAX * value );
      sine_s32s[ i * 2 + 0 ] = (LONG) ( LONG_MAX * value );
      sine_s32s[ i * 2 + 1 ] = (LONG) ( LONG_MAX * value );
    }

    while( rc == RETURN_OK &&
	   ( mode = AHI_NextAudioID( mode ) ) != AHI_INVALID_ID ) {
      struct AHIAudioCtrl* actrl;
      char                 name[ 64 ];
      struct Hook          sound_hook = {
	{ NULL, NULL },
	HookEntry,
	(HOOKFUNC) SoundFunc,
	FindTask( NULL )
      };
    
      AHI_GetAudioAttrs( mode, NULL,
			 AHIDB_Name, (ULONG) &name,
			 AHIDB_BufferLen, 64,
			 TAG_DONE );
    
      printf( "Mode 0x%08lx: %s\n", mode, name );

      actrl = AHI_AllocAudio( AHIA_AudioID,   mode,
			      AHIA_MixFreq,   44100,
			      AHIA_Channels,  1,
			      AHIA_Sounds,    6,
			      AHIA_SoundFunc, (ULONG) &sound_hook,
			      AHIA_UserData,  0,
			      TAG_DONE );

      if( actrl != NULL ) {
	struct AHISampleInfo sample_m8s  = { AHIST_M8S,  sine_m8s,  sine_length };
	struct AHISampleInfo sample_s8s  = { AHIST_S8S,  sine_s8s,  sine_length };
	struct AHISampleInfo sample_m16s = { AHIST_M16S, sine_m16s, sine_length };
	struct AHISampleInfo sample_s16s = { AHIST_S16S, sine_s16s, sine_length };
	struct AHISampleInfo sample_m32s = { AHIST_M32S, sine_m32s, sine_length };
	struct AHISampleInfo sample_s32s = { AHIST_S32S, sine_s32s, sine_length };
	
	if( AHI_LoadSound( 0, AHIST_SAMPLE, &sample_m8s,  actrl) == AHIE_OK &&
	    AHI_LoadSound( 1, AHIST_SAMPLE, &sample_s8s,  actrl) == AHIE_OK &&
	    AHI_LoadSound( 2, AHIST_SAMPLE, &sample_m16s, actrl) == AHIE_OK &&
	    AHI_LoadSound( 3, AHIST_SAMPLE, &sample_s16s, actrl) == AHIE_OK &&
	    AHI_LoadSound( 4, AHIST_SAMPLE, &sample_m32s, actrl) == AHIE_OK &&
	    AHI_LoadSound( 5, AHIST_SAMPLE, &sample_s32s, actrl) == AHIE_OK ) {

	  AHI_Play( actrl,
		    AHIP_BeginChannel, 0,
		    AHIP_Sound,        0,
		    AHIP_Freq,         44100,
		    AHIP_Vol,          0x10000,
		    AHIP_Pan,          0x00000,
		    AHIP_EndChannel,   0,
		    TAG_DONE );

	  // Now, when everything is "armed", lets start processing.

	  SetSignal( 0, SIGF_SINGLE );

	  if( AHI_ControlAudio( actrl,
				AHIC_Play, TRUE,
				TAG_DONE ) == AHIE_OK ) {
	    Wait( SIGF_SINGLE );

	    AHI_ControlAudio( actrl,
			      AHIC_Play, FALSE,
			      TAG_DONE );
	  }
	  else {
	    fprintf( stderr, "Unable start playback.\n" );
	    rc = RETURN_ERROR;
	  }

	  // AHI_FreeAudio() will unload the sounds
	}
	else {
	  fprintf( stderr, "Unable load sound.\n" );
	  rc = RETURN_ERROR;
	}
	
	AHI_FreeAudio( actrl );
      }
      else {
	fprintf( stderr, "Unable to allocate audio.\n" );
	rc = RETURN_ERROR;
      }
    }
  }
  else {
    fprintf( stderr, "Unable to allocate memory for sine\n" );
  }

  FreeVec( sine_m8s );
  FreeVec( sine_s8s );
  FreeVec( sine_s16s );
  FreeVec( sine_m16s );
  FreeVec( sine_s32s );
  FreeVec( sine_m32s );

  return rc;
}