Replace cpp::span shim with std::span

custom
jacqueline 12 months ago
parent f852e44715
commit a231fd1c8a
  1. 4
      .reuse/dep5
  2. 5
      lib/span/CMakeLists.txt
  3. 23
      lib/span/LICENSE.txt
  4. 618
      lib/span/include/span.hpp
  5. 13
      lua/licenses.lua
  6. 2
      src/audio/CMakeLists.txt
  7. 8
      src/audio/audio_converter.cpp
  8. 3
      src/audio/audio_decoder.cpp
  9. 2
      src/audio/audio_source.cpp
  10. 8
      src/audio/fatfs_audio_input.cpp
  11. 2
      src/audio/fatfs_source.cpp
  12. 12
      src/audio/include/audio_converter.hpp
  13. 2
      src/audio/include/audio_decoder.hpp
  14. 2
      src/audio/include/audio_source.hpp
  15. 2
      src/audio/include/fatfs_source.hpp
  16. 2
      src/audio/include/readahead_source.hpp
  17. 6
      src/audio/include/resample.hpp
  18. 2
      src/audio/readahead_source.cpp
  19. 4
      src/audio/resample.cpp
  20. 2
      src/codecs/CMakeLists.txt
  21. 2
      src/codecs/dr_flac.cpp
  22. 9
      src/codecs/include/codec.hpp
  23. 4
      src/codecs/include/dr_flac.hpp
  24. 4
      src/codecs/include/mad.hpp
  25. 4
      src/codecs/include/opus.hpp
  26. 9
      src/codecs/include/source_buffer.hpp
  27. 4
      src/codecs/include/vorbis.hpp
  28. 2
      src/codecs/include/wav.hpp
  29. 10
      src/codecs/mad.cpp
  30. 2
      src/codecs/opus.cpp
  31. 6
      src/codecs/source_buffer.cpp
  32. 6
      src/codecs/test/test_mad.cpp
  33. 2
      src/codecs/vorbis.cpp
  34. 55
      src/codecs/wav.cpp
  35. 2
      src/database/CMakeLists.txt
  36. 2
      src/database/include/records.hpp
  37. 9
      src/database/include/track.hpp
  38. 10
      src/database/index.cpp
  39. 2
      src/database/records.cpp
  40. 8
      src/database/track.cpp
  41. 2
      src/drivers/CMakeLists.txt
  42. 2
      src/drivers/i2s_dac.cpp
  43. 4
      src/drivers/include/i2s_dac.hpp
  44. 2
      src/locale/CMakeLists.txt
  45. 2
      src/locale/include/collation.hpp
  46. 2
      src/lua/property.cpp
  47. 6
      src/memory/include/himem.hpp
  48. 2
      src/tasks/CMakeLists.txt
  49. 10
      src/tasks/tasks.cpp
  50. 8
      src/tasks/tasks.hpp
  51. 2
      src/util/CMakeLists.txt
  52. 5
      src/util/include/debug.hpp
  53. 1
      tools/cmake/common.cmake

