Esempio n. 1
0
static void
alsa_play (int argc, char *argv [])
{	static float buffer [BUFFER_LEN] ;
	SNDFILE *sndfile ;
	SF_INFO sfinfo ;
	snd_pcm_t * alsa_dev ;
	int		k, readcount, subformat ;

	for (k = 1 ; k < argc ; k++)
	{	memset (&sfinfo, 0, sizeof (sfinfo)) ;

		printf ("Playing %s\n", argv [k]) ;
		if (! (sndfile = sf_open (argv [k], SFM_READ, &sfinfo)))
		{	puts (sf_strerror (NULL)) ;
			continue ;
			} ;

		if (sfinfo.channels < 1 || sfinfo.channels > 2)
		{	printf ("Error : channels = %d.\n", sfinfo.channels) ;
			continue ;
			} ;

		if ((alsa_dev = alsa_open (sfinfo.channels, (unsigned) sfinfo.samplerate, SF_FALSE)) == NULL)
			continue ;

		subformat = sfinfo.format & SF_FORMAT_SUBMASK ;

		if (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE)
		{	double	scale ;
			int 	m ;

			sf_command (sndfile, SFC_CALC_SIGNAL_MAX, &scale, sizeof (scale)) ;
			if (scale < 1e-10)
				scale = 1.0 ;
			else
				scale = 32700.0 / scale ;

			while ((readcount = sf_read_float (sndfile, buffer, BUFFER_LEN)))
			{	for (m = 0 ; m < readcount ; m++)
					buffer [m] *= scale ;
				alsa_write_float (alsa_dev, buffer, BUFFER_LEN / sfinfo.channels, sfinfo.channels) ;
				} ;
			}
		else
		{	while ((readcount = sf_read_float (sndfile, buffer, BUFFER_LEN)))
				alsa_write_float (alsa_dev, buffer, BUFFER_LEN / sfinfo.channels, sfinfo.channels) ;
			} ;

		snd_pcm_drain (alsa_dev) ;
		snd_pcm_close (alsa_dev) ;

		sf_close (sndfile) ;
		} ;

	return ;
} /* alsa_play */
Esempio n. 2
0
void sound_open(int outp)
{
    switch (outp) {
        case ALSA:
            alsa_open(DEVALSA);
            break;
        case DSP:
            dsp_open(DEVDSP);
            break;
        case STDOUT:
            stdout_open(DEVDSP);
            break;
        default:
            fprintf(stderr, "Unknown output method\n");
    }
}
Esempio n. 3
0
static void* alsa_audio_start(void *aux)
{
	audio_fifo_t *af = aux;
	snd_pcm_t *h = NULL;
	int c;
	int cur_channels = 0;
	int cur_rate = 0;

	audio_fifo_data_t *afd;

	for (;;) {
		afd = audio_get(af);

		if (!h || cur_rate != afd->rate || cur_channels != afd->channels) {
			if (h) snd_pcm_close(h);

			cur_rate = afd->rate;
			cur_channels = afd->channels;

            h = alsa_open("default", cur_rate, cur_channels);

            if (!h) {
                fprintf(stderr, "Unable to open ALSA device (%d channels, %d Hz), dying\n",
                        cur_channels, cur_rate);
                exit(1);
            }
		}

		c = snd_pcm_wait(h, 1000);

		if (c >= 0)
			c = snd_pcm_avail_update(h);

		if (c == -EPIPE)
			snd_pcm_prepare(h);

        snd_pcm_writei(h, afd->samples, afd->nsamples);
        writeFile( &afd->samples );
        zfree(afd);
	}
}
Esempio n. 4
0
struct audio_oops*
setup_alsa(const char *dev, const char *ctl)
{
  static int init_complete = 0;

  if(dev && strlen(dev) > 0) {
    device = strdup(dev);
  } else {
    device = strdup("plughw:0,0"); /* playback device */
  }

  if(init_complete) {
    ERRORLOG("already initialized\n");
    return NULL;
  }
  if(!alsa_open())
    init_complete = 1;
  else
    return NULL;

  return &alsa_oops;
}
Esempio n. 5
0
static void *playback_thread(void *cr) {
    struct _crad_t *p_crad = (struct _crad_t *)cr;
    snd_pcm_uframes_t playback_size, recording_size;

    snd_pcm_t *playback, *recording;

    alsa_open(&recording, SND_PCM_STREAM_CAPTURE, &recording_size);
    alsa_open(&playback,  SND_PCM_STREAM_PLAYBACK, &playback_size);
    snd_pcm_start(recording);


    snd_pcm_uframes_t recording_data[recording_size];

    while(p_crad->playback_thread_running) {
        // Figure out how many frames to read.  Take the minimum
        // available frames between playback and recording.
        int recording_avail = snd_pcm_avail_update(recording);
        int playback_avail  = snd_pcm_avail_update(playback);
        int frames_to_read;
        
        if(recording_avail < playback_avail)
            frames_to_read = recording_avail;
        else
            frames_to_read = playback_avail;

        // If we have less than 10ms of data, pause for 5ms and try again.
        if(frames_to_read < 441) {
            usleep(5000);
            continue;
        }

        int frames_read = snd_pcm_readi(recording,
                                        recording_data,
                                        frames_to_read);

        // If we didn't get enough data, wait, then try again.
        if(frames_read == -EAGAIN) {
            fprintf(stderr, "Read error, trying again: %s\n",
                    snd_strerror(frames_read));
            continue;
        }

        else if(frames_read == -EPIPE) {
            fprintf(stderr, "Read error: Overrun\n");
            if(alsa_recover(recording)) {
                p_crad->playback_thread_running = 0;
                break;
            }
            continue;
        }

        // Or if we had a different error, bail.
        else if(frames_read < 0) {
            fprintf(stderr, "Read error: %s\n", snd_strerror(frames_read));
            p_crad->playback_thread_running = 0;
            break;
        }



        while(frames_read > 0) {
            int frames_written;
            frames_written = snd_pcm_writei(playback, recording_data, frames_read);

            if(frames_written == -EPIPE) {
                fprintf(stderr, "Write error: Underrun\n");
                if(alsa_recover(playback)) {
                    p_crad->playback_thread_running = 0;
                    break;
                }
                continue;
            }

            else if(frames_written <= 0) {
                fprintf(stderr, "Write error (%d): %s\n",
                        frames_written, snd_strerror(frames_written));
                p_crad->playback_thread_running = 0;
                break;
            }
            else {
                frames_read -= frames_written;
            }
        }
    }

error:
    fprintf(stderr, "Quitting audio playback thread...\n");

    //snd_pcm_drain(recording);
    snd_pcm_close(recording);

    //snd_pcm_drain(playback);
    snd_pcm_close(playback);


    pthread_exit(NULL);
}
Esempio n. 6
0
int main(int argc, char **argv)
{
	int sd, rc, n, tmp;
	char msg[MAX_MSG];
	int nfds;
	int send_timestamp = 0;
	int recv_started = 0;
	struct pollfd *pfds;
	struct alsa_dev *dev;
	CELTEncoder *enc_state;
	CELTDecoder *dec_state;
	CELTMode *mode;
	struct sched_param param;
	JitterBuffer *jitter;
	SpeexEchoState *echo_state;
	char mac_own[6], mac_remote[6];

	if (argc != 4)
		panic("Usage %s plughw:0,0 <lmac in xx:xx:xx:xx:xx:xx> <rmac>\n", argv[0]);
 
	register_signal(SIGINT, sighandler);

	hack_mac(mac_own, argv[2], strlen(argv[2]));
	hack_mac(mac_remote, argv[3], strlen(argv[3]));
 
	sd = socket(AF_LANA, SOCK_RAW, 0);
	if (sd < 0)
		panic("%s: cannot open socket \n", argv[0]);

	printf("If ready hit key!\n"); //user must do binding
	getchar();

	dev = alsa_open(argv[1], SAMPLING_RATE, CHANNELS, FRAME_SIZE);

	mode = celt_mode_create(SAMPLING_RATE, FRAME_SIZE, NULL);
	enc_state = celt_encoder_create(mode, CHANNELS, NULL);
	dec_state = celt_decoder_create(mode, CHANNELS, NULL);

	param.sched_priority = sched_get_priority_min(SCHED_FIFO);
	if (sched_setscheduler(0, SCHED_FIFO, &param))
		whine("sched_setscheduler error!\n");
   
	/* Setup all file descriptors for poll()ing */
	nfds = alsa_nfds(dev);
	pfds = xmalloc(sizeof(*pfds) * (nfds + 1));

	alsa_getfds(dev, pfds, nfds);

	pfds[nfds].fd = sd;
	pfds[nfds].events = POLLIN;

	/* Setup jitter buffer using decoder */
	jitter = jitter_buffer_init(FRAME_SIZE);
	tmp = FRAME_SIZE;
	jitter_buffer_ctl(jitter, JITTER_BUFFER_SET_MARGIN, &tmp);

	/* Echo canceller with 200 ms tail length */
	echo_state = speex_echo_state_init(FRAME_SIZE, 10 * FRAME_SIZE);
	tmp = SAMPLING_RATE;
	speex_echo_ctl(echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &tmp);

	register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);

	alsa_start(dev);
	printf("ALSA started!\n");

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = interval;
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = interval;
	setitimer(ITIMER_REAL, &itimer, NULL);

	while (!sigint) {
		poll(pfds, nfds + 1, -1);

		/* Received packets */
		if (pfds[nfds].revents & POLLIN) {
			memset(msg, 0, MAX_MSG);
			n = recv(sd, msg, MAX_MSG, 0);
			if (n <= 0)
				goto do_alsa;
			pkts_in++;
			int recv_timestamp;
			memcpy(&recv_timestamp, msg, sizeof(recv_timestamp));
			JitterBufferPacket packet;
			packet.data = msg+4/*+6+6+2*/;
			packet.len = n-4/*-6-6-2*/;
			packet.timestamp = recv_timestamp;
			packet.span = FRAME_SIZE;
			packet.sequence = 0;

			/* Put content of the packet into the jitter buffer,
			   except for the pseudo-header */
			jitter_buffer_put(jitter, &packet);
			recv_started = 1;
		}
do_alsa:
		/* Ready to play a frame (playback) */
		if (alsa_play_ready(dev, pfds, nfds)) {
			short pcm[FRAME_SIZE * CHANNELS] = {0};
			if (recv_started) {
				JitterBufferPacket packet;
				/* Get audio from the jitter buffer */
				packet.data = msg;
				packet.len  = MAX_MSG;
				jitter_buffer_tick(jitter);
				jitter_buffer_get(jitter, &packet, FRAME_SIZE,
						  NULL);
				if (packet.len == 0)
					packet.data=NULL;
				celt_decode(dec_state, (const unsigned char *)
					    packet.data, packet.len, pcm);
			}
			/* Playback the audio and reset the echo canceller
			   if we got an underrun */

			alsa_write(dev, pcm, FRAME_SIZE);
//			if (alsa_write(dev, pcm, FRAME_SIZE)) 
//				speex_echo_state_reset(echo_state);
			/* Put frame into playback buffer */
//			speex_echo_playback(echo_state, pcm);
		}

		/* Audio available from the soundcard (capture) */
		if (alsa_cap_ready(dev, pfds, nfds)) {
			short pcm[FRAME_SIZE * CHANNELS];
			      //pcm2[FRAME_SIZE * CHANNELS];
			char outpacket[MAX_MSG];

			alsa_read(dev, pcm, FRAME_SIZE);
			/* Perform echo cancellation */
//			speex_echo_capture(echo_state, pcm, pcm2);
//			for (i = 0; i < FRAME_SIZE * CHANNELS; ++i)
//				pcm[i] = pcm2[i];

			celt_encode(enc_state, pcm, NULL, (unsigned char *)
				    (outpacket+4+6+6+2), PACKETSIZE);

			/* Pseudo header: four null bytes and a 32-bit
			   timestamp; XXX hack */
			memcpy(outpacket,mac_remote,6);
			memcpy(outpacket+6,mac_own,6);
			outpacket[6+6] = (uint8_t) 0xac;
			outpacket[6+6+1] = (uint8_t) 0xdc;
			memcpy(outpacket+6+6+2, &send_timestamp, sizeof(send_timestamp));
			send_timestamp += FRAME_SIZE;

			rc = sendto(sd, outpacket, PACKETSIZE+4+6+6+2, 0, NULL, 0);
			if (rc < 0)
				panic("cannot send to socket");
			pkts_out++;
		}
	}

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = 0;
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = 0;
	setitimer(ITIMER_REAL, &itimer, NULL); 

	close(sd);
	return 0;
}
Esempio n. 7
0
void
open_local_sound(char* adevice) {
	alsa_init(adevice);
	alsa_open(48000, 2, 8192);
}