コード例 #1
0
ファイル: naplay.c プロジェクト: EQ4/rsynth
void
audio_term(void)
{
 if (aud)
  {
   AuFlush(aud);
   AuCloseServer(aud);
  }
}
コード例 #2
0
static int nas_free(WINE_WAVEOUT* wwo)
{

  if (!wwo->FlowStarted && wwo->BufferUsed) {
     AuStartFlow(wwo->AuServ, wwo->AuFlow, NULL);
     wwo->FlowStarted = 1;
  }

  while (wwo->BufferUsed || wwo->writeBytes != wwo->sendBytes) {
    if (wwo->freeBytes)
       nas_send_buffer(wwo);
    AuHandleEvents(wwo->AuServ);
  }

  AuFlush(wwo->AuServ);
  return TRUE;
}
コード例 #3
0
static int nas_close(WINE_WAVEOUT* wwo)
{
  AuEvent ev;

  nas_free(wwo);

  AuStopFlow(wwo->AuServ, wwo->AuFlow, NULL);
  AuDestroyFlow(wwo->AuServ, wwo->AuFlow, NULL);
  AuFlush(wwo->AuServ);
  AuNextEvent(wwo->AuServ, AuTrue, &ev);
  AuDispatchEvent(wwo->AuServ, &ev);

  wwo->AuFlow = 0;
  wwo->open = 0;
  wwo->BufferUsed = 0;
  wwo->freeBytes = 0;
  wwo->SoundBuffer = NULL;
  return 1;
}
コード例 #4
0
/* StartRecording: open the device for recording.

   XXX this routine is almost identical to snd_Start().  The two should
   be factored into a single function!
*/
static int sound_StartRecording(int desiredSamplesPerSec, int stereo0, int semaIndex0)
{
  AuElement elements[2];  /* elements for the NAS flow to assemble:
   			        element 0 = physical input
			        element 1 = client export */
  AuDeviceID device;      /* physical device ID to use */
  
  DPRINTF("StartRecording\n");
  
  sound_Stop();

  DPRINTF("opening server\n");
  server = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL);
  if(server == NULL) {
    DPRINTF("failed to open audio server\n");
    return false;
  }

  /* XXX check protocol version of the server */

  semaIndex= semaIndex0;
  stereo= stereo0;
  sampleRate= desiredSamplesPerSec;

  device= choose_nas_device(server, desiredSamplesPerSec, stereo, 1);
  if(device == AuNone) {
    DPRINTF("no available device on the server!\n");
    AuCloseServer(server);
    server = NULL;
    return false;
  }

  /* record format info */
  fmtBytes=2;
  fmtSigned=1;
  fmtStereo=stereo;
  fmtIsBigendian=0;
  recording=1;


  

  /* create a flow to read from */
  DPRINTF("creating flow\n");
  flow = AuCreateFlow(server, NULL);


  /* create client and device elements to record with */
  DPRINTF("creating elements\n");

  
  AuMakeElementImportDevice(&elements[0],
			    desiredSamplesPerSec,  /* XXX should use the actual sampling rate of device */
			    device,
			    AuUnlimitedSamples,
			    0, NULL);

  AuMakeElementExportClient(&elements[1],
			    0,
			    desiredSamplesPerSec,
			    AuFormatLinearSigned16LSB,  /* XXX this should be chosen based on the platform */
			    stereo ? 2 : 1,
			    AuTrue,
			    1000000,  /* was AuUnlimitedSamples */
			    1000, /* water mark: go ahead and send frequently! */
			    0, NULL);
	


  /* set up the flow with these elements */
  AuSetElements(server,	flow,
		AuTrue,
		2, elements,
		NULL);

  /* start her up */
  DPRINTF("starting flow\n");
  AuStartFlow(server, flow, NULL);
  AuFlush(server);
  

  /* initialize the space indication */
  bytesAvail = 0;

  
  /* arrange to be informed when events come in from the server */
  aioEnable(AuServerConnectionNumber(server), NULL, AIO_EXT);
  aioHandle(AuServerConnectionNumber(server), handleAudioEvents, AIO_W);

  return true;
}
コード例 #5
0
static int sound_Start(int frameCount, int samplesPerSec, int stereo0, int semaIndex0)
{
  AuElement elements[2];  /* first is a client element, second is
			     a device output element */
  AuDeviceID device;        /* ID of the device to play to */
  

  /* open the server */
  DPRINTF("opening server\n");
  server = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL);
  if(server == NULL) {
    DPRINTF("failed to open audio server\n");
    return false;
  }

  /* XXX should check the protocol version! */

  /* record requested info */
  semaIndex = semaIndex0;
  stereo = stereo0;
  sampleRate= samplesPerSec;
  
  /* pick a device to play to */ 
  device = choose_nas_device(server, samplesPerSec, stereo, 0);
  if(device == AuNone) {
    DPRINTF("no available device on the server!\n");
    AuCloseServer(server);
    server = NULL;
    return false;
  }

  /* set up output parameters */
  fmtBytes=2;
  fmtSigned=1;
  fmtStereo=stereo;
  fmtIsBigendian=0;
  recording=0;
  


  /* create a flow to write on */
  DPRINTF("creating flow\n");
  flow = AuCreateFlow(server, NULL);


  /* create client and device elements to play with */
  DPRINTF("creating elements(%d,%d)\n",
	 frameCount, frameCount / 4);
  AuMakeElementImportClient(&elements[0],
			    samplesPerSec,
			    AuFormatLinearSigned16LSB,  /* XXX this should be chosen based on the platform */
			    stereo ? 2 : 1,
			    AuTrue,
			    2*frameCount,   /* max: 2 buffers */
			    frameCount,   /* low */
			    0, NULL);
	
  AuMakeElementExportDevice(&elements[1],
			    0,
			    device,
			    samplesPerSec,
			    AuUnlimitedSamples,
			    0, NULL);

  /* set up the flow with these elements */
  AuSetElements(server,	flow,
		AuTrue,
		2, elements,
		NULL);

  /* start her up */
  DPRINTF("starting flow\n");
  AuStartFlow(server, flow, NULL);
  AuFlush(server);
  

  /* initialize the space indication */
  bytesAvail = 0;

  
  /* arrange to be informed when events come in from the server */
  aioEnable(AuServerConnectionNumber(server), 0, AIO_EXT);
  aioHandle(AuServerConnectionNumber(server), handleAudioEvents, AIO_R);



  return true;
}
コード例 #6
0
/* Process audio events from the NAS server.  The same routine is used
   whether we are recording or playing back */
