bool WaveOutPulseAudio::CloseWaveOutDevice()
{
    bool     tResult = false;
    int      tRes;

    LOG(LOG_VERBOSE, "Going to close..");

    if (mWaveOutOpened)
    {
        StopFilePlayback();
        Stop();

        if (mOutputStream != NULL)
        {
            LOG(LOG_VERBOSE, "..draining stream");
            if (pa_simple_drain(mOutputStream, &tRes) < 0)
            {
                LOG(LOG_ERROR, "Couldn't drain the output stream because %s(%d)", pa_strerror(tRes), tRes);
            }
            LOG(LOG_VERBOSE, "..closing stream");
            pa_simple_free(mOutputStream);
        }

        LOG(LOG_INFO, "...closed");

        mWaveOutOpened = false;
        tResult = true;
    }else
        LOG(LOG_INFO, "...wasn't open");

     ResetPacketStatistic();

    return tResult;
}
예제 #2
0
static void pulse_thread(void *context)
{
#ifdef __linux__
    prctl(PR_SET_NAME, "deadbeef-pulse", 0, 0, 0, 0);
#endif

    trace ("pulse thread started \n");
    while (!pulse_terminate)
    {
        if (state != OUTPUT_STATE_PLAYING || !deadbeef->streamer_ok_to_read (-1))
        {
            usleep(10000);
            continue;
        }

        int sample_size = plugin.fmt.channels * (plugin.fmt.bps / 8);
        char buf[buffer_size];

        in_callback = 1;
        int bytesread = deadbeef->streamer_read(buf, buffer_size);
        in_callback = 0;
        if (pulse_terminate) {
            break;
        }
        if (bytesread < 0) {
            bytesread = 0;
        }

        int error;

        int res = 0;
        if (bytesread > 0) {
            deadbeef->mutex_lock (mutex);
            res = pa_simple_write(s, buf, bytesread, &error);
            deadbeef->mutex_unlock(mutex);
        }

        if (pulse_terminate) {
            break;
        }

        if (res < 0)
        {
            usleep(10000);
        }
    }

    deadbeef->mutex_lock (mutex);
    state = OUTPUT_STATE_STOPPED;
    if (s)
    {
        pa_simple_drain (s, NULL);
        pa_simple_free(s);
        s = NULL;
    }
    pulse_terminate = 0;
    pulse_tid = 0;
    deadbeef->mutex_unlock (mutex);
    trace ("pulse_thread finished\n");
}
예제 #3
0
static void flush()
{
	int error;

	if (pa_simple_drain(s, &error) < 0) {
		fprintf(stderr, "pulseaudio error: %s\n", pa_strerror(error));
	}
}
예제 #4
0
void	pulseaudio_close_audio(void) {
	if (!pulseaudio_audiodev_is_open) return;
	if (pa_simple_drain(s, &error) < 0) {
		fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error));
	}
	pa_simple_free(s);
	pulseaudio_audiodev_is_open = FALSE;
}
예제 #5
0
void mpgplayer::run()
{
    if(mpg123_init() != MPG123_OK)
        qDebug("Error initilizing mpg123");
    const char **test = mpg123_supported_decoders();
    int error;
    mpg123_handle *mh = mpg123_new(test[0],&error);
    if(!mpg123_feature(MPG123_FEATURE_DECODE_LAYER3))
    {
        qDebug("You do not seem to have mp3 decoding support");
        return;
    }
    mpg123_format_none(mh);
    if(mpg123_format(mh,samplerate,MPG123_STEREO,MPG123_ENC_SIGNED_16)!=MPG123_OK)
        qDebug("Error in initilizing format decoder");
    qDebug(test[0]);
    mpg123_open(mh,"/home/eli/Projects/groove-evan/Animal.mp3");
    net = TData;
    pa_simple *s;
    pa_sample_spec ss;
    ss.format = PA_SAMPLE_S16NE;
    ss.rate = samplerate;
    ss.channels = 2;
    s =pa_simple_new(NULL,"Groove",PA_STREAM_PLAYBACK ,NULL,"Music",&ss,NULL,NULL,NULL);

    unsigned char bytes[1024];
    size_t bsize = 1024;
    size_t done = 0;
    bool stop = false;
    playing=true;
    while(!stop)
    {
        switch(net)
        {
        case TWait: usleep(100); break;
        case TData:
            if(mpg123_read(mh,bytes,bsize,&done)==MPG123_DONE)
            {
                net=TFinish;
            }
            pa_simple_write(s,bytes,done,&error);
            break;
        case TAbort:
            stop = true;
            break;
        case TFinish:
            pa_simple_drain(s,&error);
            stop = true;
            break;
        default: break;
        }
    }
    qDebug("Finsihed playback");
    pa_simple_free(s);

    mpg123_exit();
}
예제 #6
0
void
ManglerPulse::close(bool drain) {/*{{{*/
   if (pulse_stream) {
        if (drain && pa_simple_drain(pulse_stream, &pulse_error) < 0) {
            fprintf(stderr, "pulse: pa_simple_drain() failed: %s\n", pa_strerror(pulse_error));
        }
        pa_simple_free(pulse_stream);
        pulse_stream = NULL;
    }
}/*}}}*/
예제 #7
0
int audio_drain_pulseaudio(cst_audiodev *ad)
{
    pa_simple *s;
    int err;

    s = (pa_simple *)ad->platform_data;
    pa_simple_drain(s,&err);
    
    return err;
}
예제 #8
0
static int pulseaudio_set_voice_position(ALLEGRO_VOICE *voice, unsigned int pos)
{
   PULSEAUDIO_VOICE *pv = voice->extra;

   pa_simple_drain(pv->s, NULL);
   
   al_lock_mutex(pv->buffer_mutex);
   voice->attached_stream->pos = pos;
   pv->buffer = (char*)voice->attached_stream->spl_data.buffer.ptr + pos * pv->frame_size;
   al_unlock_mutex(pv->buffer_mutex);

   return 0;
}
예제 #9
0
static void
pulse_drain (sw_handle * handle)
{
  struct pa_simple * pa ;
  int error;

  if ((pa = (struct pa_simple *)handle->custom_data) == NULL)
    return;

  if (pa_simple_drain(pa, &error) < 0) {
    fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error));
  }
}
예제 #10
0
int main(int argc, char *argv[])
{
    FILE *fp;
    int n;
    int16_t buf[BB], out[BB];
    int error;
    static const pa_sample_spec ss = {
        .format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 1};

    pa_simple *s = NULL;
    if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback",
                            &ss, NULL, NULL, &error)))
    {
        fprintf(stderr, __FILE__ ": pa_simple_new() failed: %s\n",
                pa_strerror(error));
        goto finish;
    }

    fp = fopen("out.wav", "rb");
    if (!fp)
        exit(-1);

    fread(buf, 1, 44, fp);
    n = fread(buf, 2, BB, fp);
    while (!feof(fp))
    {
        highpass(buf, out, BB, 1.0f, 10);
        memcpy(buf, out, BB * 2);
        lowpass(buf, out, BB, 1.0f / 44100.0f, 0.00002);
        if (pa_simple_write(s, out, (size_t)n * 2, &error) < 0)
        {
            fprintf(stderr, __FILE__ ": pa_simple_write() failed: %s\n",
                    pa_strerror(error));
            goto finish;
        }

        n = fread(buf, 2, BB, fp);
    }

    if (pa_simple_drain(s, &error) < 0)
    {
        fprintf(stderr, __FILE__ ": pa_simple_drain() failed: %s\n",
                pa_strerror(error));
        goto finish;
    }

