its kinda working i guess

This commit is contained in:
Lauchmelder23 2021-12-30 23:41:01 +01:00
parent 63aeae6e21
commit c3f1c344c2
6 changed files with 152 additions and 48 deletions

View file

@ -32,8 +32,7 @@ void Application::Quit()
if (window != nullptr)
{
delete file;
delete topology;
delete spectrogram;
manager.Clear();
@ -148,44 +147,15 @@ void Application::Init(int width, int height, const std::string& title)
data.camera = &camera;
data.aspectRatio = (float)width / (float)height;
topology = new ScrollingPlot(
manager,
glm::vec2(15.0f, 15.0f),
glm::uvec2(500, 500),
glm::vec2(-1.0f, 1.0f),
0.001f,
// [](float t, float y)
// {
// return cos(t) + 0.5f * cos(2.0f * t) + 0.1f * sin(1.3f * t) + 0.3f * cos(3.5f * t) + 2.0f * (y * y) - 2.0f;
// }
[](float t, float y)
{
// Weierstraß
float z = 0.0f;
for(unsigned k = 1; k < 100; k++)
{
unsigned int twoK = std::pow(2, k);
z += twoK * sin(twoK * t) * cos(twoK * y) / std::pow(3, k);
}
return z;
}
spectrogram = new Spectrogram(
manager,
glm::vec2(5.0f, 5.0f),
glm::uvec2(200, 2000),
AudioFile("res/payday.wav")
);
colormap = 3;
topology->SetColormap(colormaps[colormap]);
file = new AudioFile("res/payday.wav");
SDL_AudioSpec specs = file->GetAudioSpec();
std::cout << "Channels: " << (int)specs.channels << std::endl;
std::cout << "Format: " << std::bitset<16>{specs.format} << std::endl;
std::cout << "Samples: " << specs.samples << std::endl;
std::cout << "Frequency: " << specs.freq << std::endl;
file->Normalize();
std::cout << "First 50 samples: " << std::endl;
for(auto it = file->begin(); it != file->begin() + 50; it++)
std::cout << *it << std::endl;
spectrogram->SetColormap(colormaps[colormap]);
// glEnable(GL_CULL_FACE);
glEnable(GL_MULTISAMPLE);
@ -205,10 +175,10 @@ void Application::Launch()
camera.SetPosition(pitch, yaw, distance);
topology->SetHeightMapping(enableHeightMap);
topology->SetColorMapping(enableColorMap);
spectrogram->SetHeightMapping(enableHeightMap);
spectrogram->SetColorMapping(enableColorMap);
if(enableScroll)
topology->StepForward(3);
spectrogram->Update();
if(orthogonal)
camera.SetOrthogonal(-width / 2.0f * data.aspectRatio, width / 2.0f * data.aspectRatio, -width / 2.0, width / 2.0f, -1.0f, 100.0f);
@ -218,7 +188,7 @@ void Application::Launch()
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera.Draw(*topology);
camera.Draw(*spectrogram);
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
@ -256,7 +226,7 @@ void Application::Launch()
ImGui::Checkbox("Scrolling", &enableScroll);
ImGui::ListBox("Colormap", &colormap, colormapNames.data(), colormapNames.size());
topology->SetColormap(colormaps[colormap]);
spectrogram->SetColormap(colormaps[colormap]);
}
ImGui::End();

View file

@ -4,8 +4,7 @@
#include <chrono>
#include "Util.hpp"
#include "OrbitingCamera.hpp"
#include "ScrollingPlot.hpp"
#include "AudioFile.hpp"
#include "Spectrogram.hpp"
struct GLFWwindow;
@ -59,6 +58,5 @@ private:
bool enableScroll = false;
int colormap = 0;
ScrollingPlot* topology;
AudioFile* file;
Spectrogram* spectrogram;
};

View file

