|
@@ -4,92 +4,113 @@
|
|
|
#include <cassert>
|
|
|
#include <cmath>
|
|
|
|
|
|
-struct AudioData {
|
|
|
+struct AudioData
|
|
|
+{
|
|
|
float *data;
|
|
|
};
|
|
|
|
|
|
-namespace Audio {
|
|
|
+namespace Audio
|
|
|
+{
|
|
|
|
|
|
-AudioPlayer::AudioPlayer() {
|
|
|
+ AudioPlayer::AudioPlayer()
|
|
|
+ {
|
|
|
|
|
|
- spdlog::info("Started Audio Player {} {}", m_frequency, m_sample_rate);
|
|
|
+ spdlog::info("Started Audio Player {} {}", m_frequency, m_sample_rate);
|
|
|
|
|
|
- generate_samples();
|
|
|
- config = ma_device_config_init(ma_device_type_playback);
|
|
|
- config.playback.format = ma_format_f32;
|
|
|
- config.playback.channels = 2;
|
|
|
- config.sampleRate = m_sample_rate;
|
|
|
- config.dataCallback = data_callback;
|
|
|
- AudioData ad;
|
|
|
- ad.data = m_sample.data();
|
|
|
- //ad.length = m_sample.size();
|
|
|
- // ad.frequency = m_frequency;
|
|
|
- // ad.sample_rate = m_sample_rate;
|
|
|
- config.pUserData = static_cast<float *>(m_sample.data());
|
|
|
- ma_device_init(NULL, &config, &device);
|
|
|
+ config = ma_device_config_init(ma_device_type_playback);
|
|
|
+ config.playback.format = ma_format_f32;
|
|
|
+ config.playback.channels = 2;
|
|
|
+ config.sampleRate = 0;
|
|
|
+ config.dataCallback = data_callback;
|
|
|
|
|
|
- spdlog::info("Device: {} Channels: {}, Sample Rate: {}/{}", device.playback.name, device.playback.channels, device.sampleRate, device.playback.internalSampleRate);
|
|
|
-}
|
|
|
+ m_sample = std::vector<float>(64, 440.0f);
|
|
|
+ generate_samples();
|
|
|
|
|
|
-void AudioPlayer::play() {
|
|
|
+ }
|
|
|
|
|
|
- m_is_playing = true;
|
|
|
- ma_device_start(&device);
|
|
|
-}
|
|
|
+ void AudioPlayer::play()
|
|
|
+ {
|
|
|
+
|
|
|
+ std::vector<float> synthetic_wave = std::vector<float>(10 * m_sample_rate, m_frequency);
|
|
|
+ for (int i = 0; i < synthetic_wave.size(); ++i) {
|
|
|
+ synthetic_wave[i] = next_sample() * m_amplitude;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ config.pUserData = (void *)(synthetic_wave.data());
|
|
|
+
|
|
|
+ spdlog::info("synthetic wave is: {} {}", synthetic_wave.size(), synthetic_wave.data()[10]);
|
|
|
+
|
|
|
+
|
|
|
+ if (ma_device_init(NULL, &config, &device) != MA_SUCCESS) {
|
|
|
+ spdlog::error("could not intialize device");
|
|
|
+ exit(EXIT_FAILURE);
|
|
|
+ }
|
|
|
+ spdlog::info("Device: {} Channels: {}, Sample Rate: {}/{}", device.playback.name, device.playback.channels, device.sampleRate, device.playback.internalSampleRate);
|
|
|
+ s_frame_pos = 10;
|
|
|
+ m_is_playing = true;
|
|
|
+
|
|
|
+ spdlog::info("Playing!");
|
|
|
+ ma_device_start(&device);
|
|
|
+ }
|
|
|
|
|
|
-void AudioPlayer::pause() {
|
|
|
- m_is_playing = false;
|
|
|
- ma_device_uninit(&device);
|
|
|
-}
|
|
|
+ void AudioPlayer::pause()
|
|
|
+ {
|
|
|
+ m_is_playing = false;
|
|
|
+ ma_device_uninit(&device);
|
|
|
+ }
|
|
|
|
|
|
-bool AudioPlayer::is_playing() { return m_is_playing; }
|
|
|
+ bool AudioPlayer::is_playing() { return m_is_playing; }
|
|
|
|
|
|
-void AudioPlayer::generate_samples() {
|
|
|
- float tick = m_frequency / m_sample_rate;
|
|
|
+ void AudioPlayer::generate_samples()
|
|
|
+ {
|
|
|
+ const size_t length = 64;
|
|
|
+
|
|
|
+ for (int i = 0; i < length; ++i ) {
|
|
|
+ m_sample[i] = sinf(2 * PI_F * i / length);
|
|
|
+ //spdlog::info("Added: [{}] = {} ", i, m_sample[i]);
|
|
|
+ }
|
|
|
|
|
|
- for (float i = 0.f; i < 2 * PI_F; i += tick) {
|
|
|
- m_sample.push_back(next_sample());
|
|
|
+ spdlog::info("Have {} samples", m_sample.size());
|
|
|
}
|
|
|
|
|
|
- spdlog::info("Have {} samples", m_sample.size());
|
|
|
-}
|
|
|
+ float AudioPlayer::next_sample()
|
|
|
+ {
|
|
|
+ auto idx = get_next_frame_pos(m_frequency, m_sample_rate);
|
|
|
+ return m_sample[idx];
|
|
|
|
|
|
-float AudioPlayer::next_sample() {
|
|
|
- m_phase += m_frequency / m_sample_rate;
|
|
|
- if (m_phase >= 1.0) {
|
|
|
- m_phase -= floorf(m_phase);
|
|
|
}
|
|
|
- return sinf(2 * PI_F * m_phase) * m_amplitude;
|
|
|
-}
|
|
|
-
|
|
|
-int AudioPlayer::get_next_frame_pos(float frequency, float sample_rate) {
|
|
|
- float tick = frequency / sample_rate;
|
|
|
- float max = PI_F / tick;
|
|
|
- s_frame_pos++;
|
|
|
- if (s_frame_pos >= max) {
|
|
|
- s_frame_pos = 0;
|
|
|
+
|
|
|
+ int AudioPlayer::get_next_frame_pos(float frequency, float sample_rate)
|
|
|
+ {
|
|
|
+ float increment = 64 * frequency / sample_rate;
|
|
|
+ int v = (s_frame_pos + increment);
|
|
|
+ int idx = (int) (floorf(v % 64));
|
|
|
+ s_frame_pos++;
|
|
|
+
|
|
|
+ return idx;
|
|
|
}
|
|
|
- return s_frame_pos;
|
|
|
-}
|
|
|
-
|
|
|
-void AudioPlayer::data_callback(ma_device *device, void *output,
|
|
|
- const void *input, ma_uint32 frame_count) {
|
|
|
- float *output_f32 = (float *)output;
|
|
|
- float *ad = (float *)(device->pUserData);
|
|
|
-
|
|
|
- int j = get_next_frame_pos(440.0f, 44100.f);
|
|
|
- // spdlog::info("Got frame pos: {} with length: {} and value: {}", j, 0, (float)ad[j]);
|
|
|
- //if (ad->length == 0)
|
|
|
- // return;
|
|
|
-
|
|
|
- for (uint32_t curFrame = 0; curFrame < frame_count; curFrame+=2) {
|
|
|
- //assert(j < ad->length);
|
|
|
- // spdlog::info("Got value {} -> {}", j, ad->data[j]);
|
|
|
- float value = (float)ad[j];
|
|
|
- output_f32[curFrame * 2 + 0] = value;
|
|
|
- output_f32[curFrame * 2 + 1] = value;
|
|
|
- //if (++j >= ad->length)
|
|
|
- // j = 0;
|
|
|
+
|
|
|
+ void AudioPlayer::data_callback(ma_device *device, void *output,
|
|
|
+ const void *input, ma_uint32 frame_count)
|
|
|
+ {
|
|
|
+ float *output_f32 = (float *)output;
|
|
|
+ float *ad = (float *)(device->pUserData);
|
|
|
+
|
|
|
+ // spdlog::info("Got frame pos: {} with length: {} and value: {}", j, 0, (float)ad[j]);
|
|
|
+ // if (ad->length == 0)
|
|
|
+ // return;
|
|
|
+
|
|
|
+ for (uint32_t curFrame = 0; curFrame < frame_count; curFrame++)
|
|
|
+ {
|
|
|
+ int j = get_next_frame_pos(440.0f, 48000.f);
|
|
|
+ // assert(j < ad->length);
|
|
|
+ //spdlog::info("Got value {} -> {}", j, ad[j]);
|
|
|
+ float value = (float)ad[j];
|
|
|
+ output_f32[curFrame * 2 + 0] = value;
|
|
|
+ output_f32[curFrame * 2 + 1] = value;
|
|
|
+ // if (++j >= ad->length)
|
|
|
+ // j = 0;
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
} // namespace Audio
|