Пример #1
0
void QAudioInputPrivate::reset()
{
    if(handle)
        snd_pcm_reset(handle);
    stop();
    bytesAvailable = 0;
}
void QAudioOutputPrivate::reset()
{
    if(handle)
        snd_pcm_reset(handle);

    stop();
}
Пример #3
0
void QAlsaAudioInput::reset()
{
    if(handle)
        snd_pcm_reset(handle);
    stop();
    bytesAvailable = 0;
}
Пример #4
0
static int snd_pcm_file_reset(snd_pcm_t *pcm)
{
	snd_pcm_file_t *file = pcm->private_data;
	int err = snd_pcm_reset(file->gen.slave);
	if (err >= 0) {
		/* FIXME: Questionable here */
		snd_pcm_file_write_bytes(pcm, file->wbuf_used_bytes);
		assert(file->wbuf_used_bytes == 0);
	}
	return err;
}
Пример #5
0
static int ao_alsa_play(dtaudio_output_t *aout, uint8_t * buf, int size)
{
    alsa_ctx_t *ctx = (alsa_ctx_t *)wrapper->ao_priv;
    snd_pcm_t *alsa_handle = (snd_pcm_t *) ctx->handle;

    int bytes_per_sample = wrapper->para.bps * wrapper->para.dst_channels / 8;
    int num_frames = size / bytes_per_sample;
    snd_pcm_sframes_t res = 0;
    uint8_t *data = buf;

    if (!alsa_handle) {
        return -1;
    }

    if (num_frames == 0) {
        return 0;
    }

    if (ao_alsa_level(aout) >= ctx->buf_threshold) {
        dt_debug(TAG, "ALSA EXCEED THRESHOLD,size:%d  thres:%d \n", ao_alsa_level(aout),
                 ctx->buf_threshold);
        return 0;
    }

    res = snd_pcm_writei(alsa_handle, data, num_frames);
    if (res == -EINTR) {
        dt_info(TAG, "ALSA HAS NO SPACE, WRITE AGAIN\n");
        return res;
    }
    if (res == -ESTRPIPE) {
        snd_pcm_resume(alsa_handle);
        return res;
    }
    if (res == -EBADFD) {
        snd_pcm_reset(alsa_handle);
        return res;
    }
    if (res < 0) {
        snd_pcm_prepare(alsa_handle);
        dt_info(TAG, "snd pcm write failed prepare!\n");
        return -1;
        //goto rewrite;
    }
    if (res < num_frames) {
        data += res * bytes_per_sample;
        num_frames -= res;
        //goto rewrite;
    }
    return res * bytes_per_sample;
}
Пример #6
0
void* capture_thread(void *arg)
{
    size_t capt_samples_num = samplerate / 1000 * frame_length;
    uint8_t *capt_buf = calloc(1, capt_samples_num * 2);
    assert(capt_buf != NULL);

    /* start the capture */
	snd_pcm_prepare(acapt_hdl);
    snd_pcm_start(acapt_hdl);
    snd_pcm_reset(acapt_hdl);

    while (!terminate_threads) {
		/* capture, track the capture time  */
        struct timeval start_ts, stop_ts;
        gettimeofday(&start_ts, NULL);

        if (!audio_capture_read(capt_buf, capt_samples_num))
            continue;

        gettimeofday(&stop_ts, NULL);
        uint32_t time_delta = (stop_ts.tv_sec - start_ts.tv_sec) * 1000000 +
                                        (stop_ts.tv_usec - start_ts.tv_usec);

        if (capt_min_time == 0)
            capt_min_time = time_delta;
        else
            capt_min_time = (time_delta < capt_min_time) ?
                                                time_delta : capt_min_time;

        if (capt_max_time == 0)
            capt_max_time = time_delta;
        else
            capt_max_time = (time_delta > capt_max_time) ?
                                                time_delta : capt_max_time;

        capt_time += time_delta;
        capt_buffers++;

        if (!spsc_circular_queue_push(queue, capt_buf)) {
            capt_buffers_dropped++;
            sched_yield();
        }
    }

    free(capt_buf);
    return NULL;
}
Пример #7
0
int snd_pcm_generic_reset(snd_pcm_t *pcm)
{
    snd_pcm_generic_t *generic = pcm->private_data;
    return snd_pcm_reset(generic->slave);
}
Пример #8
0
static snd_pcm_t *
alsa_open (int channels, unsigned samplerate, int realtime)
{	const char * device = "default" ;
	snd_pcm_t *alsa_dev = NULL ;
	snd_pcm_hw_params_t *hw_params ;
	snd_pcm_uframes_t buffer_size ;
	snd_pcm_uframes_t alsa_period_size, alsa_buffer_frames ;
	snd_pcm_sw_params_t *sw_params ;

	int err ;

	if (realtime)
	{	alsa_period_size = 256 ;
		alsa_buffer_frames = 3 * alsa_period_size ;
		}
	else
	{	alsa_period_size = 1024 ;
		alsa_buffer_frames = 4 * alsa_period_size ;
		} ;

	if ((err = snd_pcm_open (&alsa_dev, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
	{	fprintf (stderr, "cannot open audio device \"%s\" (%s)\n", device, snd_strerror (err)) ;
		goto catch_error ;
		} ;

	snd_pcm_nonblock (alsa_dev, 0) ;

	if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0)
	{	fprintf (stderr, "cannot allocate hardware parameter structure (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_any (alsa_dev, hw_params)) < 0)
	{	fprintf (stderr, "cannot initialize hardware parameter structure (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_access (alsa_dev, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
	{	fprintf (stderr, "cannot set access type (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_format (alsa_dev, hw_params, SND_PCM_FORMAT_FLOAT)) < 0)
	{	fprintf (stderr, "cannot set sample format (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_rate_near (alsa_dev, hw_params, &samplerate, 0)) < 0)
	{	fprintf (stderr, "cannot set sample rate (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_channels (alsa_dev, hw_params, channels)) < 0)
	{	fprintf (stderr, "cannot set channel count (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_buffer_size_near (alsa_dev, hw_params, &alsa_buffer_frames)) < 0)
	{	fprintf (stderr, "cannot set buffer size (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params_set_period_size_near (alsa_dev, hw_params, &alsa_period_size, 0)) < 0)
	{	fprintf (stderr, "cannot set period size (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_hw_params (alsa_dev, hw_params)) < 0)
	{	fprintf (stderr, "cannot set parameters (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	/* extra check: if we have only one period, this code won't work */
	snd_pcm_hw_params_get_period_size (hw_params, &alsa_period_size, 0) ;
	snd_pcm_hw_params_get_buffer_size (hw_params, &buffer_size) ;
	if (alsa_period_size == buffer_size)
	{	fprintf (stderr, "Can't use period equal to buffer size (%lu == %lu)", alsa_period_size, buffer_size) ;
		goto catch_error ;
		} ;

	snd_pcm_hw_params_free (hw_params) ;

	if ((err = snd_pcm_sw_params_malloc (&sw_params)) != 0)
	{	fprintf (stderr, "%s: snd_pcm_sw_params_malloc: %s", __func__, snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_sw_params_current (alsa_dev, sw_params)) != 0)
	{	fprintf (stderr, "%s: snd_pcm_sw_params_current: %s", __func__, snd_strerror (err)) ;
		goto catch_error ;
		} ;

	/* note: set start threshold to delay start until the ring buffer is full */
	snd_pcm_sw_params_current (alsa_dev, sw_params) ;

	if ((err = snd_pcm_sw_params_set_start_threshold (alsa_dev, sw_params, buffer_size)) < 0)
	{	fprintf (stderr, "cannot set start threshold (%s)\n", snd_strerror (err)) ;
		goto catch_error ;
		} ;

	if ((err = snd_pcm_sw_params (alsa_dev, sw_params)) != 0)
	{	fprintf (stderr, "%s: snd_pcm_sw_params: %s", __func__, snd_strerror (err)) ;
		goto catch_error ;
		} ;

	snd_pcm_sw_params_free (sw_params) ;

	snd_pcm_reset (alsa_dev) ;

catch_error :

	if (err < 0 && alsa_dev != NULL)
	{	snd_pcm_close (alsa_dev) ;
		return NULL ;
		} ;

	return alsa_dev ;
} /* alsa_open */
Пример #9
0
static ALuint ALSAProc(ALvoid *ptr)
{
    ALCdevice *Device = (ALCdevice*)ptr;
    alsa_data *data = (alsa_data*)Device->ExtraData;
    const snd_pcm_channel_area_t *areas = NULL;
    snd_pcm_uframes_t update_size, num_updates;
    snd_pcm_sframes_t avail, commitres;
    snd_pcm_uframes_t offset, frames;
    char *WritePtr;
    int err;

    SetRTPriority();

    update_size = Device->UpdateSize;
    num_updates = Device->NumUpdates;
    while(!data->killNow)
    {
        int state = verify_state(data->pcmHandle);
        if(state < 0)
        {
            ERR("Invalid state detected: %s\n", snd_strerror(state));
            aluHandleDisconnect(Device);
            break;
        }

        avail = snd_pcm_avail_update(data->pcmHandle);
        if(avail < 0)
        {
            ERR("available update failed: %s\n", snd_strerror(avail));
            continue;
        }

        if((snd_pcm_uframes_t)avail > update_size*(num_updates+1))
        {
            WARN("available samples exceeds the buffer size\n");
            snd_pcm_reset(data->pcmHandle);
            continue;
        }

        // make sure there's frames to process
        if((snd_pcm_uframes_t)avail < update_size)
        {
            if(state != SND_PCM_STATE_RUNNING)
            {
                err = snd_pcm_start(data->pcmHandle);
                if(err < 0)
                {
                    ERR("start failed: %s\n", snd_strerror(err));
                    continue;
                }
            }
            if(snd_pcm_wait(data->pcmHandle, 1000) == 0)
                ERR("Wait timeout... buffer size too low?\n");
            continue;
        }
        avail -= avail%update_size;

        // it is possible that contiguous areas are smaller, thus we use a loop
        while(avail > 0)
        {
            frames = avail;

            err = snd_pcm_mmap_begin(data->pcmHandle, &areas, &offset, &frames);
            if(err < 0)
            {
                ERR("mmap begin error: %s\n", snd_strerror(err));
                break;
            }

            WritePtr = (char*)areas->addr + (offset * areas->step / 8);
            aluMixData(Device, WritePtr, frames);

            commitres = snd_pcm_mmap_commit(data->pcmHandle, offset, frames);
            if(commitres < 0 || (commitres-frames) != 0)
            {
                ERR("mmap commit error: %s\n",
                    snd_strerror(commitres >= 0 ? -EPIPE : commitres));
                break;
            }

            avail -= frames;
        }
    }

    return 0;
}
Пример #10
0
void QAudioInputPrivate::reset()
{
    if(handle)
        snd_pcm_reset(handle);
}
Пример #11
0
/********************************************************
 *  playstereo                                          *
 *                                                      *
 * returns: 1 on successful play                        *
 *          -1 when soundfile does not play             *
 *          0 when soundfile plays with under.over run  *
 *******************************************************/
int playstereo(char *sfname1, char *sfname2, double breakpoint, double targlength, int targloc, int cueinterval, double period)
{
  
  SNDFILE *sf1, *sf2;
  SF_INFO *sfinfo1, *sfinfo2,*sfout_info;
  short *obuff, *obuff1, *obuff2;
  sf_count_t incount1, incount2;
  double padded;
  long pad = 0;
  int j= 0, loops = 0, cueframes, targframes, pauseframes, inframes, nspeak = 2, err, init;
  snd_pcm_uframes_t outframes, totframesout;
  unsigned short *ptr;
  int outsamprate = 44100;

  /* memory for SF_INFO structures */
  sfinfo1 = (SF_INFO *) malloc(sizeof(SF_INFO));
  sfinfo2 = (SF_INFO *) malloc(sizeof(SF_INFO));

  //fprintf(stderr, "trying to open '%s'\n", sfname); 
  /* open input files*/
  if(!(sf1 = sf_open(sfname1,SFM_READ,sfinfo1))){
    fprintf(stderr,"error opening input file %s\n",sfname1);
    return -1;
  }
  
  if(!(sf2 = sf_open(sfname2,SFM_READ,sfinfo2))){
    fprintf(stderr,"error opening input file %s\n",sfname2);
    return -1;
  }

  /* determine length inframes*/
  cueframes = (int) (breakpoint*outsamprate);
  pauseframes = (int) (cueinterval*outsamprate);
  targframes = (int) (targlength*outsamprate);
  inframes=(int)(cueframes+targframes);
  if(DEBUG){fprintf(stderr,"breakpoint:%g, cueframes:%i, pauseframes:%i targframes:%i, inframes:%i\n", breakpoint, cueframes, pauseframes, targframes, inframes);}
  /* allocate buffer memory */
  obuff1 = (short *) malloc(sizeof(int)*inframes);
  obuff2 = (short *) malloc(sizeof(int)*inframes);
  /* read the data */
  if(DEBUG){fprintf(stderr,"trying to sf_readf %d frames\n",(int)inframes);}
  incount1 = sf_readf_short(sf1, obuff1, inframes);
  if(DEBUG){fprintf(stderr,"got %d samples when I tried for %d from sf_readf_short()\n",(int)incount1, (int)inframes);}
  if(DEBUG){fprintf(stderr,"trying to sf_readf %d frames\n",(int)inframes);}
  incount2 = sf_readf_short(sf2, obuff2, inframes);
  if(DEBUG){fprintf(stderr,"got %d samples when I tried for %d from sf_readf_short()\n",(int)incount1, (int)inframes);}
  
  
  if (snd_pcm_prepare (handle) < 0) {
    fprintf (stderr, "cannot prepare audio interface for use\n");
    sf_close(sf1);
    free(sfinfo1);
    free(obuff1);
    sf_close(sf2);
    free(sfinfo2);
    free(obuff2);
    return -1;
  }
  if (snd_pcm_reset(handle)<0){
    fprintf (stderr, "cannot reset audio interface for use\n");
    return -1;
  }
  /* pad the file size up to next highest period count*/    
  pad = (period * ceil((nspeak*(inframes+pauseframes))/ period))-(nspeak*(inframes+pauseframes));
  padded = (nspeak*inframes)+pad;
  outframes = padded;
  
  obuff = (short *) malloc(sizeof(int)*outframes);
  if(DEBUG){fprintf(stderr,"outframes:%d, nspeak:%d, padded:%g, targloc:%i, cut: %i\n", (int)outframes, nspeak, padded, targloc,(int)(nspeak*cueframes));}
  /* combine individual buffers into obuff */
  loops=0;
  for (j=0; j<outframes; j=j+nspeak){
    loops++;
    if (j<(nspeak*cueframes)){
      obuff[j] = obuff1[j/nspeak];
      obuff[j+1] = obuff1[j/nspeak];
    }
    else if ((j >= (nspeak*cueframes)) & (j < (nspeak*(cueframes+pauseframes)))){
      obuff[j] = 0;
      obuff[j+1] = 0;
    }
    else if ((j >= (nspeak*(cueframes+pauseframes)))&(targloc == 1)){  /*MAKE SURE THIS CORRESPONDS TO RIGHT SPEAKER TARGET - should work if rt spk is set to channel 1*/
      obuff[j] = obuff1[j/nspeak-pauseframes];
      obuff[j+1] = obuff2[j/nspeak-pauseframes];
    }
    else if ((j>= (nspeak*(cueframes+pauseframes)))&(targloc == 2)){  /*MAKE SURE THIS CORRESPONDS TO LEFT  SPEAKER TARGET*/
      obuff[j] = obuff2[j/nspeak-pauseframes];
      obuff[j+1] = obuff1[j/nspeak-pauseframes];
    }
    else{
      fprintf(stderr,"ERROR: incompatable target location %i\n",targloc);
      return -1;
    }
  }
  sfout_info = (SF_INFO *) malloc(sizeof(SF_INFO));
  sfout_info->channels = nspeak;
  sfout_info->samplerate = 44100;
  sfout_info->format = sfinfo1->format;
  if(DEBUG){fprintf(stderr,"output file format:%x \tchannels: %d \tsamplerate: %d\n",sfout_info->format, sfout_info->channels, sfout_info->samplerate);}

  ptr = obuff;
  totframesout = 0;
  if(DEBUG){printf("outframes is now %d\n", (int) outframes);}
  /*start the actual playback*/
  while (outframes > 0) {
    err = snd_pcm_writei(handle,ptr, outframes);
    if (err < 0) {
      //init = 1;
      break;  /* skip one period */
    }
    if (snd_pcm_state(handle) == SND_PCM_STATE_RUNNING)
      //init = 0;

    totframesout += err;
    ptr += err * nspeak;
    outframes -= err;
    if(DEBUG){printf("outframes is now %d\n", (int) outframes);}
    if (outframes == 0){
      if(DEBUG){printf("outframes is zero so I'll break\n");}
      break;
    }
    /* it is possible, that the initial buffer cannot store */
    /* all data from the last period, so wait a while */
  }
  if(DEBUG==3){
    printf("exited while writei loop, so what am I waiting for?\n");
    printf("frames not played: %d \n", (int)outframes);
    printf("frames played: %d \n", (int) totframesout);
  }

  
 /*free up resources*/
  free(sfinfo1);free(sfinfo2);free(sfout_info);
  free(obuff);free(obuff1);free(obuff2);
  return 1;
 }
Пример #12
0
bool PAPlayer::OpenFile(const CFileItem& file, const CPlayerOptions &options)
{
  if (m_currentlyCrossFading) CloseFileInternal(false); //user seems to be in a hurry

  m_crossFading = g_guiSettings.GetInt("mymusic.crossfade");
  //no crossfading for cdda, cd-reading goes mad and no crossfading for last.fm doesn't like two connections
  if (file.IsCDDA() || file.IsLastFM()) m_crossFading = 0;
  if (m_crossFading && IsPlaying())
  {
    //do a short crossfade on trackskip
    //set to max 2 seconds for these prev/next transitions
    if (m_crossFading > 2) m_crossFading = 2;
    //queue for crossfading
    bool result = QueueNextFile(file, false);
    if (result)
    {
      //crossfading value may be update by QueueNextFile when nr of channels changed
      if (!m_crossFading) // swap to next track
        m_decoder[m_currentDecoder].SetStatus(STATUS_ENDED);
      else //force to fade to next track immediately
        m_forceFadeToNext = true;
    }
    return result;
  }

  // normal opening of file, nothing playing or crossfading not enabled
  // however no need to return to gui audio device
  CloseFileInternal(false);

  // always open the file using the current decoder
  m_currentDecoder = 0;

  if (!m_decoder[m_currentDecoder].Create(file, (__int64)(options.starttime * 1000), m_crossFading))
    return false;

  m_iSpeed = 1;
  m_bPaused = false;
  m_bStopPlaying = false;
  ResetTime();
  m_clock.SetSpeed(0);

  CLog::Log(LOGINFO, "PAP Player: Playing %s", file.m_strPath.c_str());

  m_clock.SetClock((__int64)(options.starttime * 1000));

  m_decoder[m_currentDecoder].GetDataFormat(&m_Channels, &m_SampleRate, &m_BitsPerSample);

  if (!CreateStream(m_currentStream, m_Channels, m_SampleRate, m_BitsPerSample))
  {
    m_decoder[m_currentDecoder].Destroy();
    CLog::Log(LOGERROR, "PAPlayer::Unable to create audio stream");
  }

  *m_currentFile = file;

  if (ThreadHandle() == NULL)
    Create();

  m_startEvent.Set();

  m_bIsPlaying = true;
  m_cachingNextFile = false;
  m_currentlyCrossFading = false;
  m_forceFadeToNext = false;
  m_bQueueFailed = false;

  m_decoder[m_currentDecoder].Start();  // start playback

  if (m_pStream[m_currentStream])
     snd_pcm_reset(m_pStream[m_currentStream]);

  if (m_pStream[m_currentStream])
     snd_pcm_pause(m_pStream[m_currentStream], 0);

  m_clock.SetSpeed(m_iSpeed);
  return true;
}