finish:
    if (s)
        pa_simple_free(s);
    return 0;
}
예제 #11
0
static void pulse_connect(void) {
  static const pa_sample_spec ss = {.format = PA_SAMPLE_S16LE, .rate = 44100, .channels = 2};

  pa_dev = pa_simple_new(pulse_options.server, pulse_options.service_name, PA_STREAM_PLAYBACK,
                         pulse_options.sink, "Shairport Stream", &ss, NULL, NULL, &pa_error);

  if (!pa_dev)
    die("Could not connect to pulseaudio server: %s", pa_strerror(pa_error));
}

static void deinit(void) {
  if (pa_dev)
    pa_simple_free(pa_dev);
  pa_dev = NULL;
}

static void start(int sample_rate) {
  if (sample_rate != 44100)
    die("unexpected sample rate!");
}

static void play(short buf[], int samples) {
  if (pa_simple_write(pa_dev, (char *)buf, (size_t)samples * 4, &pa_error) < 0) {
    fprintf(stderr, __FILE__ ": pa_simple_write() failed: %s\n", pa_strerror(pa_error));
    if (pa_error == PA_ERR_CONNECTIONTERMINATED) {
      fprintf(stderr, __FILE__ ": reconnecting.");
      deinit();
      pulse_connect();
    }
  }
}

static void stop(void) {
  if (pa_simple_drain(pa_dev, &pa_error) < 0)
    fprintf(stderr, __FILE__ ": pa_simple_drain() failed: %s\n", pa_strerror(pa_error));
}

audio_output audio_pulse = {.name = "pulse",
                            .help = &help,
                            .init = &init,
                            .deinit = &deinit,
                            .start = &start,
                            .stop = &stop,
                            .flush = NULL,
                            .delay = NULL,
                            .play = &play,
                            .volume = NULL,
                            .parameters = NULL,
                            .mute = NULL};
