blob: 936558ad2e6ffb394d4d38d77c3f7ecf64d3d15b [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <zircon/assert.h>
#include <zircon/device/audio.h>
#include <zircon/types.h>
#include <string.h>
namespace audio {
namespace utils {
// Check to see if the specified frame rate is in either the 48 KHz or 44.1 KHz
// family.
bool FrameRateIn48kFamily(uint32_t rate);
bool FrameRateIn441kFamily(uint32_t rate);
// Figure out the size of an audio frame based on the sample format. Returns 0
// in the case of an error (bad channel count, bad sample format)
uint32_t ComputeFrameSize(uint16_t channels, audio_sample_format_t sample_format);
// Check to see if the specified format (rate, chan, sample_format) is
// compatible with the given format range. Returns true if it is, or
// false otherwise.
bool FormatIsCompatible(uint32_t frame_rate,
uint16_t channels,
audio_sample_format_t sample_format,
const audio_stream_format_range_t& format_range);
// A small helper class which allows code to use c++11 range-based for loop
// syntax for enumerating discrete frame rates supported by an
// audio_stream_format_range_t. Note that this enumerator will not enumerate
// anything if the frame rate range is continuous.
//
// TODO(johngro): If/when we switch to C++17, the begin/end expressions demanded
// by the range-based for loop no longer need to return identical types. We can
// use this to our advantage to eliminate the need to create an actual iterator
// instance when calling end(). We could just return some sort of strongly type
// enum placeholder instead and allow comparison between the iterator and the
// token.
class FrameRateEnumerator {
public:
class iterator {
public:
iterator() { }
iterator& operator++() {
Advance();
return *this;
}
uint32_t operator*() {
// No one should be dereferencing us if we are currently invalid.
ZX_DEBUG_ASSERT(enumerator_ != nullptr);
return cur_rate_;
}
bool operator!=(const iterator& rhs) const {
return ::memcmp(this, &rhs, sizeof(*this)) != 0;
}
private:
friend class FrameRateEnumerator;
explicit iterator(const FrameRateEnumerator* enumerator);
void Advance();
const FrameRateEnumerator* enumerator_ = nullptr;
uint32_t cur_rate_ = 0;
uint16_t cur_flag_ = 0;
uint16_t fmt_ndx_ = 0;
};
explicit FrameRateEnumerator(const audio_stream_format_range_t& range) : range_(range) { }
iterator begin() { return iterator(this); }
iterator end() { return iterator(nullptr); }
const audio_stream_format_range_t& range() const { return range_; }
private:
audio_stream_format_range_t range_;
};
} // namespace utils
} // namespace audio