Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorPeter Schlaile <peter@schlaile.de>2009-06-01 20:35:05 +0400
committerPeter Schlaile <peter@schlaile.de>2009-06-01 20:35:05 +0400
commit2a3627e338516646d3e68f4db6147a80410bcf1f (patch)
treeff4008e2a7d15a79580419c3bb9835e2c418703c /source
parentaf42ee43be7845870655f26e26b6838c396377ba (diff)
== Sequencer ==
This fixes: [#18507] Wrong audio mixdown Also: you can change output sample rate while blender is running and the audio device get's reopened automatically. Subframe-precision seeking was also broken for some releases... (shame on me)
Diffstat (limited to 'source')
-rw-r--r--source/blender/src/hddaudio.c179
-rw-r--r--source/blender/src/seqaudio.c16
2 files changed, 116 insertions, 79 deletions
diff --git a/source/blender/src/hddaudio.c b/source/blender/src/hddaudio.c
index 7175f140b09..bfddd29b198 100644
--- a/source/blender/src/hddaudio.c
+++ b/source/blender/src/hddaudio.c
@@ -216,6 +216,97 @@ long sound_hdaudio_get_duration(struct hdaudio * hdaudio, double frame_rate)
}
#ifdef WITH_FFMPEG
+
+#define RESAMPLE_FILL_RATIO (7.0/4.0)
+
+static void sound_hdaudio_run_resampler_seek(
+ struct hdaudio * hdaudio)
+{
+ int in_frame_size = (long long) hdaudio->sample_rate
+ * hdaudio->frame_duration / AV_TIME_BASE;
+
+ hdaudio->resample_samples_in = in_frame_size * RESAMPLE_FILL_RATIO;
+ hdaudio->resample_samples_written
+ = audio_resample(hdaudio->resampler,
+ hdaudio->resample_cache,
+ hdaudio->decode_cache_zero,
+ in_frame_size * RESAMPLE_FILL_RATIO);
+}
+
+static void sound_hdaudio_run_resampler_continue(
+ struct hdaudio * hdaudio)
+{
+ int target_rate = hdaudio->target_rate;
+ int target_channels = hdaudio->target_channels;
+
+ int frame_size = (long long) target_rate
+ * hdaudio->frame_duration / AV_TIME_BASE;
+ int in_frame_size = (long long) hdaudio->sample_rate
+ * hdaudio->frame_duration / AV_TIME_BASE;
+
+ int reuse_tgt = (hdaudio->resample_samples_written
+ - frame_size) * target_channels;
+ int reuse_src = (hdaudio->resample_samples_in
+ - in_frame_size) * hdaudio->channels;
+ int next_samples_in =
+ in_frame_size * RESAMPLE_FILL_RATIO
+ - reuse_src / hdaudio->channels;
+
+ memmove(hdaudio->resample_cache,
+ hdaudio->resample_cache + frame_size * target_channels,
+ reuse_tgt * sizeof(short));
+
+ hdaudio->resample_samples_written
+ = audio_resample(
+ hdaudio->resampler,
+ hdaudio->resample_cache + reuse_tgt,
+ hdaudio->decode_cache_zero + reuse_src,
+ next_samples_in)
+ + reuse_tgt / target_channels;
+
+ hdaudio->resample_samples_in = next_samples_in
+ + reuse_src / hdaudio->channels;
+}
+
+static void sound_hdaudio_init_resampler(
+ struct hdaudio * hdaudio,
+ int frame_position, int target_rate, int target_channels)
+{
+ int frame_size = (long long) target_rate
+ * hdaudio->frame_duration / AV_TIME_BASE;
+
+ if (hdaudio->resampler &&
+ (hdaudio->target_rate != target_rate
+ || hdaudio->target_channels != target_channels)) {
+ audio_resample_close(hdaudio->resampler);
+ hdaudio->resampler = 0;
+ }
+ if (!hdaudio->resampler) {
+ hdaudio->resampler = av_audio_resample_init(
+ target_channels, hdaudio->channels,
+ target_rate, hdaudio->sample_rate,
+ SAMPLE_FMT_S16, SAMPLE_FMT_S16,
+ 16, 10, 0, 0.8);
+ hdaudio->target_rate = target_rate;
+ hdaudio->target_channels = target_channels;
+ if (hdaudio->resample_cache) {
+ MEM_freeN(hdaudio->resample_cache);
+ }
+
+
+ hdaudio->resample_cache = (short*) MEM_mallocN(
+ (long long)
+ hdaudio->target_channels
+ * frame_size * 2
+ * sizeof(short),
+ "hdaudio resample cache");
+ if (frame_position == hdaudio->frame_position ||
+ frame_position == hdaudio->frame_position + 1) {
+ sound_hdaudio_run_resampler_seek(hdaudio);
+ }
+ }
+}
+
static void sound_hdaudio_extract_small_block(
struct hdaudio * hdaudio,
short * target_buffer,
@@ -240,40 +331,9 @@ static void sound_hdaudio_extract_small_block(
if (hdaudio == 0) return;
if (rate_conversion) {
- if (hdaudio->resampler &&
- (hdaudio->target_rate != target_rate
- || hdaudio->target_channels != target_channels)) {
- audio_resample_close(hdaudio->resampler);
- hdaudio->resampler = 0;
- }
- if (!hdaudio->resampler) {
- hdaudio->resampler = audio_resample_init(
- target_channels, hdaudio->channels,
- target_rate, hdaudio->sample_rate);
- hdaudio->target_rate = target_rate;
- hdaudio->target_channels = target_channels;
- if (hdaudio->resample_cache) {
- MEM_freeN(hdaudio->resample_cache);
- }
-
-
- hdaudio->resample_cache = (short*) MEM_mallocN(
- (long long)
- hdaudio->target_channels
- * frame_size * 2
- * sizeof(short),
- "hdaudio resample cache");
- if (frame_position == hdaudio->frame_position) {
- hdaudio->resample_samples_in =
- in_frame_size * 7 / 4;
- hdaudio->resample_samples_written
- = audio_resample(
- hdaudio->resampler,
- hdaudio->resample_cache,
- hdaudio->decode_cache_zero,
- in_frame_size * 7 / 4);
- }
- }
+ sound_hdaudio_init_resampler(
+ hdaudio, frame_position,
+ target_rate, target_channels);
}
if (frame_position == hdaudio->frame_position + 1
@@ -347,36 +407,11 @@ static void sound_hdaudio_extract_small_block(
}
}
+ hdaudio->decode_pos = decode_pos;
+
if (rate_conversion) {
- int written = hdaudio->resample_samples_written
- * target_channels;
- int ofs = target_channels * frame_size;
- int recycle = written - ofs;
- int next_in = in_frame_size
- + (3.0/4.0
- - (double) recycle / (double)
- (frame_size * target_channels)
- ) * in_frame_size;
-
- memmove(hdaudio->resample_cache,
- hdaudio->resample_cache + ofs,
- recycle * sizeof(short));
-
- hdaudio->resample_samples_written
- = audio_resample(
- hdaudio->resampler,
- hdaudio->resample_cache + recycle,
- hdaudio->decode_cache_zero
- + hdaudio->resample_samples_in
- * hdaudio->channels
- - bl_size,
- next_in)
- + recycle / target_channels;
-
- hdaudio->resample_samples_in = next_in;
+ sound_hdaudio_run_resampler_continue(hdaudio);
}
-
- hdaudio->decode_pos = decode_pos;
}
if (frame_position != hdaudio->frame_position) {
@@ -390,6 +425,7 @@ static void sound_hdaudio_extract_small_block(
* hdaudio->frame_duration / AV_TIME_BASE;
long long seek_pos;
+ int decode_cache_zero_init = 0;
hdaudio->frame_position = frame_position;
@@ -435,8 +471,7 @@ static void sound_hdaudio_extract_small_block(
audio_pkt_data = packet.data;
audio_pkt_size = packet.size;
- if (!hdaudio->decode_cache_zero
- && audio_pkt_size > 0) {
+ if (!decode_cache_zero_init && audio_pkt_size > 0) {
long long diff;
if (packet.pts == AV_NOPTS_VALUE) {
@@ -476,6 +511,7 @@ static void sound_hdaudio_extract_small_block(
hdaudio->decode_cache_zero
= hdaudio->decode_cache + diff;
+ decode_cache_zero_init = 1;
}
while (audio_pkt_size > 0) {
@@ -514,22 +550,18 @@ static void sound_hdaudio_extract_small_block(
break;
}
}
+ hdaudio->decode_pos = decode_pos;
+
if (rate_conversion) {
- hdaudio->resample_samples_written
- = audio_resample(hdaudio->resampler,
- hdaudio->resample_cache,
- hdaudio->decode_cache_zero,
- in_frame_size * 7 / 4);
- hdaudio->resample_samples_in =
- in_frame_size * 7 / 4;
+ sound_hdaudio_run_resampler_seek(hdaudio);
}
- hdaudio->decode_pos = decode_pos;
}
memcpy(target_buffer, (rate_conversion
? hdaudio->resample_cache
: hdaudio->decode_cache_zero) + sample_ofs,
nb_samples * target_channels * sizeof(short));
+
}
#endif
@@ -575,6 +607,9 @@ void sound_close_hdaudio(struct hdaudio * hdaudio)
avcodec_close(hdaudio->pCodecCtx);
av_close_input_file(hdaudio->pFormatCtx);
MEM_freeN (hdaudio->decode_cache);
+ if (hdaudio->resampler) {
+ audio_resample_close(hdaudio->resampler);
+ }
if (hdaudio->resample_cache) {
MEM_freeN(hdaudio->resample_cache);
}
diff --git a/source/blender/src/seqaudio.c b/source/blender/src/seqaudio.c
index e01928c7aee..03885292dfd 100644
--- a/source/blender/src/seqaudio.c
+++ b/source/blender/src/seqaudio.c
@@ -564,7 +564,7 @@ static int audio_init(SDL_AudioSpec *desired)
obtained = (SDL_AudioSpec*)MEM_mallocN(sizeof(SDL_AudioSpec),
"SDL_AudioSpec");
-
+ audio_initialised = 0;
desired->callback=audio_fill;
if ( SDL_OpenAudio(desired, obtained) < 0 ) {
@@ -670,16 +670,18 @@ void audiostream_play(int startframe, uint32_t duration, int mixdown)
sound_init_audio();
}
- if (U.mixbufsize && !audio_initialised && !mixdown) {
+ if (U.mixbufsize &&
+ (!audio_initialised
+ || desired.freq != audio_scene->audio.mixrate
+ || desired.samples != U.mixbufsize)
+ && !mixdown) {
desired.freq=audio_scene->audio.mixrate;
desired.format=AUDIO_S16SYS;
desired.channels=2;
desired.samples=U.mixbufsize;
desired.userdata=0;
- if (audio_init(&desired)==0) {
- U.mixbufsize = 0; /* no audio */
- }
+ audio_init(&desired);
}
audio_startframe = startframe;
@@ -706,7 +708,7 @@ void audiostream_start(int frame)
void audiostream_scrub(int frame)
{
- if (U.mixbufsize) audiostream_play(frame, 4096, 0);
+ audiostream_play(frame, 4096, 0);
}
void audiostream_stop(void)
@@ -721,7 +723,7 @@ int audiostream_pos(void)
{
int pos;
- if (U.mixbufsize && audio_scene) {
+ if (audio_initialised && audio_scene) {
pos = (int) (((double)(audio_pos-U.mixbufsize)
/ ( audio_scene->audio.mixrate*4 ))
* FPS );