示例#1
0
void alsamm_close_audio(void)
{
  int i,err;


#ifdef ALSAMM_DEBUG
  if(sys_verbose)
    post("closing devices");
#endif

  alsamm_stop();

  for(i=0;i< alsa_noutdev;i++){


#ifdef ALSAMM_DEBUG
    if(sys_verbose)
      post("unlink audio out %d, of %lx",i,used_outdevice[i]);
#endif

    if(alsa_outdev[i].a_synced != 0){
      if((err = snd_pcm_unlink(alsa_outdev[i].a_handle)) < 0)
        check_error(err, "snd_pcm_unlink (output)");
      alsa_outdev[i].a_synced = 0;
     }

    if((err = snd_pcm_close(alsa_outdev[i].a_handle)) <= 0)
      check_error(err, "snd_pcm_close (output)");

    if(alsa_outdev[i].a_addr){
      free(alsa_outdev[i].a_addr);
      alsa_outdev[i].a_addr = NULL;
    }
    alsa_outdev[i].a_channels = 0;
  }

  for(i=0;i< alsa_nindev;i++){

    err = snd_pcm_close(alsa_indev[i].a_handle);

    if(sys_verbose)
      check_error(err, "snd_pcm_close (input)");

    if(alsa_indev[i].a_addr){
      free(alsa_indev[i].a_addr);
      alsa_indev[i].a_addr = NULL;
    }

    alsa_indev[i].a_channels = 0;
  }
  alsa_nindev = alsa_noutdev = 0;
#ifdef ALSAMM_DEBUG
  if(sys_verbose)
    post("close_audio: after dacsend=%d (xruns=%d)done",dac_send,alsamm_xruns);
   alsamm_xruns = dac_send = 0;
#endif
}
示例#2
0
/** Fills the input buffer with audio data from the microphone.
 *
 * @param data the buffer to fill with audio data
 * @param len the size of the buffer
 * @return a pointer to the filled buffer
 */
