void end_audio_frame() { if (frame_offset == 0) // No audio added; blip_end_frame() dislikes being called with an // offset of 0 return; assert(!(is_backwards_frame && frame_offset != get_frame_len())); // Bring the signal level at the end of the frame to zero as outlined in // set_audio_signal_level() set_audio_signal_level(0); blip_end_frame(blip, frame_offset); if (playback_started) { // Fudge playback rate by an amount proportional to the difference // between the desired and current buffer fill levels to try to steer // towards it double const fudge_factor = 1.0 + 2*max_adjust*(0.5 - fill_level()); blip_set_rates(blip, cpu_clock_rate, sample_rate*fudge_factor); } else { if (fill_level() >= 0.5) { start_audio_playback(); playback_started = true; } } int const n_samples = blip_read_samples(blip, blip_samples, ARRAY_LEN(blip_samples), 0); // We expect to read all samples from blip_buf. If something goes wrong and // we don't, clear the buffer to prevent data piling up in blip_buf's // buffer (which lacks bounds checking). int const avail = blip_samples_avail(blip); if (avail != 0) { printf("Warning: didn't read all samples from blip_buf (%d samples remain) - dropping samples\n", avail); blip_clear(blip); } #ifdef RECORD_MOVIE add_movie_audio_frame(blip_samples, n_samples); #endif // Save the samples to the audio ring buffer lock_audio(); write_samples(blip_samples, n_samples); unlock_audio(); }
static void feed_data(GstElement * appsrc, guint size_hint, void *unused) { (void)size_hint; (void)unused; lock_audio(); /* Make sure we don't trigger a gst_element_set_state() call from inside gstreamer's stream thread as it will deadlock */ inside_feed_data = 1; pcm_play_get_more_callback((void **)&pcm_data, &pcm_data_size); if (pcm_data_size != 0) { GstBuffer *buffer = gst_buffer_new (); GstFlowReturn ret; GST_BUFFER_DATA (buffer) = pcm_data; GST_BUFFER_SIZE (buffer) = pcm_data_size; g_signal_emit_by_name (appsrc, "push-buffer", buffer, &ret); gst_buffer_unref (buffer); if (ret != 0) DEBUGF("push-buffer error result: %d\n", ret); pcm_play_dma_started_callback(); } else { DEBUGF("feed_data: No Data.\n"); g_signal_emit_by_name (appsrc, "end-of-stream", NULL); } inside_feed_data = 0; unlock_audio(); }
void pcm_play_unlock(void) { if (--audio_locked == 0) unlock_audio(); }