mirror of https://github.com/godotengine/godot
Use permanent audio buffer
As a side effect, fixes crackling sound when the audio buffer isn't big enough to hold a full Vorbis packet. Not related to the buffer being permanent but a bug in the previous code. It would happen when the video had 6 channel audio tracks.
This commit is contained in:
parent
06f865452f
commit
ca8664b4b6
|
|
@ -504,28 +504,32 @@ void VideoStreamPlaybackTheora::update(double p_delta) {
|
|||
ogg_packet op;
|
||||
|
||||
while (!audio_ready && !audio_done) {
|
||||
// Send remaining frames
|
||||
if (!send_audio()) {
|
||||
audio_ready = true;
|
||||
break;
|
||||
}
|
||||
|
||||
float **pcm;
|
||||
int ret = vorbis_synthesis_pcmout(&vd, &pcm);
|
||||
if (ret > 0) {
|
||||
const int AUXBUF_LEN = 4096;
|
||||
int to_read = ret;
|
||||
float aux_buffer[AUXBUF_LEN];
|
||||
while (to_read) {
|
||||
int m = MIN(AUXBUF_LEN / vi.channels, to_read);
|
||||
int frames_read = 0;
|
||||
while (frames_read < ret) {
|
||||
int m = MIN(AUXBUF_LEN / vi.channels, ret - frames_read);
|
||||
int count = 0;
|
||||
for (int j = 0; j < m; j++) {
|
||||
for (int i = 0; i < vi.channels; i++) {
|
||||
aux_buffer[count++] = pcm[i][j];
|
||||
audio_buffer[count++] = pcm[i][frames_read + j];
|
||||
}
|
||||
}
|
||||
int mixed = mix_callback(mix_udata, aux_buffer, m);
|
||||
to_read -= mixed;
|
||||
if (mixed != m) { //could mix no more
|
||||
frames_read += m;
|
||||
audio_ptr_end = m;
|
||||
if (!send_audio()) {
|
||||
audio_ready = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vorbis_synthesis_read(&vd, ret - to_read);
|
||||
vorbis_synthesis_read(&vd, frames_read);
|
||||
} else {
|
||||
/* no pending audio; is there a pending packet to decode? */
|
||||
if (ogg_stream_packetout(&vo, &op) > 0) {
|
||||
|
|
@ -649,6 +653,8 @@ void VideoStreamPlaybackTheora::seek(double p_time) {
|
|||
audio_done = !has_audio;
|
||||
theora_eos = false;
|
||||
vorbis_eos = false;
|
||||
audio_ptr_start = 0;
|
||||
audio_ptr_end = 0;
|
||||
|
||||
ogg_stream_reset(&to);
|
||||
if (has_audio) {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
|
|||
Point2i size;
|
||||
Rect2i region;
|
||||
|
||||
const static int AUXBUF_LEN = 4096;
|
||||
float audio_buffer[AUXBUF_LEN];
|
||||
int audio_ptr_start;
|
||||
int audio_ptr_end;
|
||||
|
||||
int buffer_data();
|
||||
int queue_page(ogg_page *page);
|
||||
int read_page(ogg_page *page);
|
||||
|
|
@ -108,6 +113,20 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
|
|||
protected:
|
||||
void clear();
|
||||
|
||||
_FORCE_INLINE_ bool send_audio() {
|
||||
if (audio_ptr_end > 0) {
|
||||
int mixed = mix_callback(mix_udata, &audio_buffer[audio_ptr_start * vi.channels], audio_ptr_end - audio_ptr_start);
|
||||
audio_ptr_start += mixed;
|
||||
if (audio_ptr_start == audio_ptr_end) {
|
||||
audio_ptr_start = 0;
|
||||
audio_ptr_end = 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual void play() override;
|
||||
virtual void stop() override;
|
||||
|
|
|
|||
Loading…
Reference in New Issue