Add a stream source that generates a sine wave
This commit is contained in:
@@ -86,6 +86,10 @@ struct SetTrack : tinyfsm::Event {
|
||||
std::optional<uint32_t> seek_to_second;
|
||||
};
|
||||
|
||||
struct PlaySineWave : tinyfsm::Event {
|
||||
uint32_t frequency;
|
||||
};
|
||||
|
||||
struct TogglePlayPause : tinyfsm::Event {
|
||||
std::optional<bool> set_to;
|
||||
};
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
#include "audio/audio_source.hpp"
|
||||
#include "audio/sine_source.hpp"
|
||||
#include "cppbor.h"
|
||||
#include "cppbor_parse.h"
|
||||
#include "esp_heap_caps.h"
|
||||
@@ -146,6 +148,17 @@ void AudioState::react(const SetTrack& ev) {
|
||||
});
|
||||
}
|
||||
|
||||
void AudioState::react(const PlaySineWave& ev) {
|
||||
auto tags = std::make_shared<database::TrackTags>();
|
||||
|
||||
std::stringstream title;
|
||||
title << ev.frequency << "Hz Sine Wave";
|
||||
tags->title(title.str());
|
||||
|
||||
sDecoder->open(std::make_shared<TaggedStream>(
|
||||
tags, std::make_unique<SineSource>(ev.frequency), title.str()));
|
||||
}
|
||||
|
||||
void AudioState::react(const TogglePlayPause& ev) {
|
||||
sIsPaused = !ev.set_to.value_or(sIsPaused);
|
||||
if (!sIsPaused && is_in_state<states::Standby>() &&
|
||||
|
||||
@@ -44,6 +44,7 @@ class AudioState : public tinyfsm::Fsm<AudioState> {
|
||||
void react(const tinyfsm::Event& ev) {}
|
||||
|
||||
void react(const QueueUpdate&);
|
||||
void react(const PlaySineWave&);
|
||||
void react(const SetTrack&);
|
||||
void react(const TogglePlayPause&);
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2023 jacqueline <me@jacqueline.id.au>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
#include "audio/sine_source.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <numbers>
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "audio/audio_source.hpp"
|
||||
#include "codec.hpp"
|
||||
#include "drivers/spi.hpp"
|
||||
#include "sample.hpp"
|
||||
#include "system_fsm/system_events.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
namespace audio {
|
||||
|
||||
[[maybe_unused]] static constexpr char kTag[] = "sine_src";
|
||||
|
||||
SineSource::SineSource(uint32_t freq)
|
||||
: IStream(codecs::StreamType::kNative),
|
||||
step_(0),
|
||||
increment_((2.0 * std::numbers::pi) / (48000.0 / freq)) {}
|
||||
|
||||
auto SineSource::Read(std::span<std::byte> dest_bytes) -> ssize_t {
|
||||
std::span<sample::Sample> dest{
|
||||
reinterpret_cast<sample::Sample*>(dest_bytes.data()),
|
||||
dest_bytes.size_bytes() / sizeof(sample::Sample)};
|
||||
|
||||
for (size_t i = 0; i < dest.size(); i++) {
|
||||
dest[i] = std::numeric_limits<sample::Sample>::max() *
|
||||
std::sin(step_ += increment_);
|
||||
}
|
||||
|
||||
return dest.size_bytes();
|
||||
}
|
||||
|
||||
auto SineSource::CanSeek() -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto SineSource::SeekTo(int64_t destination, SeekFrom from) -> void {}
|
||||
|
||||
auto SineSource::CurrentPosition() -> int64_t {
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto SineSource::Size() -> std::optional<int64_t> {
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace audio
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2023 jacqueline <me@jacqueline.id.au>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-only
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "codec.hpp"
|
||||
#include "ff.h"
|
||||
|
||||
#include "audio/audio_source.hpp"
|
||||
|
||||
namespace audio {
|
||||
|
||||
/*
|
||||
* Generates an infinitely long sine wave of a specified frequency.
|
||||
*/
|
||||
class SineSource : public codecs::IStream {
|
||||
public:
|
||||
SineSource(uint32_t frequency);
|
||||
|
||||
auto Read(std::span<std::byte> dest) -> ssize_t override;
|
||||
|
||||
auto CanSeek() -> bool override;
|
||||
|
||||
auto SeekTo(int64_t destination, SeekFrom from) -> void override;
|
||||
|
||||
auto CurrentPosition() -> int64_t override;
|
||||
|
||||
auto Size() -> std::optional<int64_t> override;
|
||||
|
||||
SineSource(const SineSource&) = delete;
|
||||
SineSource& operator=(const SineSource&) = delete;
|
||||
|
||||
private:
|
||||
double step_;
|
||||
double increment_;
|
||||
};
|
||||
|
||||
} // namespace audio
|
||||
Reference in New Issue
Block a user