@ -66,10 +66,6 @@ Files: lib/result/include/*
Copyright: 2017-2021 Matthew Rodusek
License: MIT
Files: lib/span/include/*
Copyright: 2018 Tristan Brindle
License: BSL-1.0
Files: lib/speexdsp/*
Copyright: 2002-2008 Xiph.org Foundation
2002-2008 Jean-Marc Valin

@ -1,5 +0,0 @@
# Copyright 2023 jacqueline <me@jacqueline.id.au>
#
# SPDX-License-Identifier: GPL-3.0-only
idf_component_register(INCLUDE_DIRS "include")

@ -1,23 +0,0 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

@ -1,618 +0,0 @@
/*
This is an implementation of C++20's std::span
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/n4820.pdf
*/
// Copyright Tristan Brindle 2018.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file ../../LICENSE_1_0.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)
#ifndef TCB_SPAN_HPP_INCLUDED
#define TCB_SPAN_HPP_INCLUDED
#include <array>
#include <cstddef>
#include <cstdint>
#include <type_traits>
#ifndef TCB_SPAN_NO_EXCEPTIONS
// Attempt to discover whether we're being compiled with exception support
#if !(defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND))
#define TCB_SPAN_NO_EXCEPTIONS
#endif
#endif
#ifndef TCB_SPAN_NO_EXCEPTIONS
#include <cstdio>
#include <stdexcept>
#endif
// Various feature test macros
#ifndef TCB_SPAN_NAMESPACE_NAME
#define TCB_SPAN_NAMESPACE_NAME tcb
#endif
#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
#define TCB_SPAN_HAVE_CPP17
#endif
#if __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#define TCB_SPAN_HAVE_CPP14
#endif
namespace TCB_SPAN_NAMESPACE_NAME {
// Establish default contract checking behavior
#if !defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION) && \
!defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION) && \
!defined(TCB_SPAN_NO_CONTRACT_CHECKING)
#if defined(NDEBUG) || !defined(TCB_SPAN_HAVE_CPP14)
#define TCB_SPAN_NO_CONTRACT_CHECKING
#else
#define TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION
#endif
#endif
#if defined(TCB_SPAN_THROW_ON_CONTRACT_VIOLATION)
struct contract_violation_error : std::logic_error {
explicit contract_violation_error(const char* msg) : std::logic_error(msg)
{}
};
inline void contract_violation(const char* msg)
{
throw contract_violation_error(msg);
}
#elif defined(TCB_SPAN_TERMINATE_ON_CONTRACT_VIOLATION)
[[noreturn]] inline void contract_violation(const char* /*unused*/)
{
std::terminate();
}
#endif
#if !defined(TCB_SPAN_NO_CONTRACT_CHECKING)
#define TCB_SPAN_STRINGIFY(cond) #cond
#define TCB_SPAN_EXPECT(cond) \
cond ? (void) 0 : contract_violation("Expected " TCB_SPAN_STRINGIFY(cond))
#else
#define TCB_SPAN_EXPECT(cond)
#endif
#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_inline_variables)
#define TCB_SPAN_INLINE_VAR inline
#else
#define TCB_SPAN_INLINE_VAR
#endif
#if defined(TCB_SPAN_HAVE_CPP14) || \
(defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
#define TCB_SPAN_HAVE_CPP14_CONSTEXPR
#endif
#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR)
#define TCB_SPAN_CONSTEXPR14 constexpr
#else
#define TCB_SPAN_CONSTEXPR14
#endif
#if defined(TCB_SPAN_HAVE_CPP14_CONSTEXPR) && \
(!defined(_MSC_VER) || _MSC_VER > 1900)
#define TCB_SPAN_CONSTEXPR_ASSIGN constexpr
#else
#define TCB_SPAN_CONSTEXPR_ASSIGN
#endif
#if defined(TCB_SPAN_NO_CONTRACT_CHECKING)
#define TCB_SPAN_CONSTEXPR11 constexpr
#else
#define TCB_SPAN_CONSTEXPR11 TCB_SPAN_CONSTEXPR14
#endif
#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_deduction_guides)
#define TCB_SPAN_HAVE_DEDUCTION_GUIDES
#endif
#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_byte)
#define TCB_SPAN_HAVE_STD_BYTE
#endif
#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_array_constexpr)
#define TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC
#endif
#if defined(TCB_SPAN_HAVE_CONSTEXPR_STD_ARRAY_ETC)
#define TCB_SPAN_ARRAY_CONSTEXPR constexpr
#else
#define TCB_SPAN_ARRAY_CONSTEXPR
#endif
#ifdef TCB_SPAN_HAVE_STD_BYTE
using byte = std::byte;
#else
using byte = unsigned char;
#endif
#if defined(TCB_SPAN_HAVE_CPP17)
#define TCB_SPAN_NODISCARD [[nodiscard]]
#else
#define TCB_SPAN_NODISCARD
#endif
TCB_SPAN_INLINE_VAR constexpr std::size_t dynamic_extent = SIZE_MAX;
template <typename ElementType, std::size_t Extent = dynamic_extent>
class span;
namespace detail {
template <typename E, std::size_t S>
struct span_storage {
constexpr span_storage() noexcept = default;
constexpr span_storage(E* p_ptr, std::size_t /*unused*/) noexcept
: ptr(p_ptr)
{}
E* ptr = nullptr;
static constexpr std::size_t size = S;
};
template <typename E>
struct span_storage<E, dynamic_extent> {
constexpr span_storage() noexcept = default;
constexpr span_storage(E* p_ptr, std::size_t p_size) noexcept
: ptr(p_ptr), size(p_size)
{}
E* ptr = nullptr;
std::size_t size = 0;
};
// Reimplementation of C++17 std::size() and std::data()
#if defined(TCB_SPAN_HAVE_CPP17) || \
defined(__cpp_lib_nonmember_container_access)
using std::data;
using std::size;
#else
template <class C>
constexpr auto size(const C& c) -> decltype(c.size())
{
return c.size();
}
template <class T, std::size_t N>
constexpr std::size_t size(const T (&)[N]) noexcept
{
return N;
}
template <class C>
constexpr auto data(C& c) -> decltype(c.data())
{
return c.data();
}
template <class C>
constexpr auto data(const C& c) -> decltype(c.data())
{
return c.data();
}
template <class T, std::size_t N>
constexpr T* data(T (&array)[N]) noexcept
{
return array;
}
template <class E>
constexpr const E* data(std::initializer_list<E> il) noexcept
{
return il.begin();
}
#endif // TCB_SPAN_HAVE_CPP17
#if defined(TCB_SPAN_HAVE_CPP17) || defined(__cpp_lib_void_t)
using std::void_t;
#else
template <typename...>
using void_t = void;
#endif
template <typename T>
using uncvref_t =
typename std::remove_cv<typename std::remove_reference<T>::type>::type;
template <typename>
struct is_span : std::false_type {};
template <typename T, std::size_t S>
struct is_span<span<T, S>> : std::true_type {};
template <typename>
struct is_std_array : std::false_type {};
template <typename T, std::size_t N>
struct is_std_array<std::array<T, N>> : std::true_type {};
template <typename, typename = void>
struct has_size_and_data : std::false_type {};
template <typename T>
struct has_size_and_data<T, void_t<decltype(detail::size(std::declval<T>())),
decltype(detail::data(std::declval<T>()))>>
: std::true_type {};
template <typename C, typename U = uncvref_t<C>>
struct is_container {
static constexpr bool value =
!is_span<U>::value && !is_std_array<U>::value &&
!std::is_array<U>::value && has_size_and_data<C>::value;
};
template <typename T>
using remove_pointer_t = typename std::remove_pointer<T>::type;
template <typename, typename, typename = void>
struct is_container_element_type_compatible : std::false_type {};
template <typename T, typename E>
struct is_container_element_type_compatible<
T, E,
typename std::enable_if<
!std::is_same<
typename std::remove_cv<decltype(detail::data(std::declval<T>()))>::type,
void>::value &&
std::is_convertible<
remove_pointer_t<decltype(detail::data(std::declval<T>()))> (*)[],
E (*)[]>::value
>::type>
: std::true_type {};
template <typename, typename = size_t>
struct is_complete : std::false_type {};
template <typename T>
struct is_complete<T, decltype(sizeof(T))> : std::true_type {};
} // namespace detail
template <typename ElementType, std::size_t Extent>
class span {
static_assert(std::is_object<ElementType>::value,
"A span's ElementType must be an object type (not a "
"reference type or void)");
static_assert(detail::is_complete<ElementType>::value,
"A span's ElementType must be a complete type (not a forward "
"declaration)");
static_assert(!std::is_abstract<ElementType>::value,
"A span's ElementType cannot be an abstract class type");
using storage_type = detail::span_storage<ElementType, Extent>;
public:
// constants and types
using element_type = ElementType;
using value_type = typename std::remove_cv<ElementType>::type;
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
using pointer = element_type*;
using const_pointer = const element_type*;
using reference = element_type&;
using const_reference = const element_type&;
using iterator = pointer;
using reverse_iterator = std::reverse_iterator<iterator>;
static constexpr size_type extent = Extent;
// [span.cons], span constructors, copy, assignment, and destructor
template <
std::size_t E = Extent,
typename std::enable_if<(E == dynamic_extent || E <= 0), int>::type = 0>
constexpr span() noexcept
{}
TCB_SPAN_CONSTEXPR11 span(pointer ptr, size_type count)
: storage_(ptr, count)
{
TCB_SPAN_EXPECT(extent == dynamic_extent || count == extent);
}
TCB_SPAN_CONSTEXPR11 span(pointer first_elem, pointer last_elem)
: storage_(first_elem, last_elem - first_elem)
{
TCB_SPAN_EXPECT(extent == dynamic_extent ||
last_elem - first_elem ==
static_cast<std::ptrdiff_t>(extent));
}
template <std::size_t N, std::size_t E = Extent,
typename std::enable_if<
(E == dynamic_extent || N == E) &&
detail::is_container_element_type_compatible<
element_type (&)[N], ElementType>::value,
int>::type = 0>
constexpr span(element_type (&arr)[N]) noexcept : storage_(arr, N)
{}
template <typename T, std::size_t N, std::size_t E = Extent,
typename std::enable_if<
(E == dynamic_extent || N == E) &&
detail::is_container_element_type_compatible<
std::array<T, N>&, ElementType>::value,
int>::type = 0>
TCB_SPAN_ARRAY_CONSTEXPR span(std::array<T, N>& arr) noexcept
: storage_(arr.data(), N)
{}
template <typename T, std::size_t N, std::size_t E = Extent,
typename std::enable_if<
(E == dynamic_extent || N == E) &&
detail::is_container_element_type_compatible<
const std::array<T, N>&, ElementType>::value,
int>::type = 0>
TCB_SPAN_ARRAY_CONSTEXPR span(const std::array<T, N>& arr) noexcept
: storage_(arr.data(), N)
{}
template <
typename Container, std::size_t E = Extent,
typename std::enable_if<
E == dynamic_extent && detail::is_container<Container>::value &&
detail::is_container_element_type_compatible<
Container&, ElementType>::value,
int>::type = 0>
constexpr span(Container& cont)
: storage_(detail::data(cont), detail::size(cont))
{}
template <
typename Container, std::size_t E = Extent,
typename std::enable_if<
E == dynamic_extent && detail::is_container<Container>::value &&
detail::is_container_element_type_compatible<
const Container&, ElementType>::value,
int>::type = 0>
constexpr span(const Container& cont)
: storage_(detail::data(cont), detail::size(cont))
{}
constexpr span(const span& other) noexcept = default;
template <typename OtherElementType, std::size_t OtherExtent,
typename std::enable_if<
(Extent == dynamic_extent || OtherExtent == dynamic_extent ||
Extent == OtherExtent) &&
std::is_convertible<OtherElementType (*)[],
ElementType (*)[]>::value,
int>::type = 0>
constexpr span(const span<OtherElementType, OtherExtent>& other) noexcept
: storage_(other.data(), other.size())
{}
~span() noexcept = default;
TCB_SPAN_CONSTEXPR_ASSIGN span&
operator=(const span& other) noexcept = default;
// [span.sub], span subviews
template <std::size_t Count>
TCB_SPAN_CONSTEXPR11 span<element_type, Count> first() const
{
TCB_SPAN_EXPECT(Count <= size());
return {data(), Count};
}
template <std::size_t Count>
TCB_SPAN_CONSTEXPR11 span<element_type, Count> last() const
{
TCB_SPAN_EXPECT(Count <= size());
return {data() + (size() - Count), Count};
}
template <std::size_t Offset, std::size_t Count = dynamic_extent>
using subspan_return_t =
span<ElementType, Count != dynamic_extent
? Count
: (Extent != dynamic_extent ? Extent - Offset
: dynamic_extent)>;
template <std::size_t Offset, std::size_t Count = dynamic_extent>
TCB_SPAN_CONSTEXPR11 subspan_return_t<Offset, Count> subspan() const
{
TCB_SPAN_EXPECT(Offset <= size() &&
(Count == dynamic_extent || Offset + Count <= size()));
return {data() + Offset,
Count != dynamic_extent ? Count : size() - Offset};
}
TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent>
first(size_type count) const
{
TCB_SPAN_EXPECT(count <= size());
return {data(), count};
}
TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent>
last(size_type count) const
{
TCB_SPAN_EXPECT(count <= size());
return {data() + (size() - count), count};
}
TCB_SPAN_CONSTEXPR11 span<element_type, dynamic_extent>
subspan(size_type offset, size_type count = dynamic_extent) const
{
TCB_SPAN_EXPECT(offset <= size() &&
(count == dynamic_extent || offset + count <= size()));
return {data() + offset,
count == dynamic_extent ? size() - offset : count};
}
// [span.obs], span observers
constexpr size_type size() const noexcept { return storage_.size; }
constexpr size_type size_bytes() const noexcept
{
return size() * sizeof(element_type);
}
TCB_SPAN_NODISCARD constexpr bool empty() const noexcept
{
return size() == 0;
}
// [span.elem], span element access
TCB_SPAN_CONSTEXPR11 reference operator[](size_type idx) const
{
TCB_SPAN_EXPECT(idx < size());
return *(data() + idx);
}
TCB_SPAN_CONSTEXPR11 reference front() const
{
TCB_SPAN_EXPECT(!empty());
return *data();
}
TCB_SPAN_CONSTEXPR11 reference back() const
{
TCB_SPAN_EXPECT(!empty());
return *(data() + (size() - 1));
}
constexpr pointer data() const noexcept { return storage_.ptr; }
// [span.iterators], span iterator support
constexpr iterator begin() const noexcept { return data(); }
constexpr iterator end() const noexcept { return data() + size(); }
TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rbegin() const noexcept
{
return reverse_iterator(end());
}
TCB_SPAN_ARRAY_CONSTEXPR reverse_iterator rend() const noexcept
{
return reverse_iterator(begin());
}
private:
storage_type storage_{};
};
#ifdef TCB_SPAN_HAVE_DEDUCTION_GUIDES
/* Deduction Guides */
template <class T, size_t N>
span(T (&)[N])->span<T, N>;
template <class T, size_t N>
span(std::array<T, N>&)->span<T, N>;
template <class T, size_t N>
span(const std::array<T, N>&)->span<const T, N>;
template <class Container>
span(Container&)->span<typename std::remove_reference<
decltype(*detail::data(std::declval<Container&>()))>::type>;
template <class Container>
span(const Container&)->span<const typename Container::value_type>;
#endif // TCB_HAVE_DEDUCTION_GUIDES
template <typename ElementType, std::size_t Extent>
constexpr span<ElementType, Extent>
make_span(span<ElementType, Extent> s) noexcept
{
return s;
}
template <typename T, std::size_t N>
constexpr span<T, N> make_span(T (&arr)[N]) noexcept
{
return {arr};
}
template <typename T, std::size_t N>
TCB_SPAN_ARRAY_CONSTEXPR span<T, N> make_span(std::array<T, N>& arr) noexcept
{
return {arr};
}
template <typename T, std::size_t N>
TCB_SPAN_ARRAY_CONSTEXPR span<const T, N>
make_span(const std::array<T, N>& arr) noexcept
{
return {arr};
}
template <typename Container>
constexpr span<typename std::remove_reference<
decltype(*detail::data(std::declval<Container&>()))>::type>
make_span(Container& cont)
{
return {cont};
}
template <typename Container>
constexpr span<const typename Container::value_type>
make_span(const Container& cont)
{
return {cont};
}
template <typename ElementType, std::size_t Extent>
span<const byte, ((Extent == dynamic_extent) ? dynamic_extent
: sizeof(ElementType) * Extent)>
as_bytes(span<ElementType, Extent> s) noexcept
{
return {reinterpret_cast<const byte*>(s.data()), s.size_bytes()};
}
template <
class ElementType, size_t Extent,
typename std::enable_if<!std::is_const<ElementType>::value, int>::type = 0>
span<byte, ((Extent == dynamic_extent) ? dynamic_extent
: sizeof(ElementType) * Extent)>
as_writable_bytes(span<ElementType, Extent> s) noexcept
{
return {reinterpret_cast<byte*>(s.data()), s.size_bytes()};
}
template <std::size_t N, typename E, std::size_t S>
constexpr auto get(span<E, S> s) -> decltype(s[N])
{
return s[N];
}
} // namespace TCB_SPAN_NAMESPACE_NAME
namespace std {
template <typename ElementType, size_t Extent>
class tuple_size<TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>>
: public integral_constant<size_t, Extent> {};
template <typename ElementType>
class tuple_size<TCB_SPAN_NAMESPACE_NAME::span<
ElementType, TCB_SPAN_NAMESPACE_NAME::dynamic_extent>>; // not defined
template <size_t I, typename ElementType, size_t Extent>
class tuple_element<I, TCB_SPAN_NAMESPACE_NAME::span<ElementType, Extent>> {
public:
static_assert(Extent != TCB_SPAN_NAMESPACE_NAME::dynamic_extent &&
I < Extent,
"");
using type = ElementType;
};
} // end namespace std
#endif // TCB_SPAN_HPP_INCLUDED

