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