uint16_t VoiceStreamer::fillBuffer(char *data, int len) {
   int latency, bufsize, room_left = len; 
   size_t frames_in, frames_out, in_max;
   ssize_t r;
   char *buffer, *data_ptr = data;
   bool done = false;

   latency = latency_min - 4;
   bufsize = (latency_max*snd_pcm_format_width(format)/8)*2;
   buffer = new char[bufsize];

   while (!done) {
      while (frames_in < loop_limit) {
         if ((r = readbuf(chandle, buffer, latency, &frames_in, 
               &in_max)) < 0) {
            break;
         } else {
            if (room_left > r<<2) {
               memcpy(data_ptr, buffer, r<<2);
               data_ptr += (r<<2);
               room_left -= (r<<2);
            } else {
               memcpy(data_ptr, buffer, room_left);
               data_ptr += room_left;
               room_left = 0;
               done = true;
               break;
            }
         } 
         
      }
      
      if (!done) {
         snd_pcm_drop(chandle);
         snd_pcm_unlink(chandle);
         snd_pcm_hw_free(chandle);
         
         frames_in = frames_out = in_max = 0;
         if (setparams_c(chandle, &latency) < 0) 
            break;
      }
   }

   return uint16_t (len - room_left);
}
示例#3
0
int main(int argc, char *argv[])
{
	struct option long_option[] =
	{
		{"help", 0, NULL, 'h'},
		{"pdevice", 1, NULL, 'P'},
		{"cdevice", 1, NULL, 'C'},
		{"min", 1, NULL, 'm'},
		{"max", 1, NULL, 'M'},
		{"frames", 1, NULL, 'F'},
		{"format", 1, NULL, 'f'},
		{"channels", 1, NULL, 'c'},
		{"rate", 1, NULL, 'r'},
		{"seconds", 1, NULL, 's'},
		{"block", 0, NULL, 'b'},
		{"time", 1, NULL, 't'},
		{"poll", 0, NULL, 'p'},
		{"effect", 0, NULL, 'e'},
		{NULL, 0, NULL, 0},
	};
	snd_pcm_t *phandle, *chandle;
	char *buffer;
	int err, latency, morehelp;
	int ok;
	snd_timestamp_t p_tstamp, c_tstamp;
	ssize_t r;
	size_t frames_in, frames_out, in_max;
	int effect = 0;
	morehelp = 0;
	while (1) {
		int c;
		if ((c = getopt_long(argc, argv, "hP:C:m:M:F:f:c:r:s:bt:pe", long_option, NULL)) < 0)
			break;
		switch (c) {
		case 'h':
			morehelp++;
			break;
		case 'P':
			pdevice = strdup(optarg);
			break;
		case 'C':
			cdevice = strdup(optarg);
			break;
		case 'm':
			err = atoi(optarg) / 2;
			latency_min = err >= 4 ? err : 4;
			if (latency_max < latency_min)
				latency_max = latency_min;
			break;
		case 'M':
			err = atoi(optarg) / 2;
			latency_max = latency_min > err ? latency_min : err;
			break;
		case 'f':
			format = snd_pcm_format_value(optarg);
			if (format == SND_PCM_FORMAT_UNKNOWN) {
				printf("Unknown format, setting to default S16_LE\n");
				format = SND_PCM_FORMAT_S16_LE;
			}
			break;
		case 'c':
			err = atoi(optarg);
			channels = err >= 1 && err < 1024 ? err : 1;
			break;
		case 'r':
			err = atoi(optarg);
			rate = err >= 4000 && err < 200000 ? err : 44100;
			break;
		case 's':
			err = atoi(optarg);
			loop_sec = err >= 1 && err <= 100000 ? err : 30;
			break;
		case 'b':
			block = 1;
			break;
		case 't':
			tick_time = atoi(optarg);
			tick_time = tick_time < 0 ? 0 : tick_time;
			break;
		case 'p':
			use_poll = 1;
			break;
		case 'e':
			effect = 1;
			break;
		}
	}

	if (morehelp) {
		help();
		return 0;
	}
	err = snd_output_stdio_attach(&output, stdout, 0);
	if (err < 0) {
		printf("Output failed: %s\n", snd_strerror(err));
		return 0;
	}

	loop_limit = loop_sec * rate;
	latency = latency_min - 4;
	buffer = malloc((latency_max * snd_pcm_format_width(format) / 8) * 2);

	setscheduler();

	printf("Playback device is %s\n", pdevice);
	printf("Capture device is %s\n", cdevice);
	printf("Parameters are %iHz, %s, %i channels, %s mode\n", rate, snd_pcm_format_name(format), channels, block ? "blocking" : "non-blocking");
	printf("Wanted tick time: %ius, poll mode: %s\n", tick_time, use_poll ? "yes" : "no");
	printf("Loop limit is %li frames, minimum latency = %i, maximum latency = %i\n", loop_limit, latency_min * 2, latency_max * 2);

	if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK, block ? 0 : SND_PCM_NONBLOCK)) < 0) {
		printf("Playback open error: %s\n", snd_strerror(err));
		return 0;
	}
	if ((err = snd_pcm_open(&chandle, cdevice, SND_PCM_STREAM_CAPTURE, block ? 0 : SND_PCM_NONBLOCK)) < 0) {
		printf("Record open error: %s\n", snd_strerror(err));
		return 0;
	}

	/* initialize the filter sweep variables */
	if (effect) {
		fs = (float) rate;
		BW = FILTER_BANDWIDTH;

		lfo = 0;
		dlfo = 2.*M_PI*FILTERSWEEP_LFO_FREQ/fs;

		x[0] = (float*) malloc(channels*sizeof(float));		
		x[1] = (float*) malloc(channels*sizeof(float));		
		x[2] = (float*) malloc(channels*sizeof(float));		
		y[0] = (float*) malloc(channels*sizeof(float));		
		y[1] = (float*) malloc(channels*sizeof(float));		
		y[2] = (float*) malloc(channels*sizeof(float));		
	}
			  
	while (1) {
		frames_in = frames_out = 0;
		if (setparams(phandle, chandle, &latency) < 0)
			break;
		showlatency(latency);
		if (tick_time_ok)
			printf("Using tick time %ius\n", tick_time_ok);
		if ((err = snd_pcm_link(chandle, phandle)) < 0) {
			printf("Streams link error: %s\n", snd_strerror(err));
			exit(0);
		}
		if (snd_pcm_format_set_silence(format, buffer, latency*channels) < 0) {
			fprintf(stderr, "silence error\n");
			break;
		}
		if (writebuf(phandle, buffer, latency, &frames_out) < 0) {
			fprintf(stderr, "write error\n");
			break;
		}
		if (writebuf(phandle, buffer, latency, &frames_out) < 0) {
			fprintf(stderr, "write error\n");
			break;
		}

		if ((err = snd_pcm_start(chandle)) < 0) {
			printf("Go error: %s\n", snd_strerror(err));
			exit(0);
		}
		gettimestamp(phandle, &p_tstamp);
		gettimestamp(chandle, &c_tstamp);
#if 0
		printf("Playback:\n");
		showstat(phandle, frames_out);
		printf("Capture:\n");
		showstat(chandle, frames_in);
#endif

		ok = 1;
		in_max = 0;
		while (ok && frames_in < loop_limit) {
			if (use_poll) {
				/* use poll to wait for next event */
				snd_pcm_wait(chandle, 1000);
			}
			if ((r = readbuf(chandle, buffer, latency, &frames_in, &in_max)) < 0)
				ok = 0;
			else {
				if (effect)
					applyeffect(buffer,r);
			 	if (writebuf(phandle, buffer, r, &frames_out) < 0)
					ok = 0;
			}
		}
		if (ok)
			printf("Success\n");
		else
			printf("Failure\n");
		printf("Playback:\n");
		showstat(phandle, frames_out);
		printf("Capture:\n");
		showstat(chandle, frames_in);
		showinmax(in_max);
		if (p_tstamp.tv_sec == p_tstamp.tv_sec &&
		    p_tstamp.tv_usec == c_tstamp.tv_usec)
			printf("Hardware sync\n");
		snd_pcm_drop(chandle);
		snd_pcm_nonblock(phandle, 0);
		snd_pcm_drain(phandle);
		snd_pcm_nonblock(phandle, !block ? 1 : 0);
		if (ok) {
#if 1
			printf("Playback time = %li.%i, Record time = %li.%i, diff = %li\n",
			       p_tstamp.tv_sec,
			       (int)p_tstamp.tv_usec,
			       c_tstamp.tv_sec,
			       (int)c_tstamp.tv_usec,
			       timediff(p_tstamp, c_tstamp));
#endif
			break;
		}
		snd_pcm_unlink(chandle);
		snd_pcm_hw_free(phandle);
		snd_pcm_hw_free(chandle);
	}
	snd_pcm_close(phandle);
	snd_pcm_close(chandle);
	return 0;
}
示例#4
0
static int alsa_stream(const char *pdevice, const char *cdevice, int latency)
{
    snd_pcm_t *phandle, *chandle;
    char *buffer;
    int err;
    ssize_t r;
    struct final_params negotiated;
    snd_pcm_format_t format = SND_PCM_FORMAT_S16_LE;
    char pdevice_new[32];

    err = snd_output_stdio_attach(&output, error_fp, 0);
    if (err < 0) {
        fprintf(error_fp, "alsa: Output failed: %s\n", snd_strerror(err));
        return 0;
    }

    /* Open the devices */
    if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK,
                            0)) < 0) {
        fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n",
                pdevice, snd_strerror(err));
        return 0;
    }
    if ((err = snd_pcm_open(&chandle, cdevice, SND_PCM_STREAM_CAPTURE,
                            SND_PCM_NONBLOCK)) < 0) {
        fprintf(error_fp, "alsa: Cannot open capture device %s: %s\n",
                cdevice, snd_strerror(err));
        snd_pcm_close(phandle);
        return 0;
    }

    err = setparams(phandle, chandle, format, latency, 0, &negotiated);

    /* Try to use plughw instead, as it allows emulating speed */
    if (err == 2 && strncmp(pdevice, "hw", 2) == 0) {

        snd_pcm_close(phandle);

        sprintf(pdevice_new, "plug%s", pdevice);
        pdevice = pdevice_new;
        if (verbose)
            fprintf(error_fp, "alsa: Trying %s for playback\n", pdevice);
        if ((err = snd_pcm_open(&phandle, pdevice, SND_PCM_STREAM_PLAYBACK,
                                0)) < 0) {
            fprintf(error_fp, "alsa: Cannot open playback device %s: %s\n",
                    pdevice, snd_strerror(err));
            snd_pcm_close(chandle);
            return 0;
        }

        err = setparams(phandle, chandle, format, latency, 1, &negotiated);
    }

    if (err != 0) {
        fprintf(error_fp, "alsa: setparams failed\n");
        snd_pcm_close(phandle);
        snd_pcm_close(chandle);
        return 1;
    }

    buffer = malloc((negotiated.bufsize * snd_pcm_format_width(format) / 8)
                    * negotiated.channels);
    if (buffer == NULL) {
        fprintf(error_fp, "alsa: Failed allocating buffer for audio\n");
        snd_pcm_close(phandle);
        snd_pcm_close(chandle);
        return 0;
    }

    if (verbose)
        fprintf(error_fp,
                "alsa: stream started from %s to %s (%i Hz, buffer delay = %.2f ms)\n",
                cdevice, pdevice, negotiated.rate,
                negotiated.latency * 1000.0 / negotiated.rate);

    while (!stop_alsa) {
        /* We start with a read and not a wait to auto(re)start the capture */
        r = readbuf(chandle, buffer, negotiated.bufsize);
        if (r == 0)   /* Succesfully recovered from an overrun? */
            continue; /* Force restart of capture stream */
        if (r > 0)
            writebuf(phandle, buffer, r);
        /* use poll to wait for next event */
        while (!stop_alsa && !snd_pcm_wait(chandle, 50))
            ;
    }

    snd_pcm_drop(chandle);
    snd_pcm_drop(phandle);

    snd_pcm_unlink(chandle);
    snd_pcm_hw_free(phandle);
    snd_pcm_hw_free(chandle);

    snd_pcm_close(phandle);
    snd_pcm_close(chandle);

    return 0;
}