@ -6,6 +6,7 @@ add_executable(visualizer
"Colormaps.cpp"
"ScrollingPlot.cpp"
"AudioFile.cpp"
"Spectrogram.cpp"
)
target_sources(visualizer PUBLIC

114
src/Spectrogram.cpp Normal file
View file

@ -0,0 +1,114 @@
#include "Spectrogram.hpp"
#include <complex>
#define POW_OF_TWO(x) ((x) && !((x) & ((x) - 1)))
std::vector<std::complex<float>> radix2dit(
const std::vector<float> samples,
size_t offset,
size_t N,
size_t s
);
Spectrogram::Spectrogram(
lol::ObjectManager& manager,
const glm::vec2& size,
const glm::uvec2& subdivision,
const AudioFile& audio
) :
Topology(manager, size, subdivision), audio(audio)
{
this->audio.Normalize();
range = glm::vec2(0.0f, 0.0005f);
MakeTexture();
}
void Spectrogram::Update()
{
// Load samples
unsigned int sampleNumber = audio.GetAudioSpec().freq / 60;
std::vector<float> samples(audio.begin() + currentStrip * sampleNumber, audio.begin() + (currentStrip + 1) * sampleNumber);
size_t N = samples.size();
// Zeropad the signal
while(!POW_OF_TWO(N))
{
samples.push_back(0.0f);
N++;
}
N = samples.size() << 3;
samples.insert(samples.end(), N - samples.size(), 0.0f);
// Perform Fourier transformation on the next samples
std::vector<std::complex<float>> spectrum = radix2dit(samples, 0, N, 1);
float freqRes = (float)audio.GetAudioSpec().freq / (float)N;
float nyquistLimit = (float)audio.GetAudioSpec().freq / 2.0f;
std::vector<std::pair<float, float>> output;
float freq = 50.0f;
float maxFreq = nyquistLimit;
for (int k = freq / freqRes; freq < nyquistLimit && freq < maxFreq; k++) // ??? wtf is going on here?
{
output.push_back(std::make_pair(freq, 2.0f * std::abs(spectrum[k]) / (float)N));
freq += freqRes;
}
float* pixels = GetTopology();
glm::uvec2 dims = image.GetDimensions();
glm::vec2 arrayDomain(0.0f, N);
glm::vec2 imageDomain(0.0f, dims.y);
unsigned int imageStrip = currentStrip % dims.x;
for(unsigned int y = 0; y < dims.y; y++)
{
std::complex<float> sample = output[Map(imageDomain, arrayDomain, y)].second;
float magnitude = std::abs(sample);
pixels[y * dims.x + imageStrip] = magnitude;
}
MakeTexture();
currentStrip++;
offset += 1.0f / (float)dims.x;
}
std::vector<std::complex<float>> radix2dit(
const std::vector<float> samples,
size_t offset,
size_t N,
size_t s
)
{
std::vector<std::complex<float>> output(N);
if(N == 1)
{
output[0] = samples[offset];
}
else
{
size_t halfN = N >> 1;
std::vector<std::complex<float>> first = radix2dit(samples, offset, halfN, 2 * s);
std::vector<std::complex<float>> second = radix2dit(samples, offset + s, halfN, 2 * s);
float coeff = -M_PI / (float)halfN;
for (int k = 0; k < halfN; k++)
{
std::complex<float> p = first[k];
std::complex<float> q = std::exp(coeff * (float)k) * second[k];
output[k] = p + q;
output[halfN + k] = p - q;
}
}
return output;
}

21
src/Spectrogram.hpp Normal file
View file

@ -0,0 +1,21 @@
#pragma once
#include "Topology.hpp"
#include "AudioFile.hpp"
class Spectrogram : public Topology
{
public:
Spectrogram(
lol::ObjectManager& manager,
const glm::vec2& size,
const glm::uvec2& subdivision,
const AudioFile& audio
);
void Update();
private:
AudioFile audio;
unsigned int currentStrip = 0;
};

View file

@ -16,7 +16,7 @@ public:
void PreRender(const lol::CameraBase& camera) override;
inline void SetHeightMapping(bool enable) { heightFactor = enable ? 2.0f : 0.0f; }
inline void SetHeightMapping(bool enable) { heightFactor = enable ? 200.0f : 0.0f; }
inline void SetColorMapping(bool enable) { renderColor = enable; }
inline virtual void Scroll(bool enable) { scroll = enable; }
@ -41,7 +41,7 @@ protected:
float offset = 0.0f;
private:
float heightFactor = 2.0f;
float heightFactor = 200.0f;
bool renderColor = true;
bool scroll = false;
};