commit b0a7cd9fae74af959da2647c723d55a22087095b Author: Keenan Tims Date: Mon Jan 6 14:04:34 2020 -0800 Initial commit - basic sine generator diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..3ea48b5 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 2.6) +project(sinesynth) + +set(CMAKE_CXX_STANDARD 11) + +include_directories(include) + +find_package(PulseAudio) +if(PULSEAUDIO_FOUND) + include_directories(${PULSEAUDIO_INCLUDE_DIR}) +endif() + +set(SINESYNTH_LIBS ${PULSEAUDIO_LIBRARY} pulse-simple) + +file(GLOB SOURCES "src/*.cpp") + +add_executable(sinesynth ${SOURCES}) +target_link_libraries(sinesynth LINK_PUBLIC ${SINESYNTH_LIBS}) \ No newline at end of file diff --git a/include/SineSynth.h b/include/SineSynth.h new file mode 100644 index 0000000..46314cb --- /dev/null +++ b/include/SineSynth.h @@ -0,0 +1,49 @@ +#pragma once + +#include +#include +#include +#include + +using std::vector; +using std::iterator_traits; + +using std::sin; +using std::cos; + +class Generator +{ +public: + virtual void getSamples(const uint16_t nSamples, float *buf) = 0; + virtual ~Generator(); + + // disallow copy of virtual interface + Generator(Generator const &) = delete; + Generator &operator=(Generator const &) = delete; + +protected: + Generator(uint32_t _sampleRate, float _frequency, float _amplitude); + uint32_t sampleRate; + float frequency; + float amplitude; + +private: +}; + +class SineGenerator : public Generator +{ +public: + SineGenerator(uint32_t _sampleRate, float _frequency, float _amplitude); + void getSamples(uint16_t nSamples, float *buf) final; + virtual ~SineGenerator(); + +private: + uint32_t tick; + float phaseIncr; +}; + +class SineSynth +{ +private: + vector generators; +}; \ No newline at end of file diff --git a/src/SineSynth.cpp b/src/SineSynth.cpp new file mode 100644 index 0000000..59759fd --- /dev/null +++ b/src/SineSynth.cpp @@ -0,0 +1,28 @@ +#include "SineSynth.h" + +#include + +Generator::Generator(uint32_t _sampleRate, float _frequency, float _amplitude) : sampleRate(_sampleRate), frequency(_frequency), amplitude(_amplitude) +{ +} + +Generator::~Generator() +{ +} + +SineGenerator::SineGenerator(uint32_t _sampleRate, float _frequency, float _amplitude = 1) : Generator(_sampleRate, _frequency, _amplitude), tick(0) { + phaseIncr = 2 * M_PI * frequency / sampleRate; + + std::cout << "Constructed SineGenerator with freq " << frequency << " phaseIncr " << phaseIncr << std::endl; +} + +SineGenerator::~SineGenerator() { + +} + +void SineGenerator::getSamples(uint16_t nSamples, float *buf) { + for (;nSamples>0;nSamples--) { + std::cout << "Generating tick " << tick << std::endl; + *buf++ = cos(phaseIncr * tick++) * amplitude; + } +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..85fb4bf --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,23 @@ +#include +#include + +#include "SineSynth.h" + +int main(int argc, char *argv[]) { + SineGenerator sg(44100, 440.0f, 0.1); + static const pa_sample_spec ss = { + .format = PA_SAMPLE_FLOAT32, + .rate = 44100, + .channels = 1 + }; + + pa_simple *s = NULL; + int error; + s = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error); + + float buf[1024]; + for (;;) { + sg.getSamples(1024, buf); + pa_simple_write(s, buf, sizeof(buf), &error); + } +} \ No newline at end of file