Skip to content

Commit

Permalink
debug: SPU stereo recording to wav file
Browse files Browse the repository at this point in the history
  • Loading branch information
JaCzekanski committed Aug 2, 2020
1 parent 47bbec1 commit f2bf793
Show file tree
Hide file tree
Showing 9 changed files with 114 additions and 14 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ add_library(core STATIC
src/input/input_manager.cpp
src/sound/adpcm.cpp
src/sound/tables.cpp
src/sound/wave.cpp
src/state/state.cpp
src/stdafx.cpp
src/system.cpp
Expand Down
3 changes: 3 additions & 0 deletions src/device/spu/spu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ void SPU::step(device::cdrom::CDROM* cdrom) {

audioBufferPos += 2;
if (audioBufferPos >= AUDIO_BUFFER_SIZE) {
if (recording) {
std::copy(audioBuffer.begin(), audioBuffer.end(), std::back_inserter(recordBuffer));
}
audioBufferPos = 0;
bufferReady = true;
}
Expand Down
4 changes: 4 additions & 0 deletions src/device/spu/spu.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ struct SPU {

System* sys;

// Debug
bool recording;
std::vector<uint16_t> recordBuffer;

uint8_t readVoice(uint32_t address) const;
void writeVoice(uint32_t address, uint8_t data);

Expand Down
40 changes: 40 additions & 0 deletions src/platform/windows/gui/debug/spu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
#include <vector>
#include "device/spu/spu.h"
#include "system.h"
#include "sound/wave.h"
#include <SDL.h>
#include <utils/event.h>
#include <iomanip>
#include <config.h>
#include <sstream>
#include "platform/windows/gui/helper/file_dialog.h"

namespace ImGui {
template <typename... Args>
Expand Down Expand Up @@ -297,6 +303,38 @@ void renderSamples(spu::SPU* spu) {
ImGui::PlotLines("Preview", samples.data(), (int)samples.size(), 0, nullptr, -1.0f, 1.0f, ImVec2(400, 80));
}

void SPU::recordingWindow(spu::SPU* spu) {
if (ImGui::Button(spu->recording ? "Pause" : "Record")) {
spu->recording = !spu->recording;
}
if (!spu->recordBuffer.empty()) {
if (!spu->recording) {
ImGui::SameLine();
if (ImGui::Button("Save")) {
auto t = std::time(nullptr);
std::stringstream ss;
ss << std::put_time(std::localtime(&t), "spu-%Y-%m-%d_%H-%M-%S.wav");
auto file = ss.str();

bool saved = wave::writeToFile(spu->recordBuffer, fmt::format("{}/{}", avocado::PATH_USER, file).c_str());
toast(saved ? fmt::format("Saved to {}", file) : fmt::format("Problem saving to {}", file));
if (saved) {
spu->recordBuffer.clear();
showOpenDirectory = true;
}
}
}

ImGui::SameLine();
ImGui::TextUnformatted(fmt::format("{:.2f} seconds captured...", spu->recordBuffer.size() / 44100.f / 2).c_str());
}

if (showOpenDirectory) {
ImGui::SameLine();
gui::helper::openFileBrowserButton(avocado::PATH_USER);
}
}

void SPU::spuWindow(spu::SPU* spu) {
const auto treeFlags = ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_DefaultOpen;
static bool parseValues = true;
Expand All @@ -309,6 +347,8 @@ void SPU::spuWindow(spu::SPU* spu) {

ImGui::Checkbox("Parse values", &parseValues);
renderSamples(spu);

if (ImGui::TreeNodeEx("Recording", treeFlags)) recordingWindow(spu);
ImGui::End();
}

Expand Down
3 changes: 3 additions & 0 deletions src/platform/windows/gui/debug/spu.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ struct SPU;

namespace gui::debug {
class SPU {
bool showOpenDirectory = false;

void spuWindow(spu::SPU* spu);

public:
bool spuWindowOpen = false;
void displayWindows(System* sys);
void recordingWindow(spu::SPU* spu);
};
} // namespace gui::debug
31 changes: 17 additions & 14 deletions src/platform/windows/gui/helper/file_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,20 +227,7 @@ void FileDialog::display(bool& windowOpen) {
ImGui::PopStyleVar();
ImGui::PopStyleVar();

#if defined(__APPLE__)
if (ImGui::Button("Reveal in Finder")) {
openFileBrowser(path.string());
}
#elif defined(_WIN32)
if (ImGui::Button("Open in Explorer")) {
openFileBrowser(path.string());
}
#elif defined(__linux__)
if (ImGui::Button("Open in file explorer")) {
openFileBrowser(path.string());
}
#endif

openFileBrowserButton(path.string());
ImGui::End();

if (!windowOpen) {
Expand All @@ -258,5 +245,21 @@ const std::string formatFileSize(uintmax_t bytes) {
char pre = units.at(exp - 1);

return fmt::format("{:4.0f} {}B", (float)bytes / std::pow(unit, exp), pre);
}

void openFileBrowserButton(const std::string& path) {
#if defined(__APPLE__)
if (ImGui::Button("Reveal in Finder")) {
openFileBrowser(path);
}
#elif defined(_WIN32)
if (ImGui::Button("Open in Explorer")) {
openFileBrowser(path);
}
#elif defined(__linux__)
if (ImGui::Button("Open in file explorer")) {
openFileBrowser(path);
}
#endif
};
}; // namespace gui::helper
2 changes: 2 additions & 0 deletions src/platform/windows/gui/helper/file_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,6 @@ class FileDialog {
};

const std::string formatFileSize(uintmax_t bytes);

void openFileBrowserButton(const std::string& path);
}; // namespace gui::helper
38 changes: 38 additions & 0 deletions src/sound/wave.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "wave.h"

namespace wave {
bool writeToFile(const std::vector<uint16_t>& buffer, const char* filename, int channels) {
FILE* f = fopen(filename, "wb");
if (!f) {
return false;
}
auto wstr = [&](const char* str) { fwrite(str, 1, strlen(str), f); };
auto w32 = [f](uint32_t i) { fwrite(&i, sizeof(i), 1, f); };
auto w16 = [f](uint16_t i) { fwrite(&i, sizeof(i), 1, f); };

const int bitPerSample = 16;
const int sampleRate = 44100;

wstr("RIFF");
w32((buffer.size() * bitPerSample / 8) + 36);

wstr("WAVE");
wstr("fmt ");
w32(16); // Subchunk size
w16(1); // PCM
w16(channels);
w32(sampleRate);
w32(sampleRate * channels * bitPerSample / 8);
w16(channels * bitPerSample / 8);
w16(bitPerSample);

wstr("data");
w32(buffer.size() * bitPerSample / 8);
for (uint16_t s : buffer) {
w16(s);
}

fclose(f);
return true;
}
}; // namespace wave
6 changes: 6 additions & 0 deletions src/sound/wave.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once
#include <vector>

namespace wave {
bool writeToFile(const std::vector<uint16_t>& buffer, const char* filename, int channels = 2);
};

0 comments on commit f2bf793

Please sign in to comment.