summaryrefslogtreecommitdiffhomepage
path: root/alsa.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2024-01-03 14:45:38 +0100
committerRoland Reichwein <mail@reichwein.it>2024-01-03 14:45:38 +0100
commit0e70fa4865c94bbaaa5d6f62396c13b43a3c6676 (patch)
tree63d7bae457cfaf40e2502a85098d35f3999f1977 /alsa.cpp
Initial filesHEADmaster
Diffstat (limited to 'alsa.cpp')
-rw-r--r--alsa.cpp112
1 files changed, 112 insertions, 0 deletions
diff --git a/alsa.cpp b/alsa.cpp
new file mode 100644
index 0000000..c5455b4
--- /dev/null
+++ b/alsa.cpp
@@ -0,0 +1,112 @@
+#include <libreichwein/file.h>
+
+#include <alsa/asoundlib.h>
+
+#include <cstdint>
+#include <cmath>
+#include <iostream>
+#include <limits>
+
+static const char *device = "default"; /* playback device */
+const snd_pcm_sframes_t nframes = 8*1024;
+int16_t buffer[nframes]; /* some random data */
+const double f_tone = 440.0;
+const unsigned int f_sample = 48000;
+const double pi = std::acos(-1);
+
+class Sin
+{
+
+public:
+
+double generate(double phase)
+{
+ int i;
+
+ for (i = 0; i < nframes; i++)
+ buffer[i] = std::sin(i * 2 * pi * f_tone / f_sample + phase) * std::numeric_limits<int16_t>::max();
+
+ double dummy;
+ return std::modf((i * 2 * pi * f_tone / f_sample + phase) / (2 * pi), &dummy) * 2 * pi;
+}
+
+};
+
+class M3
+{
+private:
+ std::vector<uint16_t> m_data;
+public:
+ M3()
+ {
+ std::string data_s = Reichwein::File::getFile("media/Bmw_M3_f80_StartUp.s16le");
+ m_data.resize(data_s.size() / 2);
+ memcpy(m_data.data(), data_s.data(), data_s.size());
+ }
+
+double generate(double phase)
+{
+ int i;
+ size_t j = phase;
+
+ for (i = 0; i < nframes; i++) {
+ if (j >= m_data.size())
+ j = 0;
+ buffer[i] = m_data[j];
+ j++;
+ }
+
+ return j;
+}
+
+};
+
+int main(void)
+{
+ int err;
+ unsigned int i;
+ snd_pcm_t *handle;
+ snd_pcm_sframes_t frames;
+
+ // non-blocking
+ if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
+ printf("Playback open error: %s\n", snd_strerror(err));
+ exit(EXIT_FAILURE);
+ }
+ if ((err = snd_pcm_set_params(handle,
+ SND_PCM_FORMAT_S16_LE,
+ SND_PCM_ACCESS_RW_INTERLEAVED,
+ 1,
+ f_sample,
+ 1,
+ 500000)) < 0) { /* 0.5sec */
+ printf("Playback open error: %s\n", snd_strerror(err));
+ exit(EXIT_FAILURE);
+ }
+
+ double phase = 0;
+ //Sin generator;
+ M3 generator;
+ for (i = 0; i < 40; i++) {
+ phase = generator.generate(phase);
+
+ frames = snd_pcm_writei(handle, buffer, nframes);
+ if (frames < 0) {
+ std::cout << "Recovering." << std::endl;
+ frames = snd_pcm_recover(handle, frames, 0);
+ }
+ if (frames < 0) {
+ printf("snd_pcm_writei failed: %s\n", snd_strerror(frames));
+ break;
+ }
+ if (frames > 0 && frames < nframes)
+ printf("Short write (expected %li, wrote %li)\n", nframes, frames);
+ }
+
+ /* pass the remaining samples, otherwise they're dropped in close */
+ err = snd_pcm_drain(handle);
+ if (err < 0)
+ printf("snd_pcm_drain failed: %s\n", snd_strerror(err));
+ snd_pcm_close(handle);
+ return 0;
+}