Skip to content

Commit

Permalink
Convert to wav before bpm detection
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiashienzsch committed Jun 13, 2022
1 parent 59cb1e8 commit d2da606
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 1 deletion.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ target_sources(StiggiDJ

"src/Core/Array.hpp"

"src/DSP/AudioFileConverter.hpp"
"src/DSP/BeatTrack.cpp"
"src/DSP/BeatTrack.hpp"
"src/DSP/DJPlayer.cpp"
Expand Down
60 changes: 60 additions & 0 deletions src/DSP/AudioFileConverter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#pragma once

#include <juce_audio_formats/juce_audio_formats.h>
#include <juce_core/juce_core.h>

namespace ta
{

struct AudioFileConverterOptions
{
juce::File source{};
juce::File destination{};
};

struct AudioFileConverterResult
{
bool success{false};
juce::String errorMessage{};
};

struct AudioFileConverter
{
using Options = AudioFileConverterOptions;
using Result = AudioFileConverterResult;

AudioFileConverter();

template<typename DestinationFormat>
auto convert(Options const& options) -> Result;

private:
juce::AudioFormatManager _formatManager;
};

inline AudioFileConverter::AudioFileConverter() { _formatManager.registerBasicFormats(); }

template<typename DestinationFormat>
inline auto AudioFileConverter::convert(Options const& options) -> Result
{
auto reader = std::unique_ptr<juce::AudioFormatReader>(_formatManager.createReaderFor(options.source));
if (reader == nullptr) { return Result{false, "Invalid file"}; }

DestinationFormat format{};
auto const sr = reader->sampleRate;
auto const ch = reader->numChannels;
auto const bits = reader->bitsPerSample;

auto out = std::make_unique<juce::FileOutputStream>(options.destination);
auto writer = std::unique_ptr<juce::AudioFormatWriter>(format.createWriterFor(out.get(), sr, ch, bits, {}, 0));

if (writer == nullptr) { return Result{false, "Failed to convert to wav"}; }
out.release(); // writer took ownership

writer->writeFromAudioReader(*reader, 0, reader->lengthInSamples);
writer->flush();

return Result{true, {}};
}

} // namespace ta
10 changes: 9 additions & 1 deletion src/DSP/BeatTrack.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
#include "BeatTrack.hpp"

#include "DSP/AudioFileConverter.hpp"

namespace ta
{
auto beatTrack(juce::File const& audioFile) -> BeatTrackResult
{
juce::TemporaryFile tmpFile{};
AudioFileConverter converter{};
auto const convertOptions = AudioFileConverterOptions{audioFile, tmpFile.getFile()};
auto const convertResult = converter.convert<juce::WavAudioFormat>(convertOptions);
if (!convertResult.success) { return BeatTrackResult{convertResult.errorMessage}; }

auto const* pythonPath = "/home/tobante/Developer/tobanteAudio/StiggiDJ/venv/bin/python3";
auto const scriptDir = juce::File{"/home/tobante/Developer/tobanteAudio/StiggiDJ/src/Scripts"};
auto const scriptPath = scriptDir.getChildFile("bpm_track.py");

juce::ChildProcess process{};
auto processArgs = juce::StringArray{pythonPath, scriptPath.getFullPathName(), audioFile.getFullPathName()};
auto processArgs = juce::StringArray{pythonPath, scriptPath.getFullPathName(), tmpFile.getFile().getFullPathName()};
if (!process.start(processArgs)) { return BeatTrackResult{"Failed to start"}; }
if (!process.waitForProcessToFinish(10'000)) { return BeatTrackResult{"Timeout"}; }

Expand Down

0 comments on commit d2da606

Please sign in to comment.