@ -63,16 +63,6 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.]])
end
local function boost(copyright)
show_license(copyright .. [[
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following:
The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.]])
end
return function(self)
local container = self.root:Object {
flex = {
@ -159,9 +149,6 @@ return function(self)
library("result", "MIT", function()
mit("Copyright (c) 2017-2021 Matthew Rodusek")
end)
library("span", "Boost", function()
boost("Copyright Tristan Brindle 2018")
end)
library("speexdsp", "bsd", function()
xiphbsd(
"Copyright 2002-2008 Xiph.org Foundation, Copyright 2002-2008 Jean-Marc Valin, Copyright 2005-2007 Analog Devices Inc., Copyright 2005-2008 Commonwealth Scientific and Industrial Research, Organisation (CSIRO), Copyright 1993, 2002, 2006 David Rowe, Copyright 2003 EpicGames, Copyright 1992-1994 Jutta Degener, Carsten Bormann")

@ -8,7 +8,7 @@ idf_component_register(
"fatfs_source.cpp" "bt_audio_output.cpp" "readahead_source.cpp"
"audio_source.cpp"
INCLUDE_DIRS "include"
REQUIRES "codecs" "drivers" "cbor" "result" "tasks" "span" "memory" "tinyfsm"
REQUIRES "codecs" "drivers" "cbor" "result" "tasks" "memory" "tinyfsm"
"database" "system_fsm" "speexdsp" "millershuffle" "libcppbor")
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})

@ -76,7 +76,7 @@ auto SampleConverter::beginStream(std::shared_ptr<TrackInfo> track) -> void {
xQueueSend(commands_, &args, portMAX_DELAY);
}
auto SampleConverter::continueStream(cpp::span<sample::Sample> input) -> void {
auto SampleConverter::continueStream(std::span<sample::Sample> input) -> void {
Args args{
.track = nullptr,
.samples_available = input.size(),
@ -182,7 +182,7 @@ auto SampleConverter::handleContinueStream(size_t samples_available) -> void {
}
}
auto SampleConverter::handleSamples(cpp::span<sample::Sample> input) -> size_t {
auto SampleConverter::handleSamples(std::span<sample::Sample> input) -> size_t {
if (source_format_ == target_format_) {
// The happiest possible case: the input format matches the output
// format already.
@ -192,7 +192,7 @@ auto SampleConverter::handleSamples(cpp::span<sample::Sample> input) -> size_t {
size_t samples_used = 0;
while (samples_used < input.size()) {
cpp::span<sample::Sample> output_source;
std::span<sample::Sample> output_source;
if (source_format_.sample_rate != target_format_.sample_rate) {
if (resampler_ == nullptr) {
ESP_LOGI(kTag, "creating new resampler for %lu -> %lu",
@ -245,7 +245,7 @@ auto SampleConverter::handleEndStream() -> void {
events::Audio().Dispatch(internal::StreamEnded{});
}
auto SampleConverter::sendToSink(cpp::span<sample::Sample> samples) -> void {
auto SampleConverter::sendToSink(std::span<sample::Sample> samples) -> void {
// Update the number of samples sunk so far *before* actually sinking them,
// since writing to the stream buffer will block when the buffer gets full.
samples_sunk_ += samples.size();

@ -5,7 +5,6 @@
*/
#include "audio_decoder.hpp"
#include <stdint.h>
#include <cstdint>
#include <cstdlib>
@ -17,6 +16,7 @@
#include <cstring>
#include <deque>
#include <memory>
#include <span>
#include <variant>
#include "cbor.h"
@ -28,7 +28,6 @@
#include "freertos/queue.h"
#include "freertos/ringbuf.h"
#include "i2s_dac.hpp"
#include "span.hpp"
#include "audio_converter.hpp"
#include "audio_events.hpp"

@ -20,7 +20,7 @@ auto TaggedStream::tags() -> std::shared_ptr<database::TrackTags> {
return tags_;
}
auto TaggedStream::Read(cpp::span<std::byte> dest) -> ssize_t {
auto TaggedStream::Read(std::span<std::byte> dest) -> ssize_t {
return wrapped_->Read(dest);
}

@ -14,6 +14,7 @@
#include <future>
#include <memory>
#include <mutex>
#include <span>
#include <string>
#include <variant>
@ -23,7 +24,6 @@
#include "freertos/portmacro.h"
#include "freertos/projdefs.h"
#include "readahead_source.hpp"
#include "span.hpp"
#include "audio_events.hpp"
#include "audio_fsm.hpp"
@ -61,7 +61,8 @@ auto FatfsAudioInput::SetPath(std::optional<std::string> path) -> void {
}
}
auto FatfsAudioInput::SetPath(const std::string& path,uint32_t offset) -> void {
auto FatfsAudioInput::SetPath(const std::string& path, uint32_t offset)
-> void {
std::lock_guard<std::mutex> guard{new_stream_mutex_};
if (OpenFile(path, offset)) {
has_new_stream_ = true;
@ -102,7 +103,8 @@ auto FatfsAudioInput::NextStream() -> std::shared_ptr<TaggedStream> {
}
}
auto FatfsAudioInput::OpenFile(const std::string& path,uint32_t offset) -> bool {
auto FatfsAudioInput::OpenFile(const std::string& path, uint32_t offset)
-> bool {
ESP_LOGI(kTag, "opening file %s", path.c_str());
auto tags = tag_parser_.ReadAndParseTags(path);

@ -33,7 +33,7 @@ FatfsSource::~FatfsSource() {
f_close(file_.get());
}
auto FatfsSource::Read(cpp::span<std::byte> dest) -> ssize_t {
auto FatfsSource::Read(std::span<std::byte> dest) -> ssize_t {
auto lock = drivers::acquire_spi();
if (f_eof(file_.get())) {
return 0;

@ -33,7 +33,7 @@ class SampleConverter {
auto SetOutput(std::shared_ptr<IAudioOutput>) -> void;
auto beginStream(std::shared_ptr<TrackInfo>) -> void;
auto continueStream(cpp::span<sample::Sample>) -> void;
auto continueStream(std::span<sample::Sample>) -> void;
auto endStream() -> void;
private:
@ -43,9 +43,9 @@ class SampleConverter {
auto handleContinueStream(size_t samples_available) -> void;
auto handleEndStream() -> void;
auto handleSamples(cpp::span<sample::Sample>) -> size_t;
auto handleSamples(std::span<sample::Sample>) -> size_t;
auto sendToSink(cpp::span<sample::Sample>) -> void;
auto sendToSink(std::span<sample::Sample>) -> void;
struct Args {
std::shared_ptr<TrackInfo>* track;
@ -57,10 +57,10 @@ class SampleConverter {
std::unique_ptr<Resampler> resampler_;
StreamBufferHandle_t source_;
cpp::span<sample::Sample> input_buffer_;
cpp::span<std::byte> input_buffer_as_bytes_;
std::span<sample::Sample> input_buffer_;
std::span<std::byte> input_buffer_as_bytes_;
cpp::span<sample::Sample> resampled_buffer_;
std::span<sample::Sample> resampled_buffer_;
std::shared_ptr<IAudioOutput> sink_;
IAudioOutput::Format source_format_;

@ -50,7 +50,7 @@ class Decoder {
std::optional<codecs::ICodec::OutputFormat> current_format_;
std::optional<IAudioOutput::Format> current_sink_format_;
cpp::span<sample::Sample> codec_buffer_;
std::span<sample::Sample> codec_buffer_;
};
} // namespace audio

@ -23,7 +23,7 @@ class TaggedStream : public codecs::IStream {
auto tags() -> std::shared_ptr<database::TrackTags>;
auto Read(cpp::span<std::byte> dest) -> ssize_t override;
auto Read(std::span<std::byte> dest) -> ssize_t override;
auto CanSeek() -> bool override;

@ -26,7 +26,7 @@ class FatfsSource : public codecs::IStream {
FatfsSource(codecs::StreamType, std::unique_ptr<FIL> file);
~FatfsSource();
auto Read(cpp::span<std::byte> dest) -> ssize_t override;
auto Read(std::span<std::byte> dest) -> ssize_t override;
auto CanSeek() -> bool override;

@ -30,7 +30,7 @@ class ReadaheadSource : public codecs::IStream {
ReadaheadSource(tasks::WorkerPool&, std::unique_ptr<codecs::IStream>);
~ReadaheadSource();
auto Read(cpp::span<std::byte> dest) -> ssize_t override;
auto Read(std::span<std::byte> dest) -> ssize_t override;
auto CanSeek() -> bool override;

@ -7,9 +7,9 @@
#pragma once
#include <cstdint>
#include <span>
#include <vector>
#include "span.hpp"
#include "speex/speex_resampler.h"
#include "sample.hpp"
@ -24,8 +24,8 @@ class Resampler {
~Resampler();
auto Process(cpp::span<sample::Sample> input,
cpp::span<sample::Sample> output,
auto Process(std::span<sample::Sample> input,
std::span<sample::Sample> output,
bool end_of_data) -> std::pair<size_t, size_t>;
private:

@ -41,7 +41,7 @@ ReadaheadSource::~ReadaheadSource() {
vStreamBufferDeleteWithCaps(buffer_);
}
auto ReadaheadSource::Read(cpp::span<std::byte> dest) -> ssize_t {
auto ReadaheadSource::Read(std::span<std::byte> dest) -> ssize_t {
size_t bytes_written = 0;
// Fill the destination from our buffer, until either the buffer is drained
// or the destination is full.

@ -38,8 +38,8 @@ Resampler::~Resampler() {
speex_resampler_destroy(resampler_);
}
auto Resampler::Process(cpp::span<sample::Sample> input,
cpp::span<sample::Sample> output,
auto Resampler::Process(std::span<sample::Sample> input,
std::span<sample::Sample> output,
bool end_of_data) -> std::pair<size_t, size_t> {
uint32_t samples_used = input.size() / num_channels_;
uint32_t samples_produced = output.size() / num_channels_;

@ -6,7 +6,7 @@ idf_component_register(
SRCS "dr_flac.cpp" "codec.cpp" "mad.cpp" "opus.cpp" "vorbis.cpp"
"source_buffer.cpp" "sample.cpp" "wav.cpp"
INCLUDE_DIRS "include"
REQUIRES "result" "span" "libmad" "drflac" "tremor" "opusfile" "memory" "util"
REQUIRES "result" "libmad" "drflac" "tremor" "opusfile" "memory" "util"
"komihash")
target_compile_options("${COMPONENT_LIB}" PRIVATE ${EXTRA_WARNINGS})

@ -100,7 +100,7 @@ auto DrFlacDecoder::OpenStream(std::shared_ptr<IStream> input, uint32_t offset)
return format;
}
auto DrFlacDecoder::DecodeTo(cpp::span<sample::Sample> output)
auto DrFlacDecoder::DecodeTo(std::span<sample::Sample> output)
-> cpp::result<OutputInfo, Error> {
size_t frames_to_read = output.size() / flac_->channels / 2;

@ -6,19 +6,16 @@
#pragma once
#include <stdint.h>
#include <sys/_stdint.h>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include "result.hpp"
#include "sample.hpp"
#include "span.hpp"
#include "types.hpp"
#include "memory_resource.hpp"
@ -35,7 +32,7 @@ class IStream {
auto type() -> StreamType { return t_; }
virtual auto Read(cpp::span<std::byte> dest) -> ssize_t = 0;
virtual auto Read(std::span<std::byte> dest) -> ssize_t = 0;
virtual auto CanSeek() -> bool = 0;
@ -128,7 +125,7 @@ class ICodec {
/*
* Writes PCM samples to the given output buffer.
*/
virtual auto DecodeTo(cpp::span<sample::Sample> destination)
virtual auto DecodeTo(std::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> = 0;
};

@ -10,13 +10,13 @@
#include <cstdint>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include "dr_flac.h"
#include "sample.hpp"
#include "source_buffer.hpp"
#include "span.hpp"
#include "codec.hpp"
@ -30,7 +30,7 @@ class DrFlacDecoder : public ICodec {
auto OpenStream(std::shared_ptr<IStream> input, uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)
auto DecodeTo(std::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
DrFlacDecoder(const DrFlacDecoder&) = delete;

@ -11,11 +11,11 @@
#include <optional>
#include <string>
#include <utility>
#include <span>
#include "mad.h"
#include "sample.hpp"
#include "source_buffer.hpp"
#include "span.hpp"
#include "codec.hpp"
@ -29,7 +29,7 @@ class MadMp3Decoder : public ICodec {
auto OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)
auto DecodeTo(std::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
MadMp3Decoder(const MadMp3Decoder&) = delete;

@ -10,12 +10,12 @@
#include <cstdint>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include "opusfile.h"
#include "sample.hpp"
#include "span.hpp"
#include "codec.hpp"
@ -29,7 +29,7 @@ class XiphOpusDecoder : public ICodec {
auto OpenStream(std::shared_ptr<IStream> input, uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)
auto DecodeTo(std::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
XiphOpusDecoder(const XiphOpusDecoder&) = delete;

@ -9,8 +9,7 @@
#include <cstddef>
#include <cstdint>
#include <functional>
#include "span.hpp"
#include <span>
#include "codec.hpp"
@ -22,15 +21,15 @@ class SourceBuffer {
~SourceBuffer();
auto Refill(IStream* src) -> bool;
auto AddBytes(std::function<size_t(cpp::span<std::byte>)> writer) -> void;
auto ConsumeBytes(std::function<size_t(cpp::span<std::byte>)> reader) -> void;
auto AddBytes(std::function<size_t(std::span<std::byte>)> writer) -> void;
auto ConsumeBytes(std::function<size_t(std::span<std::byte>)> reader) -> void;
auto Empty() -> void;
SourceBuffer(const SourceBuffer&) = delete;
SourceBuffer& operator=(const SourceBuffer&) = delete;
private:
const cpp::span<std::byte> buffer_;
const std::span<std::byte> buffer_;
size_t bytes_in_buffer_;
size_t offset_of_bytes_;
};

@ -10,12 +10,12 @@
#include <cstdint>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include "ivorbisfile.h"
#include "sample.hpp"
#include "span.hpp"
#include "codec.hpp"
@ -29,7 +29,7 @@ class TremorVorbisDecoder : public ICodec {
auto OpenStream(std::shared_ptr<IStream> input, uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)
auto DecodeTo(std::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
TremorVorbisDecoder(const TremorVorbisDecoder&) = delete;

@ -34,7 +34,7 @@ class WavDecoder : public ICodec {
auto OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
-> cpp::result<OutputFormat, Error> override;
auto DecodeTo(cpp::span<sample::Sample> destination)
auto DecodeTo(std::span<sample::Sample> destination)
-> cpp::result<OutputInfo, Error> override;
WavDecoder(const WavDecoder&) = delete;

@ -74,7 +74,7 @@ auto MadMp3Decoder::OpenStream(std::shared_ptr<IStream> input, uint32_t offset)
while (!eof && !got_header) {
eof = buffer_.Refill(input_.get());
buffer_.ConsumeBytes([&](cpp::span<std::byte> buf) -> size_t {
buffer_.ConsumeBytes([&](std::span<std::byte> buf) -> size_t {
mad_stream_buffer(stream_.get(),
reinterpret_cast<const unsigned char*>(buf.data()),
buf.size_bytes());
@ -130,7 +130,7 @@ auto MadMp3Decoder::OpenStream(std::shared_ptr<IStream> input, uint32_t offset)
}
need_refill = false;
buffer_.ConsumeBytes([&](cpp::span<std::byte> buf) -> size_t {
buffer_.ConsumeBytes([&](std::span<std::byte> buf) -> size_t {
mad_stream_buffer(stream_.get(),
reinterpret_cast<const unsigned char*>(buf.data()),
buf.size());
@ -156,13 +156,13 @@ auto MadMp3Decoder::OpenStream(std::shared_ptr<IStream> input, uint32_t offset)
return output;
}
auto MadMp3Decoder::DecodeTo(cpp::span<sample::Sample> output)
auto MadMp3Decoder::DecodeTo(std::span<sample::Sample> output)
-> cpp::result<OutputInfo, Error> {
if (current_sample_ < 0 && !is_eos_) {
if (!is_eof_) {
is_eof_ = buffer_.Refill(input_.get());
if (is_eof_) {
buffer_.AddBytes([&](cpp::span<std::byte> buf) -> size_t {
buffer_.AddBytes([&](std::span<std::byte> buf) -> size_t {
if (buf.size() < MAD_BUFFER_GUARD) {
is_eof_ = false;
return 0;
@ -174,7 +174,7 @@ auto MadMp3Decoder::DecodeTo(cpp::span<sample::Sample> output)
}
}
buffer_.ConsumeBytes([&](cpp::span<std::byte> buf) -> size_t {
buffer_.ConsumeBytes([&](std::span<std::byte> buf) -> size_t {
mad_stream_buffer(stream_.get(),
reinterpret_cast<const unsigned char*>(buf.data()),
buf.size());

@ -140,7 +140,7 @@ auto XiphOpusDecoder::OpenStream(std::shared_ptr<IStream> input,
};
}
auto XiphOpusDecoder::DecodeTo(cpp::span<sample::Sample> output)
auto XiphOpusDecoder::DecodeTo(std::span<sample::Sample> output)
-> cpp::result<OutputInfo, Error> {
int samples_written = op_read_stereo(opus_, output.data(), output.size());

@ -39,7 +39,7 @@ auto SourceBuffer::Refill(IStream* src) -> bool {
return false;
}
bool eof = false;
AddBytes([&](cpp::span<std::byte> buf) -> size_t {
AddBytes([&](std::span<std::byte> buf) -> size_t {
ssize_t bytes_read = src->Read(buf);
// Treat read errors as EOF.
eof = bytes_read <= 0;
@ -48,7 +48,7 @@ auto SourceBuffer::Refill(IStream* src) -> bool {
return eof;
}
auto SourceBuffer::AddBytes(std::function<size_t(cpp::span<std::byte>)> writer)
auto SourceBuffer::AddBytes(std::function<size_t(std::span<std::byte>)> writer)
-> void {
if (offset_of_bytes_ > 0) {
std::memmove(buffer_.data(), buffer_.data() + offset_of_bytes_,
@ -61,7 +61,7 @@ auto SourceBuffer::AddBytes(std::function<size_t(cpp::span<std::byte>)> writer)
}
auto SourceBuffer::ConsumeBytes(
std::function<size_t(cpp::span<std::byte>)> reader) -> void {
std::function<size_t(std::span<std::byte>)> reader) -> void {
size_t bytes_consumed = std::invoke(
reader, buffer_.subspan(offset_of_bytes_, bytes_in_buffer_));
assert(bytes_consumed <= bytes_in_buffer_);

@ -8,14 +8,14 @@
#include <algorithm>
#include <cstdint>
#include <span>
#include "catch2/catch.hpp"
#include "span.hpp"
#include "test.mp3.hpp"
void load_mp3(cpp::span<std::byte> dest) {
cpp::span<std::byte> src(reinterpret_cast<std::byte*>(test_mp3),
void load_mp3(std::span<std::byte> dest) {
std::span<std::byte> src(reinterpret_cast<std::byte*>(test_mp3),
test_mp3_len);
std::copy(src.begin(), src.begin() + dest.size(), dest.begin());
}

@ -129,7 +129,7 @@ auto TremorVorbisDecoder::OpenStream(std::shared_ptr<IStream> input,
};
}
auto TremorVorbisDecoder::DecodeTo(cpp::span<sample::Sample> output)
auto TremorVorbisDecoder::DecodeTo(std::span<sample::Sample> output)
-> cpp::result<OutputInfo, Error> {
int unused = 0;
long bytes_written =

@ -20,24 +20,24 @@ namespace codecs {
[[maybe_unused]] static const char kTag[] = "wav";
static inline auto bytes_to_u16(cpp::span<std::byte const, 2> bytes)
static inline auto bytes_to_u16(std::span<std::byte const, 2> bytes)
-> uint16_t {
return (uint16_t)bytes[0] | (uint16_t)bytes[1] << 8;
}
static inline auto bytes_to_u32(cpp::span<std::byte const, 4> bytes)
static inline auto bytes_to_u32(std::span<std::byte const, 4> bytes)
-> uint32_t {
return (uint32_t)bytes[0] | (uint32_t)bytes[1] << 8 |
(uint32_t)bytes[2] << 16 | (uint32_t)bytes[3] << 24;
}
static inline auto bytes_to_str(cpp::span<std::byte const> bytes)
static inline auto bytes_to_str(std::span<std::byte const> bytes)
-> std::string {
return std::string(reinterpret_cast<const char*>(bytes.data()),
bytes.size_bytes());
}
static int16_t convert_f32_to_16_bit(cpp::span<const std::byte> bytes) {
static int16_t convert_f32_to_16_bit(std::span<const std::byte> bytes) {
uint64_t val = 0;
val = (uint8_t)bytes[3];
val = (val << 8) | (uint8_t)bytes[2];
@ -57,7 +57,7 @@ static int16_t convert_f32_to_16_bit(cpp::span<const std::byte> bytes) {
return sample::FromDouble(*fval);
}
static int16_t convert_f64_to_16_bit(cpp::span<const std::byte> bytes) {
static int16_t convert_f64_to_16_bit(std::span<const std::byte> bytes) {
uint64_t val = 0;
val = (uint8_t)bytes[7];
val = (val << 8) | (uint8_t)bytes[6];
@ -71,7 +71,7 @@ static int16_t convert_f64_to_16_bit(cpp::span<const std::byte> bytes) {
return sample::FromDouble(*fval);
}
static int16_t convert_to_16_bit(cpp::span<const std::byte> bytes) {
static int16_t convert_to_16_bit(std::span<const std::byte> bytes) {
int depth = bytes.size();
int32_t val = 0;
// If 8-bit Assume Unsigned
@ -82,10 +82,13 @@ static int16_t convert_to_16_bit(cpp::span<const std::byte> bytes) {
switch (depth) {
case 4:
val = (uint8_t)bytes[3];
[[fallthrough]];
case 3:
val = (val << 8) | (uint8_t)bytes[2];
[[fallthrough]];
case 2:
val = (val << 8) | (uint8_t)bytes[1];
[[fallthrough]];
case 1:
val = (val << 8) | (uint8_t)bytes[0];
}
@ -123,7 +126,7 @@ auto WavDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
// - end of this part, next header we care about is 'data'
// - and then the next 4 bytes = 32 bit int = size of data
auto buffer_span = cpp::span{buf};
auto buffer_span = std::span{buf};
std::string riff = bytes_to_str(buffer_span.subspan(0, 4));
if (riff != "RIFF") {
@ -131,7 +134,7 @@ auto WavDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
return cpp::fail(Error::kMalformedData);
}
uint32_t file_size = bytes_to_u32(buffer_span.subspan(4, 4)) + 8;
// uint32_t file_size = bytes_to_u32(buffer_span.subspan(4, 4)) + 8;
std::string fmt_header = bytes_to_str(buffer_span.subspan(12, 4));
ESP_LOGI(kTag, "fmt header found? %s",
@ -142,9 +145,9 @@ auto WavDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
}
// Size of the fmt header, should be 16, 18 or 40
uint32_t fmt_header_size = bytes_to_u32(buffer_span.subspan(16, 4));
// uint32_t fmt_header_size = bytes_to_u32(buffer_span.subspan(16, 4));
wave_format_ = bytes_to_u16(buffer_span.subspan(20, 2));
wave_format_ = bytes_to_u16(buffer_span.subspan<20, 2>());
if (wave_format_ == kWaveFormatPCM) {
ESP_LOGD(kTag, "wave format: PCM");
} else if (wave_format_ == kWaveFormatExtensible) {
@ -156,17 +159,17 @@ auto WavDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
return cpp::fail(Error::kUnsupportedFormat);
}
num_channels_ = bytes_to_u16(buffer_span.subspan(22, 2));
num_channels_ = bytes_to_u16(buffer_span.subspan<22, 2>());
uint32_t samples_per_second = bytes_to_u32(buffer_span.subspan(24, 4));
uint32_t samples_per_second = bytes_to_u32(buffer_span.subspan<24, 4>());
uint32_t avg_bytes_per_second = bytes_to_u32(buffer_span.subspan(28, 4));
// uint32_t avg_bytes_per_second = bytes_to_u32(buffer_span.subspan(28, 4));
uint16_t block_align = bytes_to_u16(buffer_span.subspan(32, 2));
uint16_t block_align = bytes_to_u16(buffer_span.subspan<32, 2>());
bytes_per_sample_ = block_align / num_channels_;
uint16_t bits_per_sample = bytes_to_u16(buffer_span.subspan(34, 2));
// uint16_t bits_per_sample = bytes_to_u16(buffer_span.subspan(34, 2));
// find the start of the data chunk
std::array<std::byte, 4> data_tag = {std::byte{0x64}, std::byte{0x61},
@ -180,7 +183,7 @@ auto WavDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
int data_chunk_index = std::distance(buffer_span.begin(), data_loc.begin());
uint32_t data_chunk_size =
bytes_to_u32(buffer_span.subspan(data_chunk_index + 4, 4));
bytes_to_u32(buffer_span.subspan(data_chunk_index + 4, 4).first<4>());
// calculate number of samples
int number_of_samples = data_chunk_size / bytes_per_sample_;
@ -188,20 +191,20 @@ auto WavDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
// extension to the fmt chunk size (0 or 22)
uint16_t extension_size = 0;
if (wave_format_ == kWaveFormatExtensible) {
extension_size = bytes_to_u16(buffer_span.subspan(36, 2));
extension_size = bytes_to_u16(buffer_span.subspan<36, 2>());
}
// Parse extension if applicable
if (extension_size == 22) {
// Valid bits per sample
uint16_t valid_bits_per_sample = bytes_to_u16(buffer_span.subspan(38, 2));
// uint16_t valid_bits_per_sample = bytes_to_u16(buffer_span.subspan(38,
// 2));
uint32_t speaker_mask = bytes_to_u32(buffer_span.subspan(40, 4));
// uint32_t speaker_mask = bytes_to_u32(buffer_span.subspan(40, 4));
// Parse subformat
subformat_ = bytes_to_u16(buffer_span.subspan(44, 2));
if (!(subformat_ == kWaveFormatPCM ||
subformat_ == kWaveFormatIEEEFloat)) {
subformat_ = bytes_to_u16(buffer_span.subspan<44, 2>());
if (!(subformat_ == kWaveFormatPCM || subformat_ == kWaveFormatIEEEFloat)) {
ESP_LOGW(kTag, "WAVE extensible subformat_ not supported");
return cpp::fail(Error::kUnsupportedFormat);
}
@ -210,7 +213,8 @@ auto WavDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
int64_t data_offset = offset * samples_per_second * bytes_per_sample_;
// Seek track to start of data
input->SeekTo(data_chunk_index + 8 + data_offset, IStream::SeekFrom::kStartOfStream);
input->SeekTo(data_chunk_index + 8 + data_offset,
IStream::SeekFrom::kStartOfStream);
output_format_ = {.num_channels = (uint8_t)num_channels_,
.sample_rate_hz = samples_per_second,
@ -219,12 +223,12 @@ auto WavDecoder::OpenStream(std::shared_ptr<IStream> input,uint32_t offset)
return output_format_;
}
auto WavDecoder::DecodeTo(cpp::span<sample::Sample> output)
auto WavDecoder::DecodeTo(std::span<sample::Sample> output)
-> cpp::result<OutputInfo, Error> {
bool is_eof = buffer_.Refill(input_.get());
size_t samples_written = 0;
buffer_.ConsumeBytes([&](cpp::span<std::byte> buf) -> size_t {
buffer_.ConsumeBytes([&](std::span<std::byte> buf) -> size_t {
size_t bytes_read = buf.size_bytes();
size_t frames_read =
bytes_read / bytes_per_sample_ / output_format_.num_channels;
@ -254,7 +258,6 @@ auto WavDecoder::DecodeTo(cpp::span<sample::Sample> output)
return samples_written * bytes_per_sample_;
});
return OutputInfo{.samples_written = samples_written,
.is_stream_finished = samples_written == 0 && is_eof};
}

@ -6,7 +6,7 @@ idf_component_register(
SRCS "env_esp.cpp" "database.cpp" "track.cpp" "records.cpp"
"file_gatherer.cpp" "tag_parser.cpp" "index.cpp"
INCLUDE_DIRS "include"
REQUIRES "result" "span" "esp_psram" "fatfs" "libtags" "komihash" "cbor"
REQUIRES "result" "esp_psram" "fatfs" "libtags" "komihash" "cbor"
"tasks" "memory" "util" "tinyfsm" "events" "opusfile" "libcppbor")
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})

@ -80,6 +80,6 @@ auto TrackIdToBytes(TrackId id) -> std::string;
* Converts a track id encoded via TrackIdToBytes back into a TrackId. May
* return nullopt if parsing fails.
*/
auto BytesToTrackId(cpp::span<const char> bytes) -> std::optional<TrackId>;
auto BytesToTrackId(std::span<const char> bytes) -> std::optional<TrackId>;
} // namespace database

@ -6,12 +6,12 @@
#pragma once
#include <stdint.h>
#include <sys/_stdint.h>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <unordered_map>
#include <utility>
@ -19,7 +19,6 @@
#include "leveldb/db.h"
#include "memory_resource.hpp"
#include "span.hpp"
namespace database {
@ -62,7 +61,7 @@ enum class Tag {
using TagValue = std::variant<std::monostate,
std::pmr::string,
uint32_t,
cpp::span<const std::pmr::string>>;
std::span<const std::pmr::string>>;
auto tagName(Tag) -> std::string;
auto tagHash(const TagValue&) -> uint64_t;
@ -112,7 +111,7 @@ class TrackTags {
auto albumOrder() const -> uint32_t;
auto genres() const -> cpp::span<const std::pmr::string>;
auto genres() const -> std::span<const std::pmr::string>;
auto genres(const std::string_view) -> void;
/*

@ -61,11 +61,11 @@ class Indexer {
private:
auto handleLevel(const IndexKey::Header& header,
cpp::span<const Tag> components) -> void;
std::span<const Tag> components) -> void;
auto handleItem(const IndexKey::Header& header,
std::variant<std::pmr::string, uint32_t> item,
cpp::span<const Tag> components) -> void;
std::span<const Tag> components) -> void;
auto missing_value(Tag tag) -> TagValue {
switch (tag) {
@ -111,7 +111,7 @@ auto Indexer::index() -> std::vector<std::pair<IndexKey, std::string>> {
}
auto Indexer::handleLevel(const IndexKey::Header& header,
cpp::span<const Tag> components) -> void {
std::span<const Tag> components) -> void {
Tag component = components.front();
TagValue value = track_.tags().get(component);
if (std::holds_alternative<std::monostate>(value)) {
@ -129,7 +129,7 @@ auto Indexer::handleLevel(const IndexKey::Header& header,
} else if constexpr (std::is_same_v<T, uint32_t>) {
handleItem(header, arg, components);
} else if constexpr (std::is_same_v<
T, cpp::span<const std::pmr::string>>) {
T, std::span<const std::pmr::string>>) {
for (const auto& i : arg) {
handleItem(header, i, components);
}
@ -140,7 +140,7 @@ auto Indexer::handleLevel(const IndexKey::Header& header,
auto Indexer::handleItem(const IndexKey::Header& header,
std::variant<std::pmr::string, uint32_t> item,
cpp::span<const Tag> components) -> void {
std::span<const Tag> components) -> void {
IndexKey key{
.header = header,
.item = {},

@ -248,7 +248,7 @@ auto TrackIdToBytes(TrackId id) -> std::string {
return cppbor::Uint{id}.toString();
}
auto BytesToTrackId(cpp::span<const char> bytes) -> std::optional<TrackId> {
auto BytesToTrackId(std::span<const char> bytes) -> std::optional<TrackId> {
auto [res, unused, err] = cppbor::parse(
reinterpret_cast<const uint8_t*>(bytes.data()), bytes.size());
if (!res || res->type() != cppbor::UINT) {

@ -9,6 +9,7 @@
#include <iomanip>
#include <iostream>
#include <memory_resource>
#include <span>
#include <sstream>
#include <string>
@ -16,7 +17,6 @@
#include "komihash.h"
#include "memory_resource.hpp"
#include "span.hpp"
namespace database {
@ -55,7 +55,7 @@ auto tagHash(const TagValue& t) -> uint64_t {
} else if constexpr (std::is_same_v<T, uint32_t>) {
return komihash(&arg, sizeof(arg), 0);
} else if constexpr (std::is_same_v<
T, cpp::span<const std::pmr::string>>) {
T, std::span<const std::pmr::string>>) {
komihash_stream_t hash;
komihash_stream_init(&hash, 0);
for (const auto& i : arg) {
@ -79,7 +79,7 @@ auto tagToString(const TagValue& val) -> std::string {
} else if constexpr (std::is_same_v<T, uint32_t>) {
return std::to_string(arg);
} else if constexpr (std::is_same_v<
T, cpp::span<const std::pmr::string>>) {
T, std::span<const std::pmr::string>>) {
std::ostringstream builder{};
for (const auto& str : arg) {
builder << std::string{str.data(), str.size()} << ",";
@ -225,7 +225,7 @@ auto TrackTags::albumOrder() const -> uint32_t {
return (disc_.value_or(0) << 16) | track_.value_or(0);
}
auto TrackTags::genres() const -> cpp::span<const std::pmr::string> {
auto TrackTags::genres() const -> std::span<const std::pmr::string> {
return genres_;
}

@ -7,6 +7,6 @@ idf_component_register(
"i2c.cpp" "bluetooth.cpp" "spi.cpp" "display.cpp" "display_init.cpp"
"samd.cpp" "wm8523.cpp" "nvs.cpp" "haptics.cpp" "spiffs.cpp"
INCLUDE_DIRS "include"
REQUIRES "esp_adc" "fatfs" "result" "lvgl" "span" "tasks" "nvs_flash" "spiffs"
REQUIRES "esp_adc" "fatfs" "result" "lvgl" "tasks" "nvs_flash" "spiffs"
"bt" "tinyfsm" "util")
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})

@ -207,7 +207,7 @@ auto I2SDac::Reconfigure(Channels ch, BitsPerSample bps, SampleRate rate)
}
}
auto I2SDac::WriteData(const cpp::span<const std::byte>& data) -> void {
auto I2SDac::WriteData(const std::span<const std::byte>& data) -> void {
std::size_t bytes_written = 0;
esp_err_t err = i2s_channel_write(i2s_handle_, data.data(), data.size_bytes(),
&bytes_written, portMAX_DELAY);

@ -12,6 +12,7 @@
#include <memory>
#include <optional>
#include <utility>
#include <span>
#include "driver/i2s_std.h"
#include "driver/i2s_types.h"
@ -20,7 +21,6 @@
#include "freertos/portmacro.h"
#include "freertos/stream_buffer.h"
#include "result.hpp"
#include "span.hpp"
#include "gpios.hpp"
#include "sys/_stdint.h"
@ -68,7 +68,7 @@ class I2SDac {
auto Reconfigure(Channels ch, BitsPerSample bps, SampleRate rate) -> void;
auto WriteData(const cpp::span<const std::byte>& data) -> void;
auto WriteData(const std::span<const std::byte>& data) -> void;
auto SetSource(StreamBufferHandle_t buffer) -> void;
// Not copyable or movable.

@ -6,6 +6,6 @@ idf_component_register(
SRCS "collation.cpp" "strxfrm_l.c"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "priv_include"
REQUIRES "span" "esp_partition" "spi_flash")
REQUIRES "esp_partition" "spi_flash")
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})

@ -9,10 +9,10 @@
#include <cstddef>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include "esp_partition.h"
#include "span.hpp"
#include "strxfrm.h"

@ -247,7 +247,7 @@ static auto pushTagValue(lua_State* L, const database::TagValue& val) -> void {
if constexpr (std::is_same_v<T, std::pmr::string>) {
lua_pushlstring(L, arg.data(), arg.size());
} else if constexpr (std::is_same_v<
T, cpp::span<const std::pmr::string>>) {
T, std::span<const std::pmr::string>>) {
lua_createtable(L, 0, arg.size());
for (const auto& i : arg) {
lua_pushlstring(L, i.data(), i.size());

@ -8,9 +8,9 @@
#include <cstddef>
#include <cstdint>
#include <span>
#include "esp32/himem.h"
#include "span.hpp"
/*
* Wrapper around an ESP-IDF himem allocation, which uses RAII to clean up after
@ -62,14 +62,14 @@ class MappableRegion {
}
}
auto Get() -> cpp::span<std::byte> {
auto Get() -> std::span<std::byte> {
if (bytes_ == nullptr) {
return {};
}
return {bytes_, size};
}
auto Map(const HimemAlloc<size>& alloc) -> cpp::span<std::byte> {
auto Map(const HimemAlloc<size>& alloc) -> std::span<std::byte> {
assert(bytes_ == nullptr);
ESP_ERROR_CHECK(esp_himem_map(alloc.handle, range_handle, 0, 0, size, 0,
reinterpret_cast<void**>(&bytes_)));

@ -1,5 +1,5 @@
# Copyright 2023 jacqueline <me@jacqueline.id.au>
#
# SPDX-License-Identifier: GPL-3.0-only
idf_component_register(SRCS "tasks.cpp" INCLUDE_DIRS "." REQUIRES "span" "memory")
idf_component_register(SRCS "tasks.cpp" INCLUDE_DIRS "." REQUIRES "memory")
target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS})

@ -33,12 +33,12 @@ auto Name<Type::kAudioConverter>() -> std::pmr::string {
}
template <Type t>
auto AllocateStack() -> cpp::span<StackType_t>;
auto AllocateStack() -> std::span<StackType_t>;
// Decoders often require a very large amount of stack space, since they aren't
// usually written with embedded use cases in mind.
template <>
auto AllocateStack<Type::kAudioDecoder>() -> cpp::span<StackType_t> {
auto AllocateStack<Type::kAudioDecoder>() -> std::span<StackType_t> {
constexpr std::size_t size = 20 * 1024;
static StackType_t sStack[size];
return {sStack, size};
@ -46,14 +46,14 @@ auto AllocateStack<Type::kAudioDecoder>() -> cpp::span<StackType_t> {
// LVGL requires only a relatively small stack. Lua's stack is allocated
// separately.
template <>
auto AllocateStack<Type::kUi>() -> cpp::span<StackType_t> {
auto AllocateStack<Type::kUi>() -> std::span<StackType_t> {
constexpr std::size_t size = 14 * 1024;
static StackType_t sStack[size];
return {sStack, size};
}
template <>
// PCM conversion and resampling uses a very small amount of stack.
auto AllocateStack<Type::kAudioConverter>() -> cpp::span<StackType_t> {
auto AllocateStack<Type::kAudioConverter>() -> std::span<StackType_t> {
constexpr std::size_t size = 4 * 1024;
static StackType_t sStack[size];
return {sStack, size};
@ -63,7 +63,7 @@ auto AllocateStack<Type::kAudioConverter>() -> cpp::span<StackType_t> {
// cases, where large stack usage isn't so much of a concern. It therefore uses
// an eye-wateringly large amount of stack.
template <>
auto AllocateStack<Type::kBackgroundWorker>() -> cpp::span<StackType_t> {
auto AllocateStack<Type::kBackgroundWorker>() -> std::span<StackType_t> {
std::size_t size = 64 * 1024;
return {static_cast<StackType_t*>(heap_caps_malloc(size, MALLOC_CAP_SPIRAM)),
size};

@ -11,6 +11,7 @@
#include <future>
#include <memory>
#include <memory_resource>
#include <span>
#include <string>
#include "esp_heap_caps.h"
@ -19,7 +20,6 @@
#include "freertos/projdefs.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "span.hpp"
namespace tasks {
@ -46,7 +46,7 @@ enum class Type {
template <Type t>
auto Name() -> std::pmr::string;
template <Type t>
auto AllocateStack() -> cpp::span<StackType_t>;
auto AllocateStack() -> std::span<StackType_t>;
template <Type t>
auto Priority() -> UBaseType_t;
@ -56,7 +56,7 @@ template <Type t>
auto StartPersistent(const std::function<void(void)>& fn) -> void {
StaticTask_t* task_buffer = static_cast<StaticTask_t*>(heap_caps_malloc(
sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
cpp::span<StackType_t> stack = AllocateStack<t>();
std::span<StackType_t> stack = AllocateStack<t>();
xTaskCreateStatic(&PersistentMain, Name<t>().c_str(), stack.size(),
new std::function<void(void)>(fn), Priority<t>(),
stack.data(), task_buffer);
@ -67,7 +67,7 @@ auto StartPersistent(BaseType_t core, const std::function<void(void)>& fn)
-> void {
StaticTask_t* task_buffer = static_cast<StaticTask_t*>(heap_caps_malloc(
sizeof(StaticTask_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT));
cpp::span<StackType_t> stack = AllocateStack<t>();
std::span<StackType_t> stack = AllocateStack<t>();
xTaskCreateStaticPinnedToCore(&PersistentMain, Name<t>().c_str(),
stack.size(), new std::function<void(void)>(fn),
Priority<t>(), stack.data(), task_buffer, core);

@ -2,4 +2,4 @@
#
# SPDX-License-Identifier: GPL-3.0-only
idf_component_register(SRCS INCLUDE_DIRS "include" REQUIRES "database" "span")
idf_component_register(SRCS INCLUDE_DIRS "include" REQUIRES "database")

@ -8,13 +8,12 @@
#include <iomanip>
#include <ostream>
#include <span>
#include <string>
#include "span.hpp"
namespace util {
inline std::string format_hex_string(cpp::span<const std::byte> data) {
inline std::string format_hex_string(std::span<const std::byte> data) {
std::ostringstream oss;
std::ostringstream ascii_values;
int count = 0;

@ -33,7 +33,6 @@ list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/drflac")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/ogg")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/opusfile")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/result")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/span")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/speexdsp")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/tinyfsm")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{PROJ_PATH}/lib/tremor")

Loading…
Cancel
Save