LibMedia: Move AudioBlock's timing info into a separate class
This will be used to account for playback rate in audio timing.
This commit is contained in:
parent
ee66ccb4af
commit
13d04e44c2
2 changed files with 96 additions and 30 deletions
|
|
@ -10,20 +10,21 @@
|
|||
#include <AK/FixedArray.h>
|
||||
#include <AK/Math.h>
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AK/SaturatingMath.h>
|
||||
#include <AK/Time.h>
|
||||
#include <LibMedia/Audio/SampleSpecification.h>
|
||||
#include <LibMedia/AudioBlockTiming.h>
|
||||
|
||||
namespace Media {
|
||||
|
||||
class AudioBlock {
|
||||
public:
|
||||
Audio::SampleSpecification const& sample_specification() const { return m_sample_specification; }
|
||||
AK::Duration media_time_start() const { return m_media_time_start; }
|
||||
AK::Duration media_time_duration() const { return m_media_time_duration; }
|
||||
AK::Duration media_time_end() const { return m_media_time_start + m_media_time_duration; }
|
||||
i64 first_frame_index() const { return m_first_frame_index; }
|
||||
i64 end_frame_index() const { return saturating_add(m_first_frame_index, AK::clamp_to<i64>(frame_count())); }
|
||||
AudioBlockTiming const& timing() const { return m_timing; }
|
||||
AudioBlockTiming& timing() { return m_timing; }
|
||||
AK::Duration media_time_start() const { return m_timing.media_time_start(); }
|
||||
AK::Duration media_time_duration() const { return m_timing.media_time_duration(); }
|
||||
AK::Duration media_time_end() const { return m_timing.media_time_end(); }
|
||||
i64 first_frame_index() const { return m_timing.first_frame_index(); }
|
||||
i64 end_frame_index() const { return m_timing.end_frame_index(); }
|
||||
Span<float> channel_data(size_t channel)
|
||||
{
|
||||
VERIFY(channel < channel_count());
|
||||
|
|
@ -46,9 +47,7 @@ public:
|
|||
void clear()
|
||||
{
|
||||
m_sample_specification = {};
|
||||
m_media_time_start = {};
|
||||
m_media_time_duration = {};
|
||||
m_first_frame_index = 0;
|
||||
m_timing.clear();
|
||||
m_frame_count = 0;
|
||||
}
|
||||
void initialize(Audio::SampleSpecification sample_specification, AK::Duration media_time_start, size_t frame_count)
|
||||
|
|
@ -57,11 +56,9 @@ public:
|
|||
VERIFY(frame_count <= NumericLimits<i64>::max());
|
||||
VERIFY(!Checked<size_t>::multiplication_would_overflow(frame_count, sample_specification.channel_count()));
|
||||
m_sample_specification = sample_specification;
|
||||
m_media_time_start = media_time_start;
|
||||
m_first_frame_index = media_time_start.to_time_units(1, sample_rate());
|
||||
m_frame_count = frame_count;
|
||||
m_timing.initialize(media_time_start, sample_rate(), AK::clamp_to<i64>(frame_count));
|
||||
ensure_frame_capacity(frame_count);
|
||||
recalculate_media_duration_from_frame_count();
|
||||
}
|
||||
void initialize(Audio::SampleSpecification sample_specification, i64 first_frame_index, size_t frame_count)
|
||||
{
|
||||
|
|
@ -69,17 +66,15 @@ public:
|
|||
VERIFY(frame_count <= NumericLimits<i64>::max());
|
||||
VERIFY(!Checked<size_t>::multiplication_would_overflow(frame_count, sample_specification.channel_count()));
|
||||
m_sample_specification = sample_specification;
|
||||
m_first_frame_index = first_frame_index;
|
||||
m_media_time_start = AK::Duration::from_time_units(first_frame_index, 1, sample_rate());
|
||||
m_frame_count = frame_count;
|
||||
m_timing.initialize(first_frame_index, sample_rate(), AK::clamp_to<i64>(frame_count));
|
||||
ensure_frame_capacity(frame_count);
|
||||
recalculate_media_duration_from_frame_count();
|
||||
}
|
||||
void trim(size_t frame_count)
|
||||
{
|
||||
VERIFY(frame_count <= m_frame_count);
|
||||
m_frame_count = frame_count;
|
||||
recalculate_media_duration_from_frame_count();
|
||||
m_timing.set_frame_count(sample_rate(), AK::clamp_to<i64>(frame_count));
|
||||
}
|
||||
size_t copy_to_interleaved(Span<float> destination, size_t source_frame_offset = 0) const
|
||||
{
|
||||
|
|
@ -106,19 +101,17 @@ public:
|
|||
void set_first_frame_index(i64 first_frame_index)
|
||||
{
|
||||
VERIFY(!is_empty());
|
||||
m_first_frame_index = first_frame_index;
|
||||
m_media_time_start = AK::Duration::from_time_units(first_frame_index, 1, sample_rate());
|
||||
m_timing.set_first_frame_index(first_frame_index, sample_rate());
|
||||
}
|
||||
void set_media_time_start(AK::Duration media_time_start)
|
||||
{
|
||||
VERIFY(!is_empty());
|
||||
m_media_time_start = media_time_start;
|
||||
m_timing.set_media_time_start(media_time_start);
|
||||
}
|
||||
void set_media_time_duration(AK::Duration media_time_duration)
|
||||
{
|
||||
VERIFY(!is_empty());
|
||||
VERIFY(!media_time_duration.is_negative());
|
||||
m_media_time_duration = media_time_duration;
|
||||
m_timing.set_media_time_duration(media_time_duration);
|
||||
}
|
||||
bool is_empty() const
|
||||
{
|
||||
|
|
@ -138,11 +131,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void recalculate_media_duration_from_frame_count()
|
||||
{
|
||||
m_media_time_duration = AK::Duration::from_time_units(AK::clamp_to<i64>(frame_count()), 1, sample_rate());
|
||||
}
|
||||
|
||||
size_t frame_capacity() const
|
||||
{
|
||||
if (!is_empty())
|
||||
|
|
@ -159,9 +147,7 @@ private:
|
|||
}
|
||||
|
||||
Audio::SampleSpecification m_sample_specification;
|
||||
AK::Duration m_media_time_start;
|
||||
AK::Duration m_media_time_duration;
|
||||
i64 m_first_frame_index { 0 };
|
||||
AudioBlockTiming m_timing;
|
||||
size_t m_frame_count { 0 };
|
||||
FixedArray<float> m_data;
|
||||
};
|
||||
|
|
|
|||
80
Libraries/LibMedia/AudioBlockTiming.h
Normal file
80
Libraries/LibMedia/AudioBlockTiming.h
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2026-present, the Ladybird developers.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Math.h>
|
||||
#include <AK/SaturatingMath.h>
|
||||
#include <AK/Time.h>
|
||||
|
||||
namespace Media {
|
||||
|
||||
class AudioBlockTiming {
|
||||
public:
|
||||
AK::Duration media_time_start() const { return m_media_time_start; }
|
||||
AK::Duration media_time_duration() const { return m_media_time_duration; }
|
||||
AK::Duration media_time_end() const { return m_media_time_start + m_media_time_duration; }
|
||||
|
||||
i64 first_frame_index() const { return m_first_frame_index; }
|
||||
i64 frame_count() const { return m_frame_count; }
|
||||
i64 end_frame_index() const { return saturating_add(m_first_frame_index, m_frame_count); }
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_media_time_start = {};
|
||||
m_media_time_duration = {};
|
||||
m_first_frame_index = 0;
|
||||
m_frame_count = 0;
|
||||
}
|
||||
|
||||
void initialize(AK::Duration media_time_start, u32 sample_rate, i64 frame_count)
|
||||
{
|
||||
m_media_time_start = media_time_start;
|
||||
m_first_frame_index = media_time_start.to_time_units(1, sample_rate);
|
||||
m_frame_count = frame_count;
|
||||
recalculate_media_duration_from_frame_count(sample_rate);
|
||||
}
|
||||
|
||||
void initialize(i64 first_frame_index, u32 sample_rate, i64 frame_count)
|
||||
{
|
||||
m_first_frame_index = first_frame_index;
|
||||
m_media_time_start = AK::Duration::from_time_units(first_frame_index, 1, sample_rate);
|
||||
m_frame_count = frame_count;
|
||||
recalculate_media_duration_from_frame_count(sample_rate);
|
||||
}
|
||||
|
||||
void set_frame_count(u32 sample_rate, i64 frame_count)
|
||||
{
|
||||
m_frame_count = frame_count;
|
||||
recalculate_media_duration_from_frame_count(sample_rate);
|
||||
}
|
||||
|
||||
void set_first_frame_index(i64 first_frame_index, u32 sample_rate)
|
||||
{
|
||||
m_first_frame_index = first_frame_index;
|
||||
m_media_time_start = AK::Duration::from_time_units(first_frame_index, 1, sample_rate);
|
||||
}
|
||||
|
||||
void set_media_time_start(AK::Duration media_time_start) { m_media_time_start = media_time_start; }
|
||||
void set_media_time_duration(AK::Duration media_time_duration)
|
||||
{
|
||||
VERIFY(!media_time_duration.is_negative());
|
||||
m_media_time_duration = media_time_duration;
|
||||
}
|
||||
|
||||
private:
|
||||
void recalculate_media_duration_from_frame_count(u32 sample_rate)
|
||||
{
|
||||
m_media_time_duration = AK::Duration::from_time_units(m_frame_count, 1, sample_rate);
|
||||
}
|
||||
|
||||
AK::Duration m_media_time_start;
|
||||
AK::Duration m_media_time_duration;
|
||||
i64 m_first_frame_index { 0 };
|
||||
i64 m_frame_count { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue