Kaynağa Gözat

miniaudio: working, need to fix waveform generator

Douglas A 2 yıl önce
ebeveyn
işleme
59a7749c9d

+ 2 - 0
.gitignore

@@ -1 +1,3 @@
 build/
+.cache
+.vscode

+ 0 - 6
.vscode/settings.json

@@ -1,6 +0,0 @@
-{
-    "files.associations": {
-        "numbers": "cpp",
-        "vector": "cpp"
-    }
-}

+ 3 - 6
CMakeLists.txt

@@ -1,12 +1,9 @@
 cmake_minimum_required(VERSION 3.20.0)
 project(audio-player VERSION 0.1.0 LANGUAGES CXX)
 
-add_subdirectory(spdlog)
-add_subdirectory(src)
+set(CXX_STANDARD, 17)
 
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/spdlog/include)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
+add_subdirectory(src)
+add_subdirectory(spdlog)
 
-add_executable(audio-player main.cpp)
 
-target_link_libraries(audio-player audio-player-lib)

+ 47 - 0
compile_commands.json

@@ -0,0 +1,47 @@
+[
+{
+  "directory": "/home/cmte/r/MiniAudio/build/src",
+  "command": "/usr/bin/c++ -DSPDLOG_COMPILED_LIB -I/home/cmte/r/MiniAudio/spdlog/include -g -o CMakeFiles/audio-player.dir/main.cpp.o -c /home/cmte/r/MiniAudio/src/main.cpp",
+  "file": "/home/cmte/r/MiniAudio/src/main.cpp"
+},
+{
+  "directory": "/home/cmte/r/MiniAudio/build/src",
+  "command": "/usr/bin/c++ -DSPDLOG_COMPILED_LIB -I/home/cmte/r/MiniAudio/spdlog/include -g -o CMakeFiles/audio-player.dir/AudioPlayer.cpp.o -c /home/cmte/r/MiniAudio/src/AudioPlayer.cpp",
+  "file": "/home/cmte/r/MiniAudio/src/AudioPlayer.cpp"
+},
+{
+  "directory": "/home/cmte/r/MiniAudio/build/spdlog",
+  "command": "/usr/bin/c++ -DSPDLOG_COMPILED_LIB -I/home/cmte/r/MiniAudio/spdlog/include -g -std=c++11 -o CMakeFiles/spdlog.dir/src/spdlog.cpp.o -c /home/cmte/r/MiniAudio/spdlog/src/spdlog.cpp",
+  "file": "/home/cmte/r/MiniAudio/spdlog/src/spdlog.cpp"
+},
+{
+  "directory": "/home/cmte/r/MiniAudio/build/spdlog",
+  "command": "/usr/bin/c++ -DSPDLOG_COMPILED_LIB -I/home/cmte/r/MiniAudio/spdlog/include -g -std=c++11 -o CMakeFiles/spdlog.dir/src/stdout_sinks.cpp.o -c /home/cmte/r/MiniAudio/spdlog/src/stdout_sinks.cpp",
+  "file": "/home/cmte/r/MiniAudio/spdlog/src/stdout_sinks.cpp"
+},
+{
+  "directory": "/home/cmte/r/MiniAudio/build/spdlog",
+  "command": "/usr/bin/c++ -DSPDLOG_COMPILED_LIB -I/home/cmte/r/MiniAudio/spdlog/include -g -std=c++11 -o CMakeFiles/spdlog.dir/src/color_sinks.cpp.o -c /home/cmte/r/MiniAudio/spdlog/src/color_sinks.cpp",
+  "file": "/home/cmte/r/MiniAudio/spdlog/src/color_sinks.cpp"
+},
+{
+  "directory": "/home/cmte/r/MiniAudio/build/spdlog",
+  "command": "/usr/bin/c++ -DSPDLOG_COMPILED_LIB -I/home/cmte/r/MiniAudio/spdlog/include -g -std=c++11 -o CMakeFiles/spdlog.dir/src/file_sinks.cpp.o -c /home/cmte/r/MiniAudio/spdlog/src/file_sinks.cpp",
+  "file": "/home/cmte/r/MiniAudio/spdlog/src/file_sinks.cpp"
+},
+{
+  "directory": "/home/cmte/r/MiniAudio/build/spdlog",
+  "command": "/usr/bin/c++ -DSPDLOG_COMPILED_LIB -I/home/cmte/r/MiniAudio/spdlog/include -g -std=c++11 -o CMakeFiles/spdlog.dir/src/async.cpp.o -c /home/cmte/r/MiniAudio/spdlog/src/async.cpp",
+  "file": "/home/cmte/r/MiniAudio/spdlog/src/async.cpp"
+},
+{
+  "directory": "/home/cmte/r/MiniAudio/build/spdlog",
+  "command": "/usr/bin/c++ -DSPDLOG_COMPILED_LIB -I/home/cmte/r/MiniAudio/spdlog/include -g -std=c++11 -o CMakeFiles/spdlog.dir/src/cfg.cpp.o -c /home/cmte/r/MiniAudio/spdlog/src/cfg.cpp",
+  "file": "/home/cmte/r/MiniAudio/spdlog/src/cfg.cpp"
+},
+{
+  "directory": "/home/cmte/r/MiniAudio/build/spdlog",
+  "command": "/usr/bin/c++ -DSPDLOG_COMPILED_LIB -I/home/cmte/r/MiniAudio/spdlog/include -g -std=c++11 -o CMakeFiles/spdlog.dir/src/bundled_fmtlib_format.cpp.o -c /home/cmte/r/MiniAudio/spdlog/src/bundled_fmtlib_format.cpp",
+  "file": "/home/cmte/r/MiniAudio/spdlog/src/bundled_fmtlib_format.cpp"
+}
+]

+ 0 - 27
main.cpp

@@ -1,27 +0,0 @@
-#include <spdlog/spdlog.h>
-#include <memory>
-
-
-#include "LogAudio.h"
-#include "MiniAudio.h"
-
-
-
-int main () {
-
-#ifndef DEBUG
-    std::unique_ptr<Audio::AudioInterface> m = std::make_unique<Audio::MiniAudio>(Audio::MiniAudio());
-#else
-    std::unique_ptr<Audio::AudioInterface> m = std::make_unique<Audio::LogAudio>(Audio::LogAudio());
-#endif
-    m->play();
-    
-    if (m->is_playing()) {
-        spdlog::info("Player is on play mode");
-    } else {
-        spdlog::info("Player is on pause mode");
-    }
-
-    m->pause();
-    
-}

+ 1 - 1
src/AudioInterface.h

@@ -10,4 +10,4 @@ namespace Audio
         virtual void pause() = 0;
         virtual bool is_playing() = 0;
     };
-}
+}

+ 95 - 0
src/AudioPlayer.cpp

@@ -0,0 +1,95 @@
+#include "AudioPlayer.h"
+#include "spdlog/spdlog.h"
+
+#include <cassert>
+#include <cmath>
+
+struct AudioData {
+  float *data;
+};
+
+namespace Audio {
+
+AudioPlayer::AudioPlayer() {
+
+  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);
+
+  spdlog::info("Device: {} Channels: {}, Sample Rate: {}/{}", device.playback.name, device.playback.channels, device.sampleRate, device.playback.internalSampleRate);
+}
+
+void AudioPlayer::play() {
+
+  m_is_playing = true;
+  ma_device_start(&device);
+}
+
+void AudioPlayer::pause() {
+  m_is_playing = false;
+  ma_device_uninit(&device);
+}
+
+bool AudioPlayer::is_playing() { return m_is_playing; }
+
+void AudioPlayer::generate_samples() {
+  float tick = m_frequency / m_sample_rate;
+
+  for (float i = 0.f; i < 2 * PI_F; i += tick) {
+    m_sample.push_back(next_sample());
+  }
+
+  spdlog::info("Have {} samples", m_sample.size());
+}
+
+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;
+  }
+  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;
+  }
+}
+} // namespace Audio

+ 39 - 0
src/AudioPlayer.h

@@ -0,0 +1,39 @@
+#pragma once
+
+#include "AudioInterface.h"
+#include "miniaudio.h"
+#include <vector>
+
+namespace Audio {
+
+const float PI_F = 3.14159265358979f;
+
+class AudioPlayer : public AudioInterface {
+
+private:
+  inline static int s_frame_pos;
+
+  static void data_callback(ma_device *device, void *output, const void *input,
+                            ma_uint32 frame_count);
+  static int get_next_frame_pos(float frequency, float sample_rate);
+  std::vector<float> m_sample;
+  bool m_is_playing = false;
+
+  float const m_frequency = 440.0f;
+  float const m_sample_rate = 44100.00f;
+  float const m_amplitude = 1.0f;
+  float m_phase = 0.0f;
+
+  ma_device_config config;
+  ma_device device;
+
+  void generate_samples();
+  float next_sample();
+
+public:
+  AudioPlayer();
+  void play() override;
+  void pause() override;
+  bool is_playing() override;
+};
+} // namespace Audio

+ 12 - 4
src/CMakeLists.txt

@@ -1,7 +1,15 @@
 cmake_minimum_required(VERSION 3.20)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../spdlog/include)
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
 
-add_library(audio-player-lib LogAudio.cpp MiniAudio.cpp)
+project(audio-player VERSION 0.0.1 LANGUAGES CXX)
 
-target_link_libraries(audio-player-lib spdlog)
+add_executable(audio-player 
+               main.cpp 
+               AudioPlayer.cpp
+               )
+
+
+
+       target_link_libraries(audio-player
+                             spdlog)
+
+target_include_directories(audio-player PUBLIC ${CMAKE_SOURCE_DIR}/spdlog/include)

+ 1 - 1
src/LogAudio.h

@@ -13,4 +13,4 @@ namespace Audio
         void pause() override;
         bool is_playing() override;
     };
-}
+}

+ 0 - 38
src/MiniAudio.cpp

@@ -1,38 +0,0 @@
-#include "MiniAudio.h"
-
-namespace Audio {
-
-    MiniAudio::MiniAudio() 
-    {
-
-        m_config = ma_device_config_init(ma_device_type_playback);
-        m_config.playback.format = ma_format_f32;
-        generate_samples();
-    }
-    
-    void MiniAudio::play() 
-    {
-
-    }
-    
-    void MiniAudio::pause()
-    {
-
-    }
-    
-    bool MiniAudio::is_playing() 
-    {
-        return false;
-    }
-
-    void MiniAudio::generate_samples() 
-    {
-        float tick = 1 / m_sample_rate;
-
-        for (float i = 0; i < 2 * PI_F; i += tick) 
-        {
-            float value = m_amplitude * sinf(2 * PI_F * m_frequency * i) / m_sample_rate;
-            m_sample.push_back(value);
-        }
-    }
-}

+ 0 - 40
src/MiniAudio.h

@@ -1,40 +0,0 @@
-#pragma once
-
-
-#include <vector>
-
-extern "C" {
-    #define MINIAUDIO_IMPLEMENTATION
-    #include <miniaudio.h>
-}
-
-#include "AudioInterface.h"
-
-namespace Audio
-{
-
-    const float  PI_F=3.14159265358979f;
-
-    class MiniAudio : public AudioInterface
-    {
-
-    private:
-        std::vector<float> m_sample;
-        bool m_is_playing = false;
-        void generate_samples();
-        float const m_frequency     = 440.0f;
-        float const m_sample_rate   = 48000.00f;
-        float const m_amplitude     = 0.8f;
-
-        ma_device_config m_config;
-        ma_device *m_device;
-
-
-    public:
-
-        MiniAudio();
-        void play() override;
-        void pause() override;
-        bool is_playing() override;
-    };
-}

+ 35 - 0
src/main.cpp

@@ -0,0 +1,35 @@
+#include <spdlog/spdlog.h>
+#include <memory>
+#include <thread>
+#include <chrono>
+#define MINIAUDIO_IMPLEMENTATION
+extern "C" {
+        #include "miniaudio.h"
+}
+
+#include "LogAudio.h"
+#include "AudioPlayer.h"
+
+
+
+int main () {
+
+    using namespace std::chrono_literals;
+    Audio::AudioPlayer *m = new Audio::AudioPlayer();
+    m->play();
+    
+    if (m->is_playing()) {
+        spdlog::info("Player is on play mode");
+    } else {
+        spdlog::info("Player is on pause mode");
+    }
+
+    //bodge: stop the program execution.
+    getchar();
+
+
+    m->pause();
+
+    delete m;
+    
+}

+ 1 - 1
include/miniaudio.h → src/miniaudio.h

@@ -91286,4 +91286,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
-*/
+*/