Compare commits

...

19 Commits

Author SHA1 Message Date
rkcf 3673952f0c Merge pull request 'Add basic Wavetable and Wave lookup table generation' (#5) from wavetable-gen into main
Closes #2

Reviewed-on: #5
2023-02-26 23:54:51 +00:00
rkcf 23cfca8ccf Fix: Wavetable wave_table initialization 2023-02-26 17:48:42 -06:00
rkcf 916f874a8f Feat: add triangle lookup table generator
Refs: #2
2023-02-26 16:55:55 -06:00
rkcf e886b4cac2 Feat: add inverse saw lookup table generation
Refs: #2
2023-02-26 16:45:02 -06:00
rkcf 6a2f2911e7 Feat: add saw wave lookup table generation
Refs: #2
2023-02-26 16:38:53 -06:00
rkcf 32f1445862 Feat: add square wave lookup table generation
Refs: #2
2023-02-26 16:28:16 -06:00
rkcf 6b36df77e1 Fix: missing header includes and add generator declarations 2023-02-26 16:13:25 -06:00
rkcf 6d40c3876c Refactor: move gen_sin to new generators file 2023-02-26 16:02:15 -06:00
rkcf 7cea04234f Refactor: rewrite classes and fix construction 2023-02-26 09:11:20 -06:00
rkcf 0c15bd2f72 Docs: add doxygen compatable documentation to files 2023-02-26 07:22:25 -06:00
rkcf c2dd910ed7 Refactor: move wave functions to wave.cpp 2023-02-26 06:16:40 -06:00
rkcf 6abdf89009 Refactor: breakout function definition to cpp file 2023-02-26 05:49:13 -06:00
rkcf 145677f0f2 Refactor: move Wavetable class to own header 2023-02-26 05:12:15 -06:00
rkcf e2736eb276 Refactor: move Wave class to own header
Refs: #2
2023-02-26 05:08:31 -06:00
rkcf 4a274f4618 Feat: add Wave class for single cycle waveform and make Wavetable proper
Refs: #2
2023-02-26 04:27:46 -06:00
rkcf 3cc6970596 Refactor: simplify number typedefs 2023-02-26 03:53:50 -06:00
rkcf 911f16b63c Feat: add sine wavetable generation
Refs: #2
2023-02-25 14:54:33 -06:00
rkcf 3742e75309 Add: skeleton wtpp.cpp with Wavetable class
Refs: #2
2023-02-25 14:02:21 -06:00
rkcf 541af6a701 Fix: change C++ version in makefile 2023-02-25 14:01:32 -06:00
8 changed files with 288 additions and 2 deletions

View File

@ -3,9 +3,9 @@ CC = /usr/bin/clang++
GDB = /usr/bin/gdb
OLEVEL = -O2
CFLAGS = -Wall -std=c++20 $(OLEVEL) -o $(PROJ)
CFLAGS = -Wall -std=c++17 $(OLEVEL) -o $(PROJ)
OBJECTS = src/wtpp.cpp
OBJECTS = src/wtpp.cpp src/wave.cpp src/wavetable.cpp src/generators.cpp
build:
$(CC) $(CFLAGS) $(OBJECTS)

85
src/generators.cpp Normal file
View File

@ -0,0 +1,85 @@
#include "generators.h"
#include "wave.h"
sample_table_t gen_sin()
{
// Make the new Wavetable object
sample_table_t sin_vals = {0};
// Make a place to store calculated value
float_t val = 0;
// Loop through number of samples and set table values
for (uint16_t i = 0; i < DEFAULT_N_SAMPLES; i++) {
// Calculate the value of sin at position
val = std::sin((2 * M_PI * i) / DEFAULT_N_SAMPLES);
sin_vals[i] = val;
}
// Return the completed Wavetable object
return sin_vals;
}
sample_table_t gen_squ()
{
sample_table_t squ_vals = {0};
// Start high and go low at halfway
for (uint16_t i = 0; i < DEFAULT_N_SAMPLES; i++) {
if (i < (DEFAULT_N_SAMPLES / 2)) {
squ_vals[i] = 1;
} else {
squ_vals[i] = 0;
}
}
return squ_vals;
}
sample_table_t gen_saw()
{
sample_table_t saw_vals = {0};
float_t step = 2.0 / DEFAULT_N_SAMPLES; // calculate our incremental step size
float_t val = 0; // place to store calculate value
// Start low go high [0, 1]
for (uint16_t i = 0; i < DEFAULT_N_SAMPLES; i++) {
saw_vals[i] = val;
val += step;
}
return saw_vals;
}
sample_table_t gen_tri()
{
sample_table_t tri_vals = {0};
uint16_t half_samples = DEFAULT_N_SAMPLES / 2;
float_t step = 2.0 / half_samples; // calculate our incremental step size
float_t val = 0; // place to store calculate value
// Start low go high then low [0, 1, 0]
for (uint16_t i = 0; i < DEFAULT_N_SAMPLES; i++) {
tri_vals[i] = val;
if (i < half_samples) {
val += step;
} else {
val -= step;
}
}
return tri_vals;
}
sample_table_t gen_isaw()
{
sample_table_t isaw_vals = {0};
float_t step = 2.0 / DEFAULT_N_SAMPLES; // calculate our incremental step size
float_t val = 1; // place to store calculate value
// Start high go low [1, 0]
for (uint16_t i = 0; i < DEFAULT_N_SAMPLES; i++) {
isaw_vals[i] = val;
val -= step;
}
return isaw_vals;
}

37
src/generators.h Normal file
View File

@ -0,0 +1,37 @@
/*! @file generators.h
@brief Header for wave cycle data generators
*/
#ifndef GENERATORS_H_
#define GENERATORS_H_
#include "math.h"
#include <cstdint>
#include "wave.h"
/*! Generate sine wave data
@return a table of values
*/
sample_table_t gen_sin();
/*! Generate square wave data
@return a table of values
*/
sample_table_t gen_squ();
/*! Generate saw wave data
@return a table of values
*/
sample_table_t gen_saw();
/*! Generate inverse saw wave data
@return a table of values
*/
sample_table_t gen_isaw();
/*! Generate triangle wave data
@return a table of values
*/
sample_table_t gen_tri();
#endif // GENERATORS_H_

10
src/wave.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "wave.h"
// Initialize index at 0 for wave cycles and wave tables
uint16_t Wave::m_nid = 0;
void Wave::print_head() {
for (uint8_t i = 0; i < 3; i++) {
std::cout << m_table[i] << '\n';
}
}

41
src/wave.h Normal file
View File

@ -0,0 +1,41 @@
/*! @file wave.h
@brief Header for Wave class and associated Wave functions
*/
#ifndef WAVE_H_
#define WAVE_H_
#include <iostream>
#include <array>
#include <cstdint>
#include <math.h>
const uint16_t DEFAULT_N_SAMPLES = 1024;
using sample_table_t = std::array<float_t, DEFAULT_N_SAMPLES>;
/*! @class Wave wave.h "wave.h"
@brief Single cycle wave object with lookup table
*/
class Wave {
private:
static uint16_t m_nid; /*!< Unique ID number of NEXT wave */
sample_table_t m_table; /*!< Table of sample data */
public:
const uint16_t m_cid; /*!< Unique ID of current wavetable */
Wave() : m_cid(m_nid++) {}
/*! ID getter */
uint16_t getId() { return m_cid; }
/*! Sample data table setter
@param table Sample data table
*/
void setTable(sample_table_t table) { m_table = table; }
/*! Prints the first 3 values of sample data */
void print_head();
};
#endif // WAVE_H_

11
src/wavetable.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "wavetable.h"
// Initialize index at 0 for wave cycles and wave tables
uint16_t Wavetable::m_nid = 0;
std::string Wavetable::name() {
std::string id_str = std::to_string(m_cid);
id_str.append(": ");
id_str.append(m_name);
return id_str;
}

41
src/wavetable.h Normal file
View File

@ -0,0 +1,41 @@
/*! @file wavetable.h
@brief Header for Wavetable class and associated table functions
*/
#ifndef WAVETABLE_H_
#define WAVETABLE_H_
#include <array>
#include <cstdint>
#include <string>
#include "wave.h"
/* Number of Wave cycle objects in table */
const uint16_t DEFAULT_N_WAVES = 256;
using wave_table_t = std::array<Wave, DEFAULT_N_WAVES>;
/*! @class Wavetable wavetable.h "wavetable.h"
@brief Object containing a table of single cycle Wave objects
*/
class Wavetable {
private:
static uint16_t m_nid; /*!< Unique ID number of wavetable */
std::string m_name; /*!< String name of wavetable */
wave_table_t m_wave_table; /*!< Table of Wave objects */
public:
const uint16_t m_cid; /*!< Unique ID of NEXT wavetable */
Wavetable(std::string name, wave_table_t wt)
: m_name{name}, m_wave_table{wt}, m_cid(m_nid++) {}
/*! ID getter */
uint16_t getId() { return m_cid; }
/*! Makes formatted name and id string
@return a formatted string in the form "id: name"
*/
std::string name();
};
#endif // WAVETABLE_H_

61
src/wtpp.cpp Normal file
View File

@ -0,0 +1,61 @@
#include <array>
#include <cmath>
#include <cstdint>
#include <iostream>
#include <string>
#include <type_traits>
#include <math.h>
#include "wave.h"
#include "generators.h"
#include "wavetable.h"
static const uint32_t DEFAULT_SAMPLE_RATE = 44100; // 44.1 kHz sampling rate
static const uint8_t DEFAULT_BIT_DEPTH = 12;
/*! Logs a message
@param message The string to be logged
*/
static void log(std::string message)
{
std::cout << "wtpp: " << message << '\n';
}
int main()
{
log("Generating wave cycle lookup tables");
Wave sin_wave, squ_wave, saw_wave, tri_wave, isaw_wave;
// Calculate fundamental wave values
sample_table_t sin_vals = gen_sin();
sample_table_t squ_vals = gen_squ();
sample_table_t saw_vals = gen_saw();
sample_table_t tri_vals = gen_tri();
sample_table_t isaw_vals = gen_isaw();
// Set wave lookup table values
sin_wave.setTable(sin_vals);
squ_wave.setTable(squ_vals);
saw_wave.setTable(saw_vals);
tri_wave.setTable(tri_vals);
isaw_wave.setTable(isaw_vals);
log("Printing head of sine table");
sin_wave.print_head();
log("Printing head of square table");
squ_wave.print_head();
log("Printing head of saw table");
saw_wave.print_head();
log("Printing head of triangle table");
tri_wave.print_head();
log("Printing head of inverse saw table");
isaw_wave.print_head();
// Create wave table of all fundamental Wave objects
wave_table_t fundies = {sin_wave, squ_wave, saw_wave, tri_wave, isaw_wave};
Wavetable wt_01{"Fundamental Waves", fundies};
log(wt_01.name());
return 0;
}