actually use pulseaudio (works around several ALSA bugs/problems)
This commit is contained in:
parent
020469d1a2
commit
1530372180
|
@ -0,0 +1,4 @@
|
||||||
|
* set pulseaudio to 192kHz sample rate:
|
||||||
|
hardware.pulseaudio.daemon.config = { "default-sample-rate" = 192000; };
|
||||||
|
* check that sound card is operating at 192kHz:
|
||||||
|
cat /proc/asound/card0/pcm0c/sub0/hw_params
|
23
main.cpp
23
main.cpp
|
@ -6,6 +6,7 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
@ -27,7 +28,11 @@ static int waterfall_width = 1600;
|
||||||
static int waterfall_height = 700;
|
static int waterfall_height = 700;
|
||||||
static unsigned int waterfall_data[1600*700];
|
static unsigned int waterfall_data[1600*700];
|
||||||
|
|
||||||
|
static std::atomic<int> fps;
|
||||||
|
|
||||||
static void dsp_thread() {
|
static void dsp_thread() {
|
||||||
|
using namespace std::literals::chrono_literals;
|
||||||
|
|
||||||
size_t len = 6400;
|
size_t len = 6400;
|
||||||
std::vector<short int> frames(len);
|
std::vector<short int> frames(len);
|
||||||
|
|
||||||
|
@ -43,6 +48,8 @@ static void dsp_thread() {
|
||||||
for(size_t i=0; i<shape.size(); ++i)
|
for(size_t i=0; i<shape.size(); ++i)
|
||||||
axes.push_back(i);
|
axes.push_back(i);
|
||||||
std::vector<std::complex<float>> frames_ft(len);
|
std::vector<std::complex<float>> frames_ft(len);
|
||||||
|
int iterations = 0;
|
||||||
|
auto last_second = std::chrono::steady_clock::now();
|
||||||
while(!terminate_dsp) {
|
while(!terminate_dsp) {
|
||||||
int read_count = snd_pcm_readi(pcm, frames.data(), len);
|
int read_count = snd_pcm_readi(pcm, frames.data(), len);
|
||||||
if(read_count < 0) {
|
if(read_count < 0) {
|
||||||
|
@ -59,18 +66,17 @@ static void dsp_thread() {
|
||||||
waterfall_data[i] = 0xff000000 | 0x010101*std::min(int(abs(frames_ft[i*len/(4*waterfall_width)])/10000.), 255);
|
waterfall_data[i] = 0xff000000 | 0x010101*std::min(int(abs(frames_ft[i*len/(4*waterfall_width)])/10000.), 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
iterations++;
|
||||||
|
if((std::chrono::steady_clock::now() - last_second) >= 1s) {
|
||||||
|
fps = iterations;
|
||||||
|
iterations = 0;
|
||||||
|
last_second += 1s;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if(argc != 2) {
|
|
||||||
std::cerr << "please specify ALSA device on the command line" << std::endl;
|
|
||||||
std::cerr << "use arecord -L to list, and select raw device without pulseaudio" << std::endl;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
char* alsa_device = argv[1];
|
|
||||||
|
|
||||||
if (!glfwInit()) {
|
if (!glfwInit()) {
|
||||||
std::cerr << "failed to initialize GLFW" << std::endl;
|
std::cerr << "failed to initialize GLFW" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -113,7 +119,7 @@ int main(int argc, char* argv[])
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
if ((err = snd_pcm_open(&pcm, alsa_device, SND_PCM_STREAM_CAPTURE, 0)) < 0) {
|
if ((err = snd_pcm_open(&pcm, "default", SND_PCM_STREAM_CAPTURE, 0)) < 0) {
|
||||||
std::cerr << "cannot open ALSA device: " << snd_strerror(err) << std::endl;
|
std::cerr << "cannot open ALSA device: " << snd_strerror(err) << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -200,6 +206,7 @@ int main(int argc, char* argv[])
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if(ImGui::Button("Exit"))
|
if(ImGui::Button("Exit"))
|
||||||
exit = true;
|
exit = true;
|
||||||
|
ImGui::Text("FPS: %d", (int)fps);
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Image((void*)(intptr_t)waterfall, ImVec2(waterfall_width, waterfall_height));
|
ImGui::Image((void*)(intptr_t)waterfall, ImVec2(waterfall_width, waterfall_height));
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
|
|
Loading…
Reference in New Issue