Пример #1
0
static gboolean
gst_alsasink_unprepare (GstAudioSink * asink)
{
  GstAlsaSink *alsa;
  gint err;

  alsa = GST_ALSA_SINK (asink);

  CHECK (snd_pcm_drop (alsa->handle), drop);

  CHECK (snd_pcm_hw_free (alsa->handle), hw_free);

  return TRUE;

  /* ERRORS */
drop:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Could not drop samples: %s", snd_strerror (err)));
    return FALSE;
  }
hw_free:
  {
    GST_ELEMENT_ERROR (alsa, RESOURCE, SETTINGS, (NULL),
        ("Could not free hw params: %s", snd_strerror (err)));
    return FALSE;
  }
}
Пример #2
0
static int snd_pcm_file_hw_free(snd_pcm_t *pcm)
{
	snd_pcm_file_t *file = pcm->private_data;
	free(file->wbuf);
	free(file->wbuf_areas);
	file->wbuf = NULL;
	file->wbuf_areas = NULL;
	return snd_pcm_hw_free(file->gen.slave);
}
Пример #3
0
static gboolean
gst_alsasink_unprepare (GstAudioSink * asink)
{
    GstAlsaSink *alsa;

    alsa = GST_ALSA_SINK (asink);

    snd_pcm_drop (alsa->handle);
    snd_pcm_hw_free (alsa->handle);

    return TRUE;
}
Пример #4
0
static gboolean
gst_alsasrc_unprepare (GstAudioSrc * asrc)
{
  GstAlsaSrc *alsa;

  alsa = GST_ALSA_SRC (asrc);

  snd_pcm_drop (alsa->handle);
  snd_pcm_hw_free (alsa->handle);
  snd_pcm_nonblock (alsa->handle, 1);

  return TRUE;
}
Пример #5
0
int snd_pcm_close(snd_pcm_t *pcm)
{
	if (pcm->setup) {
		snd_pcm_drop(pcm);
		snd_pcm_hw_free(pcm);
	}
	_snd_pcm_munmap(pcm);
	snd_pcm_hw_munmap_status(pcm);
#if SALSA_HAS_ASYNC_SUPPORT
	if (pcm->async)
		snd_async_del_handler(pcm->async);
#endif
	close(pcm->fd);
	free(pcm);
	return 0;
}	
Пример #6
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);
}
Пример #7
0
int snd_pcm_generic_hw_free(snd_pcm_t *pcm)
{
    snd_pcm_generic_t *generic = pcm->private_data;
    return snd_pcm_hw_free(generic->slave);
}
Пример #8
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;
}
Пример #9
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;
}
Пример #10
0
/** Plays the audio contained packets queue that is filled by the 
 * chatting thread with received packets.
 */
void VoiceStreamer::playbackAudio() {
   int data_left, r;
   packet audioPacket;
   uint8_t *data_ptr;
   bool done = false;
   int pLatency = latency_min - 4;
   size_t pframes_in, pframes_out, pin_max;

   // Init playback device
   if (setparams_p(phandle, &pLatency) < 0) {
      fprintf(stderr, "Playback Audio Thread: exiting due to setparams_p error\n");
      return;
   }
   pframes_in = pframes_out = 0;
   pin_max = 0;

   while (true) {
      if (!popAudioPacket(audioPacket))
         break;
      
      data_ptr = audioPacket.data;
      data_left = (int) ntohs(audioPacket.dlength);
      while (pframes_in < loop_limit) {
         if (data_left > (pLatency<<2)) 
            r = pLatency;
         else
            r = data_left>>2;

         if (r > 0) {
            pframes_in += r;
            if ((int) pin_max < r)
               pin_max = r;

            if (writebuf(phandle, (char *) data_ptr, r, &pframes_out) < 0)  {
               break;
            }
         } else if (r == 0) { // done reading input file
            done = true;
            break;
         } else {
            break;
         }

         if (data_left > (pLatency<<2)) {
            data_ptr += (pLatency<<2);
            data_left -= (pLatency<<2);
         } else {
            data_ptr += data_left;
            data_left = 0;
         }
      }

      if (!done) {
         done = false;
         snd_pcm_nonblock(phandle, 0);
         snd_pcm_drain(phandle);
         snd_pcm_hw_free(phandle);

         pframes_in = pframes_out = pin_max = 0;
         if (setparams_p(phandle, &pLatency) < 0)  {
            fprintf(stderr, "setparams_p < 0!\n");
            break;
         }
      }
   }

   startPlayback = false;
   fprintf(stderr, "Playback Audio Thread exitting!\n");
}