예제 #12
0
int audio_close_pulseaudio(cst_audiodev *ad)
{
  int result;
  pa_simple *s;

  if (ad == NULL)
      return 0;

  s = (pa_simple *) ad->platform_data;

  pa_simple_drain(s,&result);

  pa_simple_free(s);
  cst_free(ad);
  return result;
}
예제 #13
0
static PyObject *simple_drain(simple *self) {
    int ret;

    if (!self->s) {
        PyErr_SetString(PyExc_RuntimeError, "Not connected to pulseaudio server");
        return Py_BuildValue("i", -1);
    }

    ret = pa_simple_drain(self->s, &self->error);

    if (ret < 0) {
        PyErr_SetString(PyExc_RuntimeError, pa_strerror(self->error));
        return Py_BuildValue("i", -2);
    }

    return Py_BuildValue("i", 0);
}
void WaveOutPulseAudio::Stop()
{
    int tRes;

    LOG(LOG_VERBOSE, "Stopping playback stream..");

    mPlayMutex.lock();

    if (!mWaveOutOpened)
    {
        // unlock grabbing
        mPlayMutex.unlock();

        LOG(LOG_VERBOSE, "Playback device wasn't opened yet");

        return;
    }

    if (mPlaybackStopped)
    {
        // unlock grabbing
        mPlayMutex.unlock();

        LOG(LOG_VERBOSE, "Playback was already stopped");

        return;
    }

    WaveOut::Stop();
    mFilePlaybackLoops = 0;

    if (mOutputStream != NULL)
    {
        LOG(LOG_VERBOSE, "..draining stream");
        if (pa_simple_drain(mOutputStream, &tRes) < 0)
        {
            LOG(LOG_ERROR, "Couldn't drain the output stream because %s(%d)", pa_strerror(tRes), tRes);
        }
    }

    // unlock grabbing
    mPlayMutex.unlock();
}
예제 #15
0
파일: ao_pulse.c 프로젝트: Distrotech/libao
int ao_plugin_close(ao_device *device) {
    assert(device && device->internal);
    ao_pulse_internal *internal = (ao_pulse_internal *) device->internal;

    if(internal->simple){

      /* this is a PulseAudio ALSA bug workaround;
         pa_simple_drain() always takes about 2 seconds, even if
         there's nothing to drain.  Rather than wait for no
         reason, determine the current playback depth, wait
         that long, then kill the stream.  Remove this code
         once Pulse gets fixed. */

      pa_usec_t us = pa_simple_get_latency(internal->simple, NULL);
      if(us<0 || us>1000000){
        pa_simple_drain(internal->simple, NULL);
      }else{
        us -= internal->static_delay;
        if(us>0){
          struct timespec sleep,wake;
          sleep.tv_sec = (int)(us/1000000);
          sleep.tv_nsec = (us-sleep.tv_sec*1000000)*1000;
          while(nanosleep(&sleep,&wake)<0){
            if(errno==EINTR)
              sleep=wake;
            else
              break;
          }
        }
      }

      pa_simple_free(internal->simple);
      internal->simple = NULL;
    }

    return 1;
}
예제 #16
0
void OutputPulseAudio::drain()
{
    int error;
    if (m_connection)
        pa_simple_drain(m_connection, &error);
}
예제 #17
0
파일: main_pulse.c 프로젝트: zwizwa/rai
int main(int argc, char*argv[]) {
    /* The Sample format to use */
    static const pa_sample_spec ss = {
        .format = PA_SAMPLE_S16LE,
        .rate = 44100,
        .channels = proc_size_out
    };

    LOG("channels = %d\n", ss.channels);

    pa_simple *s = NULL;
    int ret = 1;
    int error;

#if defined(proc_param_samplerate) && 0 == proc_param_samplerate
    LOG("samplerate = %d\n", ss.rate);
    param.samplerate = ss.rate;
#endif

#if defined(proc_param_timestep) && 0 == proc_param_timestep
    param.timestep = 1 / (float)ss.rate;
    LOG("timestep = %f\n", param.timestep);
#endif

    /* Output buffers.  FIXME: a_in: currently no inputs supported. */
    int nframes = 1024; // does this matter?
    for (int i=0; i < ss.channels; i++) a_out[i] = calloc(nframes, sizeof(float));
    uint16_t buf[nframes * ss.channels];

    /* Create a new playback stream */
    if (!(s = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) {
        fprintf(stderr, "pa_simple_new() failed: %d\n", error);
        goto exit;
    }

    /* Start reader */
    pthread_t thread;
    pthread_create(&thread, NULL, thread_main, NULL);

    unsigned int stamp = 0;
    for(;;) {  // FIXME: exit?

        proc_loop((void*)&state, &in, &param, &out, &store, nframes);

        for (int i=0; i<nframes; i++) {
            for(int c=0; c<ss.channels; c++) {
                buf[i*ss.channels+c] = ((float)0x7FFF) * a_out[c][i];
            }
        }

        if (pa_simple_write(s, buf, (size_t) sizeof(buf), &error) < 0) goto exit;

        // for live coding: exit when source file changed.
        if (argc >= 2) {
            struct stat s;
            stat(argv[1], &s);
            if (stamp && (stamp != s.st_mtime)) goto exit;
            stamp = s.st_mtime;
        }
    }
  exit:
    pa_simple_drain(s, &error); // ignore error
    if (s) pa_simple_free(s);
    return 0;
}
예제 #18
0
int main(int argc, char*argv[])
{
	/* The Sample format to use */
	static const pa_sample_spec ss =
	{
		.format = PA_SAMPLE_S16LE,
		.rate = 44100,
		.channels = 2
	};

	pa_simple* dev_out = 0;
	pa_simple* dev_in = 0;

	int ret = 1;
	int error;


	/* Create a new playback stream */
	if (!(dev_out = pa_simple_new(NULL, "Noise Remover", PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error)))
	{
		fprintf(stderr, __FILE__": pa_simple_new() failed: %dev_out\n", pa_strerror(error));
		goto finish;
	}
	if (!(dev_in = pa_simple_new(NULL, "Noise Remover", PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error)))
	{
		fprintf(stderr, __FILE__": pa_simple_new() failed: %dev_out\n", pa_strerror(error));
		goto finish;
	}

	{
		int i;
		float f;

		SpeexPreprocessState* pp = speex_preprocess_state_init(BUFSIZE, ss.rate);

		i = 1;       speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_DENOISE, &i);
		i = 1;       speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_AGC, &i);
		f = 8000;    speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &f);
		i = 1;       speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_DEREVERB, &i);
		f = 0.04;     speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_DEREVERB_DECAY, &f);
		f = 0.03;     speex_preprocess_ctl(pp, SPEEX_PREPROCESS_SET_DEREVERB_LEVEL, &f);

		double lowest_rms = 99999999999999;
		int silence_count = 0;

		for (;;)
		{
			int16_t buf[BUFSIZE];

			/* Read some data ... */
			if (pa_simple_read(dev_in, buf, sizeof(buf), &error) < 0)
			{
		        fprintf(stderr, __FILE__": pa_simple_read() failed: %s\n",  pa_strerror(error));
		        goto finish;
		    }

		    /* ... Use speex to de-noise ... */
		    double total = 0;
		    for(int n = 0; n < sizeof(buf); n++)
		    	total += buf[n] * buf[n];
		    double rms = std::sqrt(total / sizeof(buf));

		    if(rms < lowest_rms)
		    	lowest_rms = rms;
		    
			
		    if((rms - lowest_rms) < 50) // this value will probably need adjusting for you
		    	silence_count = 0;
			else if(silence_count < 10)
				silence_count++;

			if(silence_count == 10)
				speex_preprocess_run(pp, buf);
			else
				continue; // don't write it out...

			/* ... and play it */
			if (pa_simple_write(dev_out, buf, sizeof(buf), &error) < 0)
			{
				fprintf(stderr, __FILE__": pa_simple_write() failed: %dev_out\n", pa_strerror(error));
				goto finish;
			}
		}
		/* Make sure that every single sample was played */
		if (pa_simple_drain(dev_out, &error) < 0)
		{
			fprintf(stderr, __FILE__": pa_simple_drain() failed: %dev_out\n", pa_strerror(error));
			goto finish;
		}
	}
	ret = 0;
