예제 #1
0
int
sgi_audio_read(audio_desc_t ad, u_char *buf, int buf_bytes)
{
	long   		len;

        UNUSED(ad); assert(audio_fd > 0);
        
	if (non_block) {
		if ((len = ALgetfilled(rp)) < bytes_per_block )
			return (0);
                len = min(len, buf_bytes);
	} else {
		len = (long)buf_bytes;
        }

        len /= BYTES_PER_SAMPLE; /* We only open device in 16 bit mode */

	if (len > QSIZE) {
		fprintf(stderr, "audio_read: too big!\n");
		len = QSIZE;
	}

	ALreadsamps(rp, buf, len);

	return ((int)len * BYTES_PER_SAMPLE);
}
예제 #2
0
int  
sgi_audio_is_ready(audio_desc_t ad)
{
        UNUSED(ad); assert(audio_fd > 0);
        
        if (ALgetfilled(rp) >= ALgetfillpoint(rp)) {
                return TRUE;
        } else {
                return FALSE;
        }
}
예제 #3
0
/**
 * @brief  Read samples from device
 * 
 * Try to read @a sampnum samples and returns actual number of recorded
 * samples currently available.  This function will block until
 * at least one sample can be obtained.
 * 
 * @param buf [out] samples obtained in this function
 * @param sampnum [in] wanted number of samples to be read
 * 
 * @return actural number of read samples, -2 if an error occured.
 */
int
adin_mic_read(SP16 *buf, int sampnum)
{
  long cnt;

  cnt = ALgetfilled(aport);	/* get samples currently stored in queue */
  if (cnt > sampnum) cnt = sampnum;
  if (ALreadsamps(aport, buf, cnt) < 0) { /* get them */
    jlog("Error: adin_o2: failed to read sample\n");
    return(-2);			/* return negative on error */
  }
  return cnt;
}
예제 #4
0
파일: sound.c 프로젝트: hhirsch/netrek
/*
 * Clean up sound routines.
 */
void sfxEnd(int waitForSounds) {
	int idx;

	endingOnPurpose = 1;

	if (waitForSounds) {		/* wait for sounds to complete */
		for (idx=0; idx < nAudioPorts; idx++) {
			while (ALgetfilled(audioPort[idx]) > 0)
				sginap(1);

			ALcloseport(audioPort[idx]);
		}
	} else if (soundChild > 0)	/* kill childs playing sounds */
		kill(soundChild, SIGKILL);

	if (nAudioPorts > 0)		/* reset audio subsystem */
		sfxResetAudioHw();
}
예제 #5
0
파일: sound.c 프로젝트: hhirsch/netrek
/*
 * Sound handler.
 */
static void sfxSoundHandler(void *arg) {
	ALport *ap = (ALport *)arg;
	Sample samp[MAX_AUDIO_PORTS];

	int idx, nap;
	int treated;
	int nSounds = 1;
	int nextPort = 0;
	long maxSampsPerPass;
	long sampCount;
	long pvbuf[2];
	struct _sfx ss;
	struct pollfd pf;

	prctl(PR_TERMCHILD, 0);

	(void) signal(SIGHUP, sfxDieGracefully);

	maxSampsPerPass = 1600;

	for (idx=0; idx < nAudioPorts; idx++) {
		samp[idx].id = -1;
		samp[idx].sample = NULL;
		samp[idx].sampsToPlay = 0;
		samp[idx].repeat = 0;
	}

	/*
	 * Set sample rate for output device.
	 */
	pvbuf[0] = AL_OUTPUT_RATE;
	pvbuf[1] = AL_RATE_16000;

	(void) ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2L);

	/*
	 * Prepare to read from pipe.
	 */
	pf.fd = spigot[0];
	pf.events = POLLIN | POLLRDNORM | POLLRDBAND;

