summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--CMakeLists.txt21
-rw-r--r--examples/test.c134
-rw-r--r--mmband/adsr.c9
-rw-r--r--mmband/api/adsr.h2
-rw-r--r--mmband/api/instrument.h2
-rw-r--r--mmband/audio_player.c4
-rw-r--r--mmband/instrument.c13
-rw-r--r--mmband/waves/none.c2
-rw-r--r--mmband/waves/waveform.h2
10 files changed, 170 insertions, 22 deletions
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index f84692f..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "vendor/portaudio"]
- path = vendor/portaudio
- url = https://github.com/PortAudio/portaudio
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b476823..c564c75 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,8 +4,13 @@ project(mmband VERSION 0.1)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_library(${PROJECT_NAME} SHARED
- ${PROJECT_NAME}/audio_player.c
${PROJECT_NAME}/instrument.c
+ ${PROJECT_NAME}/adsr.c
+ ${PROJECT_NAME}/waves/none.c
+ ${PROJECT_NAME}/waves/sine.c
+ ${PROJECT_NAME}/waves/square.c
+ ${PROJECT_NAME}/waves/saw.c
+ ${PROJECT_NAME}/waves/triangle.c
)
target_include_directories(${PROJECT_NAME} PUBLIC .)
@@ -16,6 +21,18 @@ set_target_properties(${PROECT_NAME} PROPERTIES
COMPILE_WARNING_AS_ERROR ON
)
+add_executable(examples
+ examples/test.c
+)
+
+target_include_directories(examples PUBLIC .)
+set_target_properties(examples PROPERTIES
+ C_STANDARD 99
+ C_STANDARD_REQUIRED ON
+ C_EXTENSIONS OFF
+ COMPILE_WARNING_AS_ERROR ON
+)
+
add_subdirectory(vendor/portaudio)
-target_link_libraries(${PROJECT_NAME} portaudio)
+target_link_libraries(examples ${PROJECT_NAME} portaudio)
diff --git a/examples/test.c b/examples/test.c
new file mode 100644
index 0000000..05c5114
--- /dev/null
+++ b/examples/test.c
@@ -0,0 +1,134 @@
+#include "mmband/api/adsr.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <portaudio.h>
+#include <mmband/api/instrument.h>
+
+#define SAMPLE_RATE 44100
+#define FRAMES_PER_BUFFER 512
+
+// TODO: make adsr depend on sample rate
+
+int main (void) {
+ PaStream *stream;
+ PaError err = Pa_Initialize();
+ if (err != paNoError) {
+ printf("PortAudio error: %s\n", Pa_GetErrorText(err));
+ return 1;
+ }
+
+ PaStreamParameters output_params;
+ output_params.device = Pa_GetDefaultOutputDevice();
+ output_params.channelCount = 2;
+ output_params.sampleFormat = paFloat32;
+ output_params.suggestedLatency = Pa_GetDeviceInfo(output_params.device)->defaultHighInputLatency;
+ output_params.hostApiSpecificStreamInfo = NULL;
+
+ printf("Opening stream.\n");
+ err = Pa_OpenStream(
+ &stream,
+ NULL,
+ &output_params,
+ SAMPLE_RATE,
+ FRAMES_PER_BUFFER,
+ paClipOff,
+ NULL,
+ NULL
+ );
+ if (err != paNoError) {
+ printf("PortAudio error: %s\n", Pa_GetErrorText(err));
+ return 1;
+ }
+
+ instrument_ref instrument = ins_new();
+
+ ins_set_carrier(instrument, OSC_SINE);
+ ins_set_modulator(instrument, OSC_SINE);
+ ins_set_carrier_amplitude(instrument, 0.25);
+ ins_set_modulator_amplitude(instrument, 0.25);
+ ins_set_frequency_mult(instrument, 3.0);
+
+ adsr_ref adsr = adsr_new();
+
+ adsr_set_attack(adsr, 0.2);
+ adsr_set_decay(adsr, 0.2);
+ adsr_set_sustain(adsr, 0.85);
+ adsr_set_release(adsr, 0.5);
+
+ int switch_frames = (60.0 / 120.0) * SAMPLE_RATE;
+ int iteration = 0;
+ int state = 0;
+
+ printf("Starting stream.\n");
+ err = Pa_StartStream(stream);
+ if (err != paNoError) {
+ printf("PortAudio error: %s\n", Pa_GetErrorText(err));
+ return 1;
+ }
+
+ ins_set_frequency(instrument, 246.9);
+ for (int i = 0; i < (60 * SAMPLE_RATE) / FRAMES_PER_BUFFER; ++i) {
+ float buffer[FRAMES_PER_BUFFER][2];
+ for (int j = 0; j < FRAMES_PER_BUFFER; j++) {
+ iteration++;
+
+ if (iteration >= switch_frames) {
+ switch (state) {
+ case 0:
+ ins_set_frequency(instrument, 329.6);
+ //adsr_reset(adsr);
+ state++;
+ break;
+ case 1:
+ ins_set_frequency(instrument, 370.0);
+ //adsr_reset(adsr);
+ state++;
+ break;
+ case 2:
+ ins_set_frequency(instrument, 440.0);
+ //adsr_reset(adsr);
+ state++;
+ break;
+ case 3:
+ ins_set_frequency(instrument, 370.0);
+ //adsr_reset(adsr);
+ state++;
+ break;
+ case 4:
+ ins_set_frequency(instrument, 329.6);
+ //adsr_reset(adsr);
+ state++;
+ break;
+ default:
+ ins_set_frequency(instrument, 246.9);
+ //adsr_reset(adsr);
+ state = 0;
+ break;
+ }
+
+ iteration = 0;
+ }
+
+ //float env = adsr_tick(adsr, SAMPLE_RATE);
+ float ins = ins_tick(instrument, SAMPLE_RATE);
+ buffer[j][0] = ins;// * env;
+ buffer[j][1] = ins;// * env;
+ }
+
+ err = Pa_WriteStream(stream, buffer, FRAMES_PER_BUFFER);
+ if (err != paNoError) {
+ printf("PortAudio error: %s\n", Pa_GetErrorText(err));
+ return 1;
+ }
+ }
+
+ Pa_StopStream(stream);
+ Pa_CloseStream(stream);
+
+ adsr_free(adsr);
+ ins_free(instrument);
+
+ Pa_Terminate();
+ return 0;
+}
diff --git a/mmband/adsr.c b/mmband/adsr.c
index b2a22e6..b27d1fb 100644
--- a/mmband/adsr.c
+++ b/mmband/adsr.c
@@ -1,6 +1,7 @@
#include <math.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <stdio.h>
#include <mmband/api/adsr.h>
@@ -75,10 +76,10 @@ void adsr_gate (adsr_ref adsr) {
}
}
-float adsr_tick (adsr_ref adsr) {
+float adsr_tick (adsr_ref adsr, int sample_rate) {
switch (adsr->state) {
case ADSR_ATTACK:
- adsr->out = adsr->attack_base + adsr->out * adsr->attack_curve;
+ adsr->out = adsr->attack_base + adsr->out * (adsr->attack_curve / sample_rate);
if (adsr->out >= 1.0) {
adsr->out = 1.0;
@@ -87,7 +88,7 @@ float adsr_tick (adsr_ref adsr) {
break;
case ADSR_DECAY:
- adsr->out = adsr->decay_base + adsr->out * adsr->decay_curve;
+ adsr->out = adsr->decay_base + adsr->out * (adsr->decay_curve / sample_rate);
if (adsr->out <= adsr->sustain) {
adsr->out = adsr->sustain;
@@ -96,7 +97,7 @@ float adsr_tick (adsr_ref adsr) {
break;
case ADSR_RELEASE:
- adsr->out = adsr->release_base + adsr->out * adsr->release_curve;
+ adsr->out = adsr->release_base + adsr->out * (adsr->release_curve / sample_rate);
if (adsr->out <= 0.0) {
adsr->out = 0.0;
diff --git a/mmband/api/adsr.h b/mmband/api/adsr.h
index 62b58d2..cc2dee6 100644
--- a/mmband/api/adsr.h
+++ b/mmband/api/adsr.h
@@ -10,7 +10,7 @@ MMAPI void adsr_free (adsr_ref adsr);
MMAPI void adsr_reset (adsr_ref adsr);
MMAPI void adsr_gate (adsr_ref adsr);
-MMAPI float adsr_tick (adsr_ref adsr);
+MMAPI float adsr_tick (adsr_ref adsr, int sample_rate);
MMAPI void adsr_set_attack (adsr_ref adsr, float attack_rate);
MMAPI void adsr_set_decay (adsr_ref adsr, float decay_rate);
diff --git a/mmband/api/instrument.h b/mmband/api/instrument.h
index bad0d48..3190d10 100644
--- a/mmband/api/instrument.h
+++ b/mmband/api/instrument.h
@@ -39,7 +39,7 @@ MMAPI void ins_set_modulator (instrument_ref instrument, enum osc
MMAPI void ins_set_carrier_amplitude (instrument_ref instrument, float amplitude);
MMAPI void ins_set_carrier_frequency (instrument_ref instrument, float amplitude);
MMAPI void ins_set_modulator_amplitude (instrument_ref instrument, float amplitude);
-MMAPI void ins_set_frequency_ratio (instrument_ref instrument, float ratio);
+MMAPI void ins_set_frequency_mult (instrument_ref instrument, float mult);
MMAPI void ins_set_frequency (instrument_ref instrument, float frequency);
MMAPI float ins_tick (instrument_ref instrument, int sample_rate);
diff --git a/mmband/audio_player.c b/mmband/audio_player.c
deleted file mode 100644
index 3b257a4..0000000
--- a/mmband/audio_player.c
+++ /dev/null
@@ -1,4 +0,0 @@
-// dummy function for initial commit
-int add (int a, int b) {
- return a + b;
-}
diff --git a/mmband/instrument.c b/mmband/instrument.c
index 38c7d43..2ec9821 100644
--- a/mmband/instrument.c
+++ b/mmband/instrument.c
@@ -1,5 +1,6 @@
#include <math.h>
#include <stdlib.h>
+#include <stdio.h>
#include <mmband/api/instrument.h>
#include <mmband/api/adsr.h>
@@ -18,7 +19,7 @@ struct instrument {
struct oscillation carrier;
struct oscillation modulator;
- float frequency_ratio;
+ float frequency_mult;
};
float osc_tick (struct oscillation *osc, int sample_rate) {
@@ -55,7 +56,7 @@ float modulate (struct oscillation *carrier, struct oscillation *modulator, int
instrument_ref ins_new () {
instrument_ref instrument = malloc(sizeof(struct instrument));
- instrument->frequency_ratio = 1.0;
+ instrument->frequency_mult = 1.0;
instrument->carrier.type = OSC_SINE;
instrument->carrier.amplitude = 0.0;
@@ -92,17 +93,17 @@ void ins_set_carrier_amplitude (instrument_ref instrument, float amplitude) {
instrument->carrier.amplitude = amplitude;
}
-void ins_set_modulator_aplitude (instrument_ref instrument, float amplitude) {
+void ins_set_modulator_amplitude (instrument_ref instrument, float amplitude) {
instrument->modulator.amplitude = amplitude;
}
-void ins_set_frequency_ratio (instrument_ref instrument, float frequency_ratio) {
- instrument->frequency_ratio = frequency_ratio;
+void ins_set_frequency_mult (instrument_ref instrument, float frequency_mult) {
+ instrument->frequency_mult = frequency_mult;
}
void ins_set_frequency (instrument_ref instrument, float frequency) {
instrument->carrier.frequency = frequency;
- instrument->modulator.frequency = frequency * instrument->frequency_ratio;
+ instrument->modulator.frequency = frequency * instrument->frequency_mult;
}
float ins_tick (instrument_ref instrument, int sample_rate) {
diff --git a/mmband/waves/none.c b/mmband/waves/none.c
index 110dc1c..4526e8f 100644
--- a/mmband/waves/none.c
+++ b/mmband/waves/none.c
@@ -1,6 +1,6 @@
#include <mmband/waves/waveform.h>
-float zero (float phase) {
+float none (float phase) {
(void) phase;
return 0.0;
diff --git a/mmband/waves/waveform.h b/mmband/waves/waveform.h
index df18e36..cb7128c 100644
--- a/mmband/waves/waveform.h
+++ b/mmband/waves/waveform.h
@@ -1,6 +1,8 @@
#ifndef MMBAND_WAVEFORM_H
#define MMBAND_WAVEFORM_H
+#include <mmband/api/lib.h>
+
typedef float wave_function (float);
wave_function none;