finish:
	if (dev_out)
		pa_simple_free(dev_out);
	if (dev_in)
		pa_simple_free(dev_in);
	return ret;
}
예제 #19
0
void *
microphone_writer_thread (void *)
{
#if INCLUDE_PULSEAUDIO
	/* The Sample format to use */
	const int BUFSIZE = 10240;
	pa_sample_spec ss;
	pa_buffer_attr buff;
	ss.format = PA_SAMPLE_S16LE;
	ss.rate = 48000;
	ss.channels = 1;

	pa_simple *s = NULL;
	int ret = 1;
	int error;

	/* Create a new playback stream */
	memset (&buff, 0, sizeof (buff));
	buff.maxlength = (uint32_t) -1;
	buff.tlength = (uint32_t) -1;
	buff.minreq = (uint32_t) -1;
	buff.prebuf = (uint32_t) -1;
	buff.tlength = (uint32_t) -1;
	if (!(s = pa_simple_new (NULL, "Moonlight Microphone Writer", PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, &buff, &error))) {
		Shocker_FailTestFast (g_strdup_printf ("microphone_writer_thread (): could not create pa stream: %s\n", pa_strerror (error)));
		goto finish;
	}

	while (1) {
		char *file = NULL;
		pthread_mutex_lock (&file_mutex);
		for (int i = 0; i < 6; i++) {
			if (mic_files [i] != NULL) {
				file = mic_files [i];
				for (int j = i + 1; j < 6; j++)
					mic_files [j - 1] = mic_files [j];
				mic_files [5] = NULL;
				break;
			}
		}
		if (file == NULL)
			running = false;
		pthread_mutex_unlock (&file_mutex);
		if (file == NULL) {
			printf ("microphone_writer_thread (): nothing more to write\n");
			break;
		}
		printf ("microphone_writer_thread (): reading %s\n", file);
	
		guint16 header [19];
	
		FILE *fd = fopen (file, "r");
		if (fd == NULL) {
			Shocker_FailTestFast (g_strdup_printf ("microphone_writer_thread (): could not open file %s: %s\n", file, strerror (errno)));
		}

		if (fread (header, 1, 38, fd) != 38) {
			Shocker_FailTestFast (g_strdup_printf ("microphone_writer_thread (): could not read file header of %s: %s\n", file, strerror (errno)));
		}

		int header_size = 20 + header [8] + (header [9] << 16) + 8;
		printf ("microphone_writer_thread (): skipping header to %s %i, wFormatTag: %i channels: %i samplesPerSec: %ihz BytesPerSec: %i BlockAlign: %i BitsPerSample: %i\n",
			file, header_size, header [10], header [11], (header [13] << 16) + header [12], (header [15] << 16) + header [14], header [16], header [17]);

		if (fseek (fd, header_size, SEEK_SET) != 0) {
			Shocker_FailTestFast (g_strdup_printf ("microphone_writer_thread (): could not seek beyond file header of %s at %i: %s\n", file, header_size, strerror (errno)));
		}
	
		while (1) {
			uint8_t buf[BUFSIZE];
			ssize_t r;

			r = fread (buf, 1, BUFSIZE, fd);
			if (r == 0) {
				printf ("microphone_writer_thread () eof: %s\n", file);
				break;
			}
	
			if (r < 0) {
				Shocker_FailTestFast (g_strdup_printf ("microphone_writer_thread (): read failed in %s: %s\n", file, strerror (errno)));
				break;
			}
	
			/* ... and play it */
			printf ("microphone_writer_thread () %s about to write %i bytes\n", file, (int) r);
			int pa_r = pa_simple_write (s, buf, (size_t) r, &error);
			if (r < 0) {
				Shocker_FailTestFast (g_strdup_printf ("microphone_writer_thread (): write failed: %s\n", pa_strerror (error)));
				break;
			} else {
				printf ("microphone_writer_thread () %s pa result: %i, wrote %i bytes\n", file, pa_r, (int) r);
			}
		}

		fclose (fd);
		g_free (file);
	}

	/* Make sure that every single sample was played */
	if (pa_simple_drain(s, &error) < 0) {
		Shocker_FailTestFast (g_strdup_printf ("microphone_writer_thread (): drain failed: %s\n", pa_strerror (error)));
		goto finish;
	}

	ret = 0;

finish:
	if (s)
		pa_simple_free(s);

#else
	Shocker_FailTestFast (g_strdup_printf ("microphone_writer_thread (): you need to build with pulseaudio support\n", filename, err->message));
#endif

	printf ("microphone_writer_thread (): done\n");
	return NULL;
}
예제 #20
0
파일: shusherd.c 프로젝트: shyPi/shyPi
void audio_trigger(context_t *context) {
  int input_fd = -1;
  static const pa_sample_spec ss = {
    .format = PA_SAMPLE_S16LE,
    .rate = 44100,
    .channels = 1
  };
  int error;

  daemon_log(LOG_INFO, "Trigger %s", context->shush_filename);

  if (context->points_threshold < 0) {
    daemon_log(LOG_INFO, "Threshold below 0, not triggering sound");
  }

  daemon_log(LOG_INFO,
             "Opening %s for output",
             context->output_device ?: "default sink");

  pa_simple *pa_output = pa_simple_new(
                              NULL,
                              "shusherd",
                              PA_STREAM_PLAYBACK,
                              context->output_device,
                              "playback",
                              &ss,
                              NULL,
                              NULL,
                              &error);
  if (!pa_output) {
    daemon_log(LOG_ERR, "pa_simple_new failed: %s", pa_strerror(error));
    goto finish;
  }

  input_fd = open(context->shush_filename, O_RDONLY);
  if (input_fd < 0) {
    daemon_log(LOG_ERR, "Error reading %s: %s", context->shush_filename, strerror(errno));
    goto finish;
  }

  for (;;) {
    uint8_t buf[BUFSIZE];
    ssize_t r;

    r = read(input_fd, buf, sizeof(buf));
    if (r < 0) {
      daemon_log(LOG_ERR, "read() failed: %s", strerror(errno));
      goto finish;
    }

    if (r == 0)
      goto finish;

    if (pa_simple_write(pa_output, buf, (size_t) r, &error) < 0) {
      daemon_log(LOG_ERR, "pa_simple_write() failed: %s", pa_strerror(errno));
      goto finish;
    }
  }

  if (pa_simple_drain(pa_output, &error) < 0) {
    daemon_log(LOG_ERR, "pa_simple_drain() failed: %s", pa_strerror(errno));
    goto finish;
  }

finish:
  if (input_fd > 0)
    close(input_fd);
  if (pa_output)
    pa_simple_free(pa_output);
}