#define EVER ;;
	for (EVER) {
		if (nSounds == 0 || (idx=poll(&pf, 1, 0)) > 0) {
			(void) read(spigot[0], &ss, sizeof(ss));
			treated = 0;
			if (ss.loop == 1 && ss.repeat == 0) {
				treated = 1;
				for (idx=0; idx < nAudioPorts; idx++) {
					if (samp[idx].id == ss.id) {
						samp[idx].id = -1;
						samp[idx].repeat = 0;
						samp[idx].sampsToPlay = 0;
						samp[idx].sample = NULL;
					}
				}
			} else if (ss.loop == 1 && ss.count > 1) {
				for (idx=0; idx < nAudioPorts; idx++) {
					if (samp[idx].id == ss.id) {
						treated = 1;
						samp[idx].repeat = ss.repeat;
						samp[idx].sampsToPlay = (long)ss.soundSize[ss.pitch];
						samp[idx].sampsPlayed = 0;
						samp[idx].sample = ss.soundData[ss.pitch];
					}
				}
			}
			if (!treated) {
				for (idx=0; idx < nAudioPorts; idx++) {
					nextPort = (nextPort+1) % nAudioPorts;
					if (samp[nextPort].repeat == 0)
						break;
				}
				samp[nextPort].sample = ss.soundData[ss.pitch];
				samp[nextPort].sampsToPlay = (long)ss.soundSize[ss.pitch];
				samp[nextPort].sampsPlayed = 0;
				samp[nextPort].repeat = ss.repeat;
				samp[nextPort].id = ss.id;
			}
		} else if (idx < 0)
			(void) fprintf(stderr, "panic: input poll failed: %s\n", strerror(errno));

		nSounds = 0;
		nap = 0;

		for (idx=0; idx < nAudioPorts; idx++) {
			if (samp[idx].sampsToPlay > 0) {
				nSounds++;
				if (ALgetfilled(ap[idx]) > 4000) {
					nap++;
					continue;
				}
			}
			if (samp[idx].sampsToPlay >= maxSampsPerPass) {
				(void) ALwritesamps(ap[idx],
						    samp[idx].sample + samp[idx].sampsPlayed, maxSampsPerPass);
				samp[idx].sampsPlayed += maxSampsPerPass;
				samp[idx].sampsToPlay -= maxSampsPerPass;

			} else if (samp[idx].sampsToPlay > 0) {
				if ((samp[idx].sampsToPlay%2) == 1) {
					samp[idx].sampsToPlay -= 1;
					samp[idx].sampsPlayed += 1;
				}
				if (samp[idx].sampsToPlay > 0)
				    (void) ALwritesamps(ap[idx],
							samp[idx].sample+samp[idx].sampsPlayed, samp[idx].sampsToPlay);

				if (samp[idx].repeat) {
					sampCount = maxSampsPerPass - samp[idx].sampsToPlay;
					samp[idx].sampsToPlay += samp[idx].sampsPlayed - sampCount;
					samp[idx].sampsPlayed = sampCount;
					(void) ALwritesamps(ap[idx], samp[idx].sample, sampCount);
				} else
					samp[idx].sampsToPlay = 0;
			}
		}
		if (nap == nSounds)
			sginap(1);
	}
	return;
}
예제 #6
0
void MainLoop(ALport alp, FileDescriptor dacfd, FileDescriptor sockfd, SynthState *v1, SynthState *v2) {
/*    int hwm = 300, lwm = 256; */
    int hwm = 1000, lwm = 800;
    fd_set read_fds, write_fds;

    /* largest file descriptor to search for */    
    int	nfds = BIGGER_OF(dacfd, sockfd) + 1;

    printf("MainLoop: dacfd %d, sockfd %d, nfds %d\n", dacfd, sockfd, nfds);

    time_to_quit = 0;
    sigset(SIGINT, catch_sigint);       /* set sig handler       */

    while(!time_to_quit) {

	/* compute sine wave samples while the sound output buffer is below
	   the high water mark */

	while (ALgetfilled(alp) < hwm) {
	    Synthesize(alp, v1, v2);
	}

	/* Figure out the time tag corresponding to the time in the future that we haven't
	   computed any samples for yet. */
	OSCInvokeAllMessagesThatAreReady(OSCTT_PlusSeconds(OSCTT_CurrentTime(), 
							   ALgetfilled(alp) / the_sample_rate));

	/* set the low water mark, i.e. when we want control from select(2) */
	ALsetfillpoint(alp, OUTPUTQUEUESIZE - lwm);

	/* set up select */
	FD_ZERO(&read_fds);	/* clear read_fds */
	FD_ZERO(&write_fds);	/* clear write_fds */
	FD_SET(dacfd, &write_fds);
	FD_SET(sockfd, &read_fds); 

	FD_SET(0, &read_fds);	/* stdin */

	/* give control back to OS scheduler to put us to sleep until the DAC
	   queue drains and/or a character is available from standard input */

	if (select(nfds, &read_fds, &write_fds, (fd_set * )0, (struct timeval *)0) < 0) {
	    /* select reported an error */
	    perror("bad select"); 
	    goto quit;
	}

	if(FD_ISSET(sockfd, &read_fds)) {
	    ReceivePacket(sockfd);
	}

	/* is there a character in the queue? */
	if (FD_ISSET(0, &read_fds)) {
	    /* this will never block */
	    char c = getchar();

	    if (c == 'q') {
		/* quit */
		break;
	    } else if ((c <= '9') && (c >= '0')) {
		/* tweak frequency */
		v1->f = 440.0 + 100.0 * (c - '0');
	    }
	}
    }
quit:
    ALcloseport(alp);
    closeudp(sockfd);
}
예제 #7
0
/*---------------------------------------------------------------------------------------------------*/
static PaError Pa_SgiAudioProcess(internalPortAudioStream *past) /* Spawned by PaHost_StartEngine(). */
{
    PaError                 result = paNoError;
    PaHostSoundControl      *pahsc;
    
    if (!past)
        return paBadStreamPtr;
    pahsc = (PaHostSoundControl*)past->past_DeviceData;
	if (!pahsc)
        return paInternalError;
	past->past_IsActive = 1;            /* Wasn't this already done by the calling parent?!   */
    DBUG(("entering thread.\n"));

    while (!past->past_StopSoon)        /* OR-ing StopSoon and StopNow here gives problems! */
        {
        /*---------------------------------------- INPUT: ------------------------------------*/
        if (pahsc->pahsc_NativeInputBuffer)     /* Then pahsc_ALportIN should also be there!  */
            {
            while (ALgetfilled(pahsc->pahsc_ALportIN) < pahsc->pahsc_SamplesPerInputBuffer)
                {
                /* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */
                if (past->past_StopNow)    /* Don't let ALreadsamps() block */
                    goto done;
                }
            if (ALreadsamps(pahsc->pahsc_ALportIN, (void*)pahsc->pahsc_NativeInputBuffer,
                            pahsc->pahsc_SamplesPerInputBuffer))    /* Number of samples instead  */
                {                                                   /* of number of frames.       */
                ERR_RPT(("ALreadsamps() failed.\n"));
                result =  paInternalError;
                goto done;
                }
            }
        /*---------------------------------------------------- USER CALLBACK ROUTINE: ----------*/
        /* DBUG(("Calling Pa_CallConvertInt16()...\n")); */
        Pa_StartUsageCalculation(past);                     /* Convert 16 bit native data to    */
	    result = Pa_CallConvertInt16(past,                  /* user data and call user routine. */
				                 pahsc->pahsc_NativeInputBuffer, pahsc->pahsc_NativeOutputBuffer);
	    Pa_EndUsageCalculation(past);
	    if (result) 
		    {
			DBUG(("Pa_CallConvertInt16() returned %d, stopping...\n", result));
            goto done;                      /* This is apparently NOT an error!       */
		    }                               /* Just letting the userCallBack stop us. */
        /*---------------------------------------- OUTPUT: ------------------------------------*/
        if (pahsc->pahsc_NativeOutputBuffer)    /* Then pahsc_ALportOUT should also be there!  */
            {
            while (ALgetfillable(pahsc->pahsc_ALportOUT) < pahsc->pahsc_SamplesPerOutputBuffer)
                {
                /* Trying sginap(1); and usleep(); here... things get blocked under IRIX6.2. */
                if (past->past_StopNow)    /* Don't let ALwritesamps() block */
                    goto done;
                }
            if (ALwritesamps(pahsc->pahsc_ALportOUT, (void*)pahsc->pahsc_NativeOutputBuffer,
                             pahsc->pahsc_SamplesPerOutputBuffer))
                {
                ERR_RPT(("ALwritesamps() failed.\n"));
                result = paInternalError;
                goto done;
                }
            }
        /*-------------------------------------------------------------------------------------*/
        }
done:
    /* pahsc->pahsc_ThreadPID = -1;   Hu? doesn't help!! (added by Pieter) */
    past->past_IsActive = 0;
    DBUG(("leaving thread.\n"));
    return result;
}
예제 #8
0
static void
drain_audio_port (AudioContext ac)
{
  while (ALgetfilled (ac->ac_port) > 0)
    sginap(1);
}