• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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