void QAudioInputPrivate::reset() { if(handle) snd_pcm_reset(handle); stop(); bytesAvailable = 0; }
void QAudioOutputPrivate::reset() { if(handle) snd_pcm_reset(handle); stop(); }
void QAlsaAudioInput::reset() { if(handle) snd_pcm_reset(handle); stop(); bytesAvailable = 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; }
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; }
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; }
int snd_pcm_generic_reset(snd_pcm_t *pcm) { snd_pcm_generic_t *generic = pcm->private_data; return snd_pcm_reset(generic->slave); }
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 */
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; }
void QAudioInputPrivate::reset() { if(handle) snd_pcm_reset(handle); }
/******************************************************** * 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; }
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; }