chromium/media/cast/test/utility/audio_utility.cc

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include <cmath>
#include <numbers>
#include <vector>

#include "base/check_op.h"
#include "base/time/time.h"
#include "media/base/audio_bus.h"
#include "media/cast/test/utility/audio_utility.h"

namespace media {
namespace cast {

TestAudioBusFactory::TestAudioBusFactory(int num_channels,
                                         int sample_rate,
                                         float sine_wave_frequency,
                                         float volume)
    :{}

TestAudioBusFactory::~TestAudioBusFactory() = default;

std::unique_ptr<AudioBus> TestAudioBusFactory::NextAudioBus(
    const base::TimeDelta& duration) {}

int CountZeroCrossings(const float* samples, int length) {}

// EncodeTimestamp stores a 16-bit number as frequencies in a sample.
// Our internal code tends to work on 10ms chunks of data, and to
// make sure the decoding always work, I wanted to make sure that the
// encoded value can be decoded from 5ms of sample data, assuming a
// sampling rate of 48Khz, this turns out to be 240 samples.
// Each bit of the timestamp is stored as a frequency, where the
// frequency is bit_number * 200 Hz. We also add a 'sense' tone to
// the output, this tone is 17 * 200 = 3400Hz, and when we decode,
// we can use this tone to make sure that we aren't decoding bogus data.
// Also, we use this tone to scale our expectations in case something
// changed changed the volume of the audio.
//
// Normally, we will encode 480 samples (10ms) of data, but when we
// read it will will scan 240 samples at a time until something that
// can be decoded is found.
//
// The intention is to use these routines to encode the frame number
// that goes with each chunk of audio, so if our frame rate is
// 30Hz, we would encode 48000/30 = 1600 samples of "1", then
// 1600 samples of "2", etc. When we decode this, it is possible
// that we get a chunk of data that is spanning two frame numbers,
// so we gray-code the numbers. Since adjacent gray-coded number
// will only differ in one bit, we should never get numbers out
// of sequence when decoding, at least not by more than one.

const double kBaseFrequency =;
const int kSamplingFrequency =;
const size_t kNumBits =;
const size_t kSamplesToAnalyze =;
const double kSenseFrequency =;
const double kMinSense =;

bool EncodeTimestamp(uint16_t timestamp,
                     size_t sample_offset,
                     size_t length,
                     float* samples) {}

namespace {
// We use a slow DCT here since this code is only used for testing.
// While an FFT would probably be faster, it wouldn't be a LOT
// faster since we only analyze 17 out of 120 frequencies.
// With an FFT we would verify that none of the higher frequencies
// contain a lot of energy, which would be useful in detecting
// bogus data.
double DecodeOneFrequency(const float* samples,
                          size_t length,
                          double frequency) {}
}  // namespace

// When decoding, we first check for sense frequency, then we decode
// each of the bits. Each frequency must have a strength that is similar to
// the sense frequency or to zero, or the decoding fails. If it fails, we
// move head by 60 samples and try again until we run out of samples.
bool DecodeTimestamp(const float* samples, size_t length, uint16_t* timestamp) {}

}  // namespace cast
}  // namespace media