void *audio_loop(void *context_p) {
  context_t *context = (context_t *)context_p;
  time_t t = time(NULL);
  double loudness;
  double points = 0.0;
  int error;

  //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);

  daemon_log(LOG_INFO, "Starting listening...");

  const short buf[BUFSIZE/2];

  int bytes = 0;
  int trigger = 0;
  int latest_trigger_time = 0;

  while (context->enable_processing) {
    if ((bytes = pa_simple_read(context->pa_input, (void *)buf, sizeof(buf), &error)) < 0) {
      daemon_log(LOG_ERR, "pa_simple_read failed: %s", pa_strerror(error));
      assert(0);
    }

    if ((time(NULL) - latest_trigger_time) < context->cooldown) {
      continue;
    }

    ebur128_add_frames_short(context->ebur128_state, buf, sizeof(buf)/2);

    if ((time(NULL) - t) > SAMPLE_TIME) {
      t = time(NULL);
      ebur128_loudness_shortterm(context->ebur128_state, &loudness);

      points += 100 - fabs(loudness);

      daemon_log(LOG_INFO, "Points: %f (%d) (%f)",
                 points, context->points_threshold, loudness);

      if (points > context->points_threshold) {
        trigger = 1;
      } else {
        points *= context->decay;
      }
    }

    if (trigger) {
      latest_trigger_time = time(NULL);
      audio_trigger(context);
      points = 0;
      trigger = 0;
      daemon_log(LOG_INFO,
                 "Waiting %d seconds before listening again",
                 context->cooldown);
    }
  }

  daemon_log(LOG_INFO, "Stopped listening...");

  return 0;
}
/**
    \fn    localInit
    \brief Take & initialize the device

*/
bool pulseSimpleAudioDevice::localInit(void) 
{
ADM_info("Pulse, initiliazing channel=%d samplerate=%d\n",(int)_channels,(int)_frequency);
pa_simple *s;
pa_sample_spec ss;
int er;
pa_buffer_attr attr;
pa_channel_map map,*pmap=NULL;
    attr.maxlength = (uint32_t) -1;
    attr.tlength = (uint32_t )-1;
    attr.prebuf =(uint32_t) -1;
    attr.minreq = (uint32_t) -1;
    attr.fragsize =(uint32_t) -1;

  // We want something like 20 ms latency
   uint64_t bufSize=_frequency;
            bufSize*=_channels;
            bufSize*=2;      // 1 second worth of audio

  bufSize=bufSize/1000;
  bufSize*=ADM_PULSE_LATENCY;
  attr.tlength=bufSize;       // Latency in bytes
 

  // Channel mapping
  if(_channels>2)
    {
        pmap=&map;
        map.channels=_channels;
        map.map[0]=PA_CHANNEL_POSITION_FRONT_LEFT;
        map.map[1]=PA_CHANNEL_POSITION_FRONT_RIGHT;
        map.map[2]=PA_CHANNEL_POSITION_FRONT_CENTER;
        map.map[3]=PA_CHANNEL_POSITION_REAR_LEFT;
        map.map[4]=PA_CHANNEL_POSITION_REAR_RIGHT;
        map.map[5]=PA_CHANNEL_POSITION_SUBWOOFER;
  }

  ss.format = PA_SAMPLE_S16LE;
  ss.channels = _channels;
  ss.rate =_frequency;
 
  instance= pa_simple_new(NULL,               // Use the default server.
                    "Avidemux2",           // Our application's name.
                    PA_STREAM_PLAYBACK,
                    NULL,               // Use the default device.
                    "Sound",            // Description of our stream.
                    &ss,                // Our sample format.
                    pmap,               // Use default channel map
                    &attr ,             // Use default buffering attributes.
                    &er               // Ignore error code.
                    );
  if(!instance)
    {
        ADM_info("[PulseSimple] open failed :%s\n",pa_strerror(er));
        return 0;
    }
#if 0
    pa_usec_t l=0;
    // Latency...
    Clock    ticktock;
    ticktock.reset();
    if(0>pa_simple_write(INSTANCE,silence, sizeOf10ms,&er))
    {
      fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(er));
    }
    pa_simple_drain(INSTANCE,&er);
    latency=ticktock.getElapsedMS();
    ADM_info("[Pulse] Latency :%"PRIu32", total %"PRIu32"\n",latency,pa_simple_get_latency(INSTANCE,&er)/1000);