static void handleAudioEvents(int fd, void *data, int flags)
{
  if(!server) {
    DPRINTF( "handleAudioEvents called while unconnected!\n");
    return;
  }

  /* read events once */
  AuEventsQueued(server, AuEventsQueuedAfterReading);

  /* then loop through the read queue */
  while(AuEventsQueued(server, AuEventsQueuedAlready)) {
    AuEvent event;
    AuNextEvent(server, AuTrue, &event);
    DPRINTF("event of type %d\n", event.type);
    
    switch(event.type) {
    case 0:
      {
	AuErrorEvent *errEvent = (AuErrorEvent *) &event;
	char errdesc[1000];
      
	AuGetErrorText(server, errEvent->error_code, errdesc, sizeof(errdesc));
	fprintf(stderr, "audio error: %s\n", errdesc);
	sound_Stop();
	return;  /* return, not break, so that we don't
		    process the now-closed server any longer! */
      }
    

    case AuEventTypeElementNotify:
      {
	AuElementNotifyEvent *enEvent = (AuElementNotifyEvent *)&event;

	switch(enEvent->kind) {
	case AuElementNotifyKindLowWater:
	  DPRINTF("low water event\n");
	  bytesAvail += enEvent->num_bytes;
	  break;
	case AuElementNotifyKindHighWater:
	  DPRINTF("high water event\n");
	  bytesAvail += enEvent->num_bytes;
	  break;
	case AuElementNotifyKindState:
	  DPRINTF("state change (%d->%d)\n",
		  enEvent->prev_state,
		  enEvent->cur_state);
	  bytesAvail += enEvent->num_bytes;
	  if(enEvent->cur_state == AuStatePause) {
	       /* if the flow has stopped, then arrange for it to get started again */
	       /* XXX there is probably a more intelligent place to do
                  this, in case there is a real reason it has paused */
	       DPRINTF("unpausing\n");
	       AuStartFlow(server, flow, NULL);
	       AuFlush(server);
	  }

	  break;
	}
      }
    }
  }

  if(bytesAvail > 0) {
    DPRINTF("bytesAvail: %d\n", bytesAvail);
    signalSemaphoreWithIndex(semaIndex);
  }

  aioHandle(fd, handleAudioEvents, flags & AIO_RW);
}
コード例 #7
0
static int sound_PlaySamplesFromAtLength(int frameCount, int arrayIndex, int startIndex)
{
  int bytesToPlay;
  int framesToPlay;
  char *buf;   /* buffer to play from; it may not be arrayIndex if a
                  conversion is necessary */

  DPRINTF("PlaySamples(frameCount=%d, arrayIndex=%d, startIndex=%d\n",
	  frameCount, arrayIndex, startIndex);
  
  /* figure out how much to play */
  bytesToPlay = frameCount * bytesPerPlayFrame();
  if (bytesToPlay > bytesAvail)
    bytesToPlay = bytesAvail;
  
  framesToPlay = bytesToPlay / bytesPerPlayFrame();

  /* convert the buffer when not in stereo; when playing back, Squeak
     will send mono data as stereo, where the right channel is to be
     ignored */
  if(stereo)
    {
      buf= (char *) (arrayIndex + 4*startIndex);
    }
  else
    {
      int i;
      short *sbuf;  /* the buffer, as short's instead of char's */

      DPRINTF("converting\n");
      
      buf= malloc(2 * frameCount);
      if(buf == NULL)
	{
	  fprintf(stderr, "out of memory\n");
	  return 0;
	}
      sbuf= (short *) buf;
      

      for(i=0; i<frameCount; i++)
	{
	  sbuf[i]= ((short *) (arrayIndex + 4*startIndex)) [2*i];
	}
    }
      
	
  DPRINTF("writing %d bytes (%d frames)\n", bytesToPlay, framesToPlay);
  AuWriteElement(server, flow, 0,
		 bytesToPlay,
		 buf,
		 AuFalse,
		 NULL);
  AuFlush(server);
  

  bytesAvail -= bytesToPlay;

  if(!stereo)
    {
      free(buf);
    }
  
  return framesToPlay;
}