Skip to content

Commit

Permalink
✨ (Audio): Add AudioKit
Browse files Browse the repository at this point in the history
Co-Authored-By: Maxime Blanc <[email protected]>
Co-Authored-By: SamHadjes <[email protected]>
  • Loading branch information
3 people committed Mar 18, 2024
1 parent ab90489 commit eadecbf
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 0 deletions.
4 changes: 4 additions & 0 deletions libs/AudioKit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ target_include_directories(AudioKit

target_sources(AudioKit
PRIVATE
source/AudioKit.cpp
source/WavFile.cpp
)

target_link_libraries(AudioKit
mbed-os
CoreSTM32Hal
CoreDAC
CoreEventQueue
FileManagerKit
)
53 changes: 53 additions & 0 deletions libs/AudioKit/include/AudioKit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Leka - LekaOS
// Copyright 2024 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "CoreEventQueue.h"
#include "DigitalOut.h"
#include "FileManagerKit.h"
#include "WavFile.h"
#include "interface/drivers/DAC.h"
#include "interface/drivers/STM32HalBasicTimer.h"

namespace leka {

class AudioKit
{
public:
explicit AudioKit(interface::STM32HalBasicTimer &dac_timer, interface::DACDMA &dac)
: _dac_timer(dac_timer), _dac(dac)
{
// nothing to do
}

void initialize();

void enableAudio();
void disableAudio();

void play(const std::filesystem::path &path);
void stop();

void setData(uint32_t offset);
void run();

private:
mbed::DigitalOut _audio_enable {SOUND_ENABLE, 1};

interface::STM32HalBasicTimer &_dac_timer;
interface::DACDMA &_dac;

FileManagerKit::File _file {};
WavFile _wav_file {_file};

CoreEventQueue _event_queue {};

static constexpr uint32_t played_data_size {2000};
std::array<uint16_t, played_data_size> played_data {};

static constexpr uint8_t _repetition {10};
};

} // namespace leka
86 changes: 86 additions & 0 deletions libs/AudioKit/source/AudioKit.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Leka - LekaOS
// Copyright 2024 APF France handicap
// SPDX-License-Identifier: Apache-2.0

#include "AudioKit.h"

#include "rtos/ThisThread.h"

#include "LogKit.h"

using namespace leka;
using namespace std::chrono_literals;

void AudioKit::initialize()
{
_event_queue.dispatch_forever();

auto onHalfTransfer = [this] { setData(0); };
auto onCompleteTransfer = [this] { setData(played_data_size / 2); };

_dac.registerDMACallbacks([this, onHalfTransfer] { _event_queue.call(onHalfTransfer); },
[this, onCompleteTransfer] { _event_queue.call(onCompleteTransfer); });
_dac.registerDataToPlay(played_data);

constexpr auto file_sample_rate = float {44'100.0};
constexpr auto timer_rate = float {file_sample_rate * _repetition};

_dac_timer.initialize(timer_rate);
_dac.initialize();
}

void AudioKit::enableAudio()
{
_audio_enable = 1;
}

void AudioKit::disableAudio()
{
stop();
_audio_enable = 0;
}

void AudioKit::play(const std::filesystem::path &path)
{
auto is_open = _wav_file.open(path);
if (!is_open) {
return;
}

setData(0);
setData(played_data_size / 2);

enableAudio();

run();
}

void AudioKit::stop()
{
_dac.stop();
}

void AudioKit::setData(uint32_t offset)
{
if (_wav_file.isEndOfFile()) {
stop();
return;
}

constexpr auto file_data_size = played_data_size / _repetition / 2;
auto file_data = std::array<int16_t, file_data_size> {};

_wav_file.read(file_data);

for (uint32_t i = 0; i < file_data.size(); i++) {
auto normalized_value = static_cast<uint16_t>((file_data.at(i) + 0x8000) >> 4);
std::fill_n(played_data.begin() + offset + i * _repetition, _repetition, normalized_value);
}

rtos::ThisThread::sleep_for(2ms); // Related to played_data_size and _repetition
}

void AudioKit::run()
{
_dac.start();
}

0 comments on commit eadecbf

Please sign in to comment.