#endif
    ADM_info("[PulseSimple] open ok for fq=%d channels=%d\n",ss.rate,ss.channels);
    return 1;

}
int main(int argc, char *argv[]) {
    long l_lWritecount = 0;
    pa_simple *l_SSimple = NULL;
    long l_lSizeonesec = (PLAY_FRAMES_PER_BUFFER * 2) * sizeof(float);

    /* Alloc size for one block */
    float *l_fSampleBlock = (float *)malloc(l_lSizeonesec);
    int l_iError = 0;
    struct sigaction l_SSa;

    static const pa_sample_spec l_SSs = {
         .format = PA_SAMPLE_FLOAT32,
         .rate = 44100,
         .channels = 2
    };

    printf("Playing file: '%s'\n", argv[1]);

    /* Open file. Because this is just a example we asume
      What you are doing and give file first argument */
    if (! (m_SInfile = sf_open(argv[1], SFM_READ, &m_SSfinfo))) {
        printf ("Not able to open input file %s.\n", argv[1]) ;
        sf_perror (NULL) ;
        return  1 ;
    }

    l_SSa.sa_flags = SA_SIGINFO;
    sigemptyset(&l_SSa.sa_mask);
    l_SSa.sa_sigaction = handler;

    if (sigaction(SIGINT, &l_SSa, NULL) == -1) {
        printf("Can't set SIGINT handler!\n");
        sf_close(m_SInfile);
        return -1;
    }

    if (sigaction(SIGHUP, &l_SSa, NULL) == -1) {
        printf("Can't set SIGHUP handler!\n");
        sf_close(m_SInfile);
        return -1;
    }

    /* Create a new playback stream */
    if (!(l_SSimple = pa_simple_new(NULL, "Simple example Pulseaudio playback application", PA_STREAM_PLAYBACK, NULL, "Playback", &l_SSs, NULL, NULL, &l_iError))) {
       fprintf(stderr, "main: pa_simple_new() failed: %s\n", pa_strerror(l_iError));
       goto exit;
    }

    fflush(stdout);

    while(1) {
        l_lWritecount = sf_read_float(m_SInfile, l_fSampleBlock, l_lSizeonesec / 4);

        if(l_lWritecount <= 0) {
            printf("** File has ended!\n");
            break;
        }

        if (pa_simple_write(l_SSimple, l_fSampleBlock, l_lWritecount * 4, &l_iError) < 0) {
            fprintf(stderr, "main: pa_simple_write() failed: %s (%ld)\n", pa_strerror(l_iError), l_lWritecount / 2);
            goto exit;
        }

        if(m_iLoop) {
           break;
        }
    }

    /* Make sure that every single sample was played */
    if (pa_simple_drain(l_SSimple, &l_iError) < 0) {
        fprintf(stderr, "main: pa_simple_drain() failed: %s\n", pa_strerror(l_iError));
        goto exit;
    }

exit:
    sf_close(m_SInfile);
    if (l_SSimple)
       pa_simple_free(l_SSimple);
    return 0;
}
예제 #23
0
static void *pulseaudio_update(ALLEGRO_THREAD *self, void *data)
{
   ALLEGRO_VOICE *voice = data;
   PULSEAUDIO_VOICE *pv = voice->extra;
   (void)self;

   for (;;) {
      enum PULSEAUDIO_VOICE_STATUS status;

      al_lock_mutex(voice->mutex);
      while ((status = pv->status) == PV_IDLE) {
         al_wait_cond(pv->status_cond, voice->mutex);
      }
      al_unlock_mutex(voice->mutex);

      if (status == PV_JOIN) {
         break;
      }

      if (status == PV_PLAYING) {
         unsigned int frames = pv->buffer_size_in_frames;
         if (voice->is_streaming) { 
            // streaming audio           
            const void *data = _al_voice_update(voice, voice->mutex, &frames);
            if (data) {
               pa_simple_write(pv->s, data,
                  frames * pv->frame_size_in_bytes, NULL);
            }
         }
         else {
            // direct buffer audio
            al_lock_mutex(pv->buffer_mutex);
            const char *data = pv->buffer;
            unsigned int len = frames * pv->frame_size_in_bytes;
            pv->buffer += frames * pv->frame_size_in_bytes;
            if (pv->buffer > pv->buffer_end) {
               len = pv->buffer_end - data;
               pv->buffer = voice->attached_stream->spl_data.buffer.ptr;
               voice->attached_stream->pos = 0;
               if (voice->attached_stream->loop == ALLEGRO_PLAYMODE_ONCE) {
                  al_lock_mutex(voice->mutex);
                  pv->status = PV_STOPPING;
                  al_broadcast_cond(pv->status_cond);
                  al_unlock_mutex(voice->mutex);
               }
            }
            else {
               voice->attached_stream->pos += frames;
            }
            al_unlock_mutex(pv->buffer_mutex);

            pa_simple_write(pv->s, data, len, NULL);
         }
      }
      else if (status == PV_STOPPING) {
         pa_simple_drain(pv->s, NULL);
         al_lock_mutex(voice->mutex);
         pv->status = PV_IDLE;
         al_broadcast_cond(pv->status_cond);
         al_unlock_mutex(voice->mutex);
      }
   }

   return NULL;
}
예제 #24
0
파일: pulseaudio.c 프로젝트: Voxar/spot
int pulseaudio_play (AUDIOCTX * actx)
{
	int error;
	pa_simple *s;
	pa_PRIVATE *priv = (pa_PRIVATE *) actx->driverprivate;
	bool quit = false;

	assert (priv != NULL);

	s = (pa_simple *) priv->pa_simple;

	/* Driver loop */
	for (;;) {

		uint8_t buf[1024];
		ssize_t r;

		/* Fetch state lock */
		pthread_mutex_lock (&priv->lock);

		switch (priv->state) {
		case PU_END:
			quit = true;
			break;

		case PU_PAUSED:
			/* Wait for unpause signal */
			pthread_cond_wait (&priv->pause, &priv->lock);
			break;

		case PU_PLAYING:
		case PU_IDLE:
		default:
			break;
		}

		pthread_mutex_unlock (&priv->lock);

		if (quit)
			break;

		/* Read some data ... */
		r = pcm_read (actx->pcmprivate, (char *) buf, sizeof (buf), 0,
			      2, 1, NULL);

		if (r == OV_HOLE) {	/* vorbis got garbage */
			DSFYDEBUG ("pcm_read() == %s\n", "OV_HOLE");
			continue;
		}

		if (r <= 0) {
			if (r == 0)	/* EOF */
				break;
			DSFYDEBUG ("pcm_read() failed == %zd\n", r);
			exit (-1);
		}

		/* ... and play it */
		if (pa_simple_write (s, buf, (size_t) r, &error) < 0) {
			DSFYDEBUG ("pa_simple_write() failed: %s\n",
				   pa_strerror (error))
				exit (-1);
		}
	}

	/* Make sure that every single sample was played */
	if (pa_simple_drain (s, &error) < 0) {
		DSFYDEBUG ("pa_simple_drain() failed: %s\n",
			   pa_strerror (error))
			exit (-1);
	}

	if (s)
		pa_simple_free (s);

        pthread_cond_signal (&priv->end);

	/* This will kill the thread */
	return 0;
}
예제 #25
0
int main(int argc, char **argv)
{
    if (argc != 1 && argc != 2) {
        fprintf(stderr, "usage: %s [sink_name] < input_file\n", argv[0]);
        exit(1);
    }

    const char *server_name = NULL;
    const char *client_name = "example play simple";
    const char *sink_name = NULL;
    const char *stream_name = "example stream";

    if (argc > 1) {
        sink_name = argv[1];
    }

    pa_sample_spec sample_spec = {};
    sample_spec.format = PA_SAMPLE_FLOAT32LE;
    sample_spec.rate = 44100;
    sample_spec.channels = 2;

    int error = 0;
    pa_simple *simple = pa_simple_new(
        server_name,
        client_name,
        PA_STREAM_PLAYBACK,
        sink_name,
        stream_name,
        &sample_spec,
        NULL,
        NULL,
        &error);

    if (simple == NULL) {
        fprintf(stderr, "pa_simple_new: %s\n", pa_strerror(error));
        exit(1);
    }

    const pa_usec_t start_time = pa_rtclock_now();
    uint64_t n_bytes = 0;

    for (;;) {
        char buf[1024];
        ssize_t sz = read(STDIN_FILENO, buf, sizeof(buf));
        if (sz == -1) {
            fprintf(stderr, "read: %s\n", strerror(errno));
            exit(1);
        }

        if (sz == 0) {
            break;
        }

        print_info(simple, &sample_spec, start_time, n_bytes);

        if (pa_simple_write(simple, buf, (size_t)sz, &error) != 0) {
            fprintf(stderr, "pa_simple_write: %s\n", pa_strerror(error));
            exit(1);
        }

        n_bytes += (uint64_t)sz;
    }

    /* wait until all samples are sent and played on server */
    if (pa_simple_drain(simple, &error) != 0) {
        fprintf(stderr, "pa_simple_drain: %s\n", pa_strerror(error));
        exit(1);
    }

    print_info(simple, &sample_spec, start_time, n_bytes);

    pa_simple_free(simple);

    return 0;
}