/** * Sends a chunk of silence to the audio outputs. This is called when * there is not enough decoded data in the pipe yet, to prevent * underruns in the hardware buffers. * * The player lock is not held. */ static bool player_send_silence(struct player *player) { assert(audio_format_defined(&player->play_audio_format)); struct music_chunk *chunk = music_buffer_allocate(player_buffer); if (chunk == NULL) { g_warning("Failed to allocate silence buffer"); return false; } #ifndef NDEBUG chunk->audio_format = player->play_audio_format; #endif size_t frame_size = audio_format_frame_size(&player->play_audio_format); /* this formula ensures that we don't send partial frames */ unsigned num_frames = sizeof(chunk->data) / frame_size; chunk->times = -1.0; /* undefined time stamp */ chunk->length = num_frames * frame_size; memset(chunk->data, 0, chunk->length); if (!audio_output_all_play(chunk)) { music_buffer_return(player_buffer, chunk); return false; } return true; }
struct music_chunk * decoder_get_chunk(struct decoder *decoder, struct input_stream *is) { struct decoder_control *dc = decoder->dc; enum decoder_command cmd; assert(decoder != NULL); if (decoder->chunk != NULL) return decoder->chunk; do { decoder->chunk = music_buffer_allocate(dc->buffer); if (decoder->chunk != NULL) { decoder->chunk->replay_gain_serial = decoder->replay_gain_serial; if (decoder->replay_gain_serial != 0) decoder->chunk->replay_gain_info = decoder->replay_gain_info; return decoder->chunk; } decoder_lock(dc); cmd = need_chunks(dc, is, true); decoder_unlock(dc); } while (cmd == DECODE_COMMAND_NONE); return NULL; }