xref: /aosp_15_r20/external/webrtc/api/audio/audio_frame.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include "api/audio/audio_frame.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <string.h>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
16*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
19*d9f75844SAndroid Build Coastguard Worker 
AudioFrame()20*d9f75844SAndroid Build Coastguard Worker AudioFrame::AudioFrame() {
21*d9f75844SAndroid Build Coastguard Worker   // Visual Studio doesn't like this in the class definition.
22*d9f75844SAndroid Build Coastguard Worker   static_assert(sizeof(data_) == kMaxDataSizeBytes, "kMaxDataSizeBytes");
23*d9f75844SAndroid Build Coastguard Worker }
24*d9f75844SAndroid Build Coastguard Worker 
Reset()25*d9f75844SAndroid Build Coastguard Worker void AudioFrame::Reset() {
26*d9f75844SAndroid Build Coastguard Worker   ResetWithoutMuting();
27*d9f75844SAndroid Build Coastguard Worker   muted_ = true;
28*d9f75844SAndroid Build Coastguard Worker }
29*d9f75844SAndroid Build Coastguard Worker 
ResetWithoutMuting()30*d9f75844SAndroid Build Coastguard Worker void AudioFrame::ResetWithoutMuting() {
31*d9f75844SAndroid Build Coastguard Worker   // TODO(wu): Zero is a valid value for `timestamp_`. We should initialize
32*d9f75844SAndroid Build Coastguard Worker   // to an invalid value, or add a new member to indicate invalidity.
33*d9f75844SAndroid Build Coastguard Worker   timestamp_ = 0;
34*d9f75844SAndroid Build Coastguard Worker   elapsed_time_ms_ = -1;
35*d9f75844SAndroid Build Coastguard Worker   ntp_time_ms_ = -1;
36*d9f75844SAndroid Build Coastguard Worker   samples_per_channel_ = 0;
37*d9f75844SAndroid Build Coastguard Worker   sample_rate_hz_ = 0;
38*d9f75844SAndroid Build Coastguard Worker   num_channels_ = 0;
39*d9f75844SAndroid Build Coastguard Worker   channel_layout_ = CHANNEL_LAYOUT_NONE;
40*d9f75844SAndroid Build Coastguard Worker   speech_type_ = kUndefined;
41*d9f75844SAndroid Build Coastguard Worker   vad_activity_ = kVadUnknown;
42*d9f75844SAndroid Build Coastguard Worker   profile_timestamp_ms_ = 0;
43*d9f75844SAndroid Build Coastguard Worker   packet_infos_ = RtpPacketInfos();
44*d9f75844SAndroid Build Coastguard Worker   absolute_capture_timestamp_ms_ = absl::nullopt;
45*d9f75844SAndroid Build Coastguard Worker }
46*d9f75844SAndroid Build Coastguard Worker 
UpdateFrame(uint32_t timestamp,const int16_t * data,size_t samples_per_channel,int sample_rate_hz,SpeechType speech_type,VADActivity vad_activity,size_t num_channels)47*d9f75844SAndroid Build Coastguard Worker void AudioFrame::UpdateFrame(uint32_t timestamp,
48*d9f75844SAndroid Build Coastguard Worker                              const int16_t* data,
49*d9f75844SAndroid Build Coastguard Worker                              size_t samples_per_channel,
50*d9f75844SAndroid Build Coastguard Worker                              int sample_rate_hz,
51*d9f75844SAndroid Build Coastguard Worker                              SpeechType speech_type,
52*d9f75844SAndroid Build Coastguard Worker                              VADActivity vad_activity,
53*d9f75844SAndroid Build Coastguard Worker                              size_t num_channels) {
54*d9f75844SAndroid Build Coastguard Worker   timestamp_ = timestamp;
55*d9f75844SAndroid Build Coastguard Worker   samples_per_channel_ = samples_per_channel;
56*d9f75844SAndroid Build Coastguard Worker   sample_rate_hz_ = sample_rate_hz;
57*d9f75844SAndroid Build Coastguard Worker   speech_type_ = speech_type;
58*d9f75844SAndroid Build Coastguard Worker   vad_activity_ = vad_activity;
59*d9f75844SAndroid Build Coastguard Worker   num_channels_ = num_channels;
60*d9f75844SAndroid Build Coastguard Worker   channel_layout_ = GuessChannelLayout(num_channels);
61*d9f75844SAndroid Build Coastguard Worker   if (channel_layout_ != CHANNEL_LAYOUT_UNSUPPORTED) {
62*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK_EQ(num_channels, ChannelLayoutToChannelCount(channel_layout_));
63*d9f75844SAndroid Build Coastguard Worker   }
64*d9f75844SAndroid Build Coastguard Worker 
65*d9f75844SAndroid Build Coastguard Worker   const size_t length = samples_per_channel * num_channels;
66*d9f75844SAndroid Build Coastguard Worker   RTC_CHECK_LE(length, kMaxDataSizeSamples);
67*d9f75844SAndroid Build Coastguard Worker   if (data != nullptr) {
68*d9f75844SAndroid Build Coastguard Worker     memcpy(data_, data, sizeof(int16_t) * length);
69*d9f75844SAndroid Build Coastguard Worker     muted_ = false;
70*d9f75844SAndroid Build Coastguard Worker   } else {
71*d9f75844SAndroid Build Coastguard Worker     muted_ = true;
72*d9f75844SAndroid Build Coastguard Worker   }
73*d9f75844SAndroid Build Coastguard Worker }
74*d9f75844SAndroid Build Coastguard Worker 
CopyFrom(const AudioFrame & src)75*d9f75844SAndroid Build Coastguard Worker void AudioFrame::CopyFrom(const AudioFrame& src) {
76*d9f75844SAndroid Build Coastguard Worker   if (this == &src)
77*d9f75844SAndroid Build Coastguard Worker     return;
78*d9f75844SAndroid Build Coastguard Worker 
79*d9f75844SAndroid Build Coastguard Worker   timestamp_ = src.timestamp_;
80*d9f75844SAndroid Build Coastguard Worker   elapsed_time_ms_ = src.elapsed_time_ms_;
81*d9f75844SAndroid Build Coastguard Worker   ntp_time_ms_ = src.ntp_time_ms_;
82*d9f75844SAndroid Build Coastguard Worker   packet_infos_ = src.packet_infos_;
83*d9f75844SAndroid Build Coastguard Worker   muted_ = src.muted();
84*d9f75844SAndroid Build Coastguard Worker   samples_per_channel_ = src.samples_per_channel_;
85*d9f75844SAndroid Build Coastguard Worker   sample_rate_hz_ = src.sample_rate_hz_;
86*d9f75844SAndroid Build Coastguard Worker   speech_type_ = src.speech_type_;
87*d9f75844SAndroid Build Coastguard Worker   vad_activity_ = src.vad_activity_;
88*d9f75844SAndroid Build Coastguard Worker   num_channels_ = src.num_channels_;
89*d9f75844SAndroid Build Coastguard Worker   channel_layout_ = src.channel_layout_;
90*d9f75844SAndroid Build Coastguard Worker   absolute_capture_timestamp_ms_ = src.absolute_capture_timestamp_ms();
91*d9f75844SAndroid Build Coastguard Worker 
92*d9f75844SAndroid Build Coastguard Worker   const size_t length = samples_per_channel_ * num_channels_;
93*d9f75844SAndroid Build Coastguard Worker   RTC_CHECK_LE(length, kMaxDataSizeSamples);
94*d9f75844SAndroid Build Coastguard Worker   if (!src.muted()) {
95*d9f75844SAndroid Build Coastguard Worker     memcpy(data_, src.data(), sizeof(int16_t) * length);
96*d9f75844SAndroid Build Coastguard Worker     muted_ = false;
97*d9f75844SAndroid Build Coastguard Worker   }
98*d9f75844SAndroid Build Coastguard Worker }
99*d9f75844SAndroid Build Coastguard Worker 
UpdateProfileTimeStamp()100*d9f75844SAndroid Build Coastguard Worker void AudioFrame::UpdateProfileTimeStamp() {
101*d9f75844SAndroid Build Coastguard Worker   profile_timestamp_ms_ = rtc::TimeMillis();
102*d9f75844SAndroid Build Coastguard Worker }
103*d9f75844SAndroid Build Coastguard Worker 
ElapsedProfileTimeMs() const104*d9f75844SAndroid Build Coastguard Worker int64_t AudioFrame::ElapsedProfileTimeMs() const {
105*d9f75844SAndroid Build Coastguard Worker   if (profile_timestamp_ms_ == 0) {
106*d9f75844SAndroid Build Coastguard Worker     // Profiling has not been activated.
107*d9f75844SAndroid Build Coastguard Worker     return -1;
108*d9f75844SAndroid Build Coastguard Worker   }
109*d9f75844SAndroid Build Coastguard Worker   return rtc::TimeSince(profile_timestamp_ms_);
110*d9f75844SAndroid Build Coastguard Worker }
111*d9f75844SAndroid Build Coastguard Worker 
data() const112*d9f75844SAndroid Build Coastguard Worker const int16_t* AudioFrame::data() const {
113*d9f75844SAndroid Build Coastguard Worker   return muted_ ? empty_data() : data_;
114*d9f75844SAndroid Build Coastguard Worker }
115*d9f75844SAndroid Build Coastguard Worker 
116*d9f75844SAndroid Build Coastguard Worker // TODO(henrik.lundin) Can we skip zeroing the buffer?
117*d9f75844SAndroid Build Coastguard Worker // See https://bugs.chromium.org/p/webrtc/issues/detail?id=5647.
mutable_data()118*d9f75844SAndroid Build Coastguard Worker int16_t* AudioFrame::mutable_data() {
119*d9f75844SAndroid Build Coastguard Worker   if (muted_) {
120*d9f75844SAndroid Build Coastguard Worker     memset(data_, 0, kMaxDataSizeBytes);
121*d9f75844SAndroid Build Coastguard Worker     muted_ = false;
122*d9f75844SAndroid Build Coastguard Worker   }
123*d9f75844SAndroid Build Coastguard Worker   return data_;
124*d9f75844SAndroid Build Coastguard Worker }
125*d9f75844SAndroid Build Coastguard Worker 
Mute()126*d9f75844SAndroid Build Coastguard Worker void AudioFrame::Mute() {
127*d9f75844SAndroid Build Coastguard Worker   muted_ = true;
128*d9f75844SAndroid Build Coastguard Worker }
129*d9f75844SAndroid Build Coastguard Worker 
muted() const130*d9f75844SAndroid Build Coastguard Worker bool AudioFrame::muted() const {
131*d9f75844SAndroid Build Coastguard Worker   return muted_;
132*d9f75844SAndroid Build Coastguard Worker }
133*d9f75844SAndroid Build Coastguard Worker 
134*d9f75844SAndroid Build Coastguard Worker // static
empty_data()135*d9f75844SAndroid Build Coastguard Worker const int16_t* AudioFrame::empty_data() {
136*d9f75844SAndroid Build Coastguard Worker   static int16_t* null_data = new int16_t[kMaxDataSizeSamples]();
137*d9f75844SAndroid Build Coastguard Worker   return &null_data[0];
138*d9f75844SAndroid Build Coastguard Worker }
139*d9f75844SAndroid Build Coastguard Worker 
140*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
141