12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "remoting/host/audio_silence_detector.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <stdlib.h> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace remoting { 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Silence period threshold in seconds. Silence intervals shorter than this 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// value are still encoded and sent to the client, so that we don't disrupt 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// playback by dropping them. 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int kSilencePeriodThresholdSeconds = 1; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AudioSilenceDetector::AudioSilenceDetector(int threshold) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : threshold_(threshold), 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silence_length_max_(0), 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silence_length_(0) { 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(threshold_, 0); 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AudioSilenceDetector::~AudioSilenceDetector() { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AudioSilenceDetector::Reset(int sampling_rate, int channels) { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GT(sampling_rate, 0); 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silence_length_ = 0; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silence_length_max_ = 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sampling_rate * channels * kSilencePeriodThresholdSeconds; 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AudioSilenceDetector::IsSilence(const int16* samples, 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t samples_count) { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool silent_packet = true; 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Potentially this loop can be optimized (e.g. using SSE or adding special 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // case for threshold_==0), but it's not worth worrying about because the 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // amount of data it processes is relaively small. 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < samples_count; ++i) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (abs(samples[i]) > threshold_) { 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silent_packet = false; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!silent_packet) { 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silence_length_ = 0; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) silence_length_ += samples_count; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return silence_length_ > silence_length_max_; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace remoting 60