static int init(int argc, char **argv);
static void deinit(void);
static void start(int i_sample_rate, int i_sample_format);
-static void play(short buf[], int samples);
+static void play(void *buf, int samples);
static void stop(void);
static void flush(void);
int delay(long *the_delay);
}
}
-static void play(short buf[], int samples) {
+static void play(void *buf, int samples) {
// debug(3,"audio_alsa play called.");
int ret = 0;
if (alsa_handle == NULL) {
if (samples == 0)
debug(1, "empty buffer being passed to pcm_writei -- skipping it");
if ((samples != 0) && (buf != NULL)) {
- err = alsa_pcm_write(alsa_handle, (char *)buf, samples);
+ err = alsa_pcm_write(alsa_handle, buf, samples);
if (err < 0) {
debug(1, "Error %d writing %d samples in play(): \"%s\".", err, samples,
snd_strerror(err));
do_mute(1);
if (alsa_handle) {
- debug(1,"Start drain.");
- if ((derr = snd_pcm_drain(alsa_handle)))
- debug(1, "Error %d (\"%s\") draining output device.", derr, snd_strerror(derr));
- debug(1,"Finish drain.");
+ if ((derr = snd_pcm_drop(alsa_handle)))
+ debug(1, "Error %d (\"%s\") dropping output device.", derr, snd_strerror(derr));
if ((derr = snd_pcm_hw_free(alsa_handle)))
debug(1, "Error %d (\"%s\") freeing the output device hardware.", derr, snd_strerror(derr));
// flush also closes the device
if ((derr = snd_pcm_close(alsa_handle)))
debug(1, "Error %d (\"%s\") closing the output device.", derr, snd_strerror(derr));
+
alsa_handle = NULL;
}
pthread_mutex_unlock(&alsa_mutex);
static void init_buffer(rtsp_conn_info *conn) {
int i;
for (i = 0; i < BUFFER_FRAMES; i++)
- conn->audio_buffer[i].data = malloc(
- conn->input_bytes_per_frame * (conn->max_frames_per_packet + conn->max_frame_size_change));
+ conn->audio_buffer[i].data = malloc(conn->input_bytes_per_frame * conn->max_frames_per_packet);
ab_resync(conn);
}
// ab_write),ab_read,ab_write);
conn->ab_buffering = 0;
}
- signed short *silence;
+ void *silence;
// if (fs==0)
// debug(2,"Zero length silence buffer needed with gross_frame_gap of %lld and
// dac_delay of %lld.",gross_frame_gap,dac_delay);
// the fs (number of frames of silence to play) can be zero in the DAC doesn't
// start
- // ouotputting frames for a while -- it could get loaded up but not start
+ // outputting frames for a while -- it could get loaded up but not start
// responding
// for many milliseconds.
if (fs > 0) {
// debug(1,"Back end has no delay function.");
// send the appropriate prefiller here...
- signed short *silence;
+ void *silence;
if (lead_time != 0) {
int64_t frame_gap = (lead_time * config.output_rate) >> 32;
// debug(1,"%d frames needed.",frame_gap);
if (silence == NULL)
debug(1, "Failed to allocate %d frame silence buffer.", fs);
else {
- // debug(1, "Outputting %d frames of silence.", fs);
+ // debug(1, "No delay function -- outputting %d frames of silence.", fs);
memset(silence, 0, conn->output_bytes_per_frame * fs);
config.output->play(silence, fs);
free(silence);
static char rnstate[256];
initstate(time(NULL), rnstate, 256);
- signed short *inbuf, *tbuf, *silence;
+ signed short *inbuf, *tbuf;
int32_t *sbuf;
die("Failed to allocate memory for the transition buffer.");
sbuf = 0;
// initialise this, because soxr stuffing might be chosen later
- // if (config.packet_stuffing == ST_soxr) { // needed for stuffing
+
sbuf = malloc(sizeof(int32_t) * 2 * (conn->max_frames_per_packet * conn->output_sample_ratio +
conn->max_frame_size_change));
if (sbuf == NULL)
debug(1, "Failed to allocate memory for the sbuf buffer.");
- // }
- // We might need an output buffer and a buffer of silence.
+
// The size of these dependents on the number of frames, the size of each frame and the maximum
// size change
outbuf = malloc(
(conn->max_frames_per_packet * conn->output_sample_ratio + conn->max_frame_size_change));
if (outbuf == NULL)
die("Failed to allocate memory for an output buffer.");
- silence = malloc(conn->output_bytes_per_frame * conn->max_frames_per_packet *
- conn->output_sample_ratio);
- if (silence == NULL)
- die("Failed to allocate memory for a silence buffer.");
- memset(silence, 0,
- conn->output_bytes_per_frame * conn->max_frames_per_packet * conn->output_sample_ratio);
conn->first_packet_timestamp = 0;
conn->missing_packets = conn->late_packets = conn->too_late_packets = conn->resend_requests = 0;
conn->flush_rtp_timestamp =
conn->play_number_after_flush++;
if (inframe->timestamp == 0) {
debug(3, "Player has supplied a silent frame, (possibly frame %u) for play number %d.",
- SUCCESSOR(conn->last_seqno_read),play_number);
+ SUCCESSOR(conn->last_seqno_read), play_number);
conn->last_seqno_read = (SUCCESSOR(conn->last_seqno_read) &
0xffff); // manage the packet out of sequence minder
- config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio);
+
+ void *silence = malloc(conn->output_bytes_per_frame * conn->max_frames_per_packet *
+ conn->output_sample_ratio);
+ if (silence == NULL) {
+ debug(1, "Failed to allocate memory for a silent frame silence buffer.");
+ } else {
+ // the player may change the contents of the buffer, so it has to be zeroed each time;
+ // might as well malloc and freee it locally
+ memset(silence, 0, conn->output_bytes_per_frame * conn->max_frames_per_packet *
+ conn->output_sample_ratio);
+ config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio);
+ free(silence);
+ }
} else if (conn->play_number_after_flush < 10) {
/*
int64_t difference = 0;
debug(1, "Play number %d, monotonic timestamp %llx, difference
%lld.",conn->play_number_after_flush,inframe->timestamp,difference);
*/
- config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio);
+ void *silence = malloc(conn->output_bytes_per_frame * conn->max_frames_per_packet *
+ conn->output_sample_ratio);
+ if (silence == NULL) {
+ debug(1, "Failed to allocate memory for a flush silence buffer.");
+ } else {
+ // the player may change the contents of the buffer, so it has to be zeroed each time;
+ // might as well malloc and freee it locally
+ memset(silence, 0, conn->output_bytes_per_frame * conn->max_frames_per_packet *
+ conn->output_sample_ratio);
+ config.output->play(silence, conn->max_frames_per_packet * conn->output_sample_ratio);
+ free(silence);
+ }
} else if (frames_to_drop) {
if (frames_to_drop > 3 * config.output_rate)
warn("Very large number of frames to drop: %" PRId64 ".", frames_to_drop);
die("Failed to allocate memory for a long_silence buffer of %d frames.",
silence_length);
memset(long_silence, 0, conn->output_bytes_per_frame * silence_length);
- config.output->play((short *)long_silence, silence_length);
+ config.output->play(long_silence, silence_length);
free(long_silence);
}
} else {
if (play_samples == 0)
debug(1, "play_samples==0 skipping it (1).");
else
- config.output->play((short *)outbuf, play_samples); // remove the (short*)!
+ config.output->play(outbuf, play_samples);
}
// check for loss of sync
if (outbuf == NULL)
debug(1, "NULL outbuf to play -- skipping it.");
else
- config.output->play((short *)outbuf, play_samples); // remove the (short*)!
+ config.output->play(outbuf, play_samples); // remove the (short*)!
}
// mark the frame as finished
}
if (outbuf)
free(outbuf);
- if (silence)
- free(silence);
if (tbuf)
free(tbuf);
if (sbuf)