Create an array of wave data for wavetable synth

Hello,

I am working on a synth project called the_synth located here:

Wondering how the author created those arrays, the elements (numbers) for his waveform table arrays; SinTable[], Triangle[], SquareTable[], etc.
(Dis he take a recorded wav sample and somehow convert it to text?) I did try contacting the author, however no reply.

All is going well with my project, just wondering how I could replace those arrays with my own. If anyone might be able to offer any advice, it would be greatly appreciated.

Thanks,
TonyA

In what form do you have data for your arrays?

I've created wave tables by using trig functions and for loops.

On a real computer, it is easier. Write a program to do the calculations and print them, with as much formatting as you bother to do, as required for array initialisation.

I usually go as far as making rows of 16 separated by commas.

You can use trig and then scaling and shifting to make the data perfect for, well, whatever it is supposed to be used for.

You can get tots carried away, like looking into Fourier series if you want to make sawtooth or triangle waveforms.

Doesn't matter how slow or fast, as it just prints the table.

Use a text editor to add the other little bits. Or if you are better with a text editor, use it to do all the formatting of a long list of numbers.

In Unix you can direct the output to a file, convenient.

Or just a lot of cutting and pasting.

a7

There are "canned" C programs to convert raw data to C declarations. Sorry I don't know where, but I've seen them.

For sound files, you have to be careful to omit file headers and trailers.

I've seen them come and go beneath my fingers, these are one offs, too lazy to make anything worth keeping…

And who remembers those guys who could do anythjng with a text editor?

a7

Well, in truth they really only consist of a few lines of code. :slight_smile:

I have ignorantly just used writing to a binary file. The simplest sound file is just a bunch of numbers.

First step after that is your favorite sound tool what can read that file and save it as a real sound file.

The same programs that can write wave tables as text can write binary files that are music, well maybe not music to everyone's ears…

And again, it may take some time to synthesize a few minutes of a composition. Who cares?

The real fun is modern software synthesizers that do real time calculations, putting all those clock cycles per second to some good use.

The Arduino can do a bit of that and keep up OK.

a7

I played with one really fun sound tool, way back. It was a drag and drop functional diagram. I modelled some diesel locomotive horns. Then they sneakily phased out the freeware aspect of it, and my files were orphaned. I was not happy about that.

It depends on what those array data are.
Are you taking o out some sort of function?
If that is true then declare an array of the appropriate size and use a for loop to place the calculated data into an array.

If you want to define an array that contains things like a sound sample, then I have some code written in the Processing language that will take a wav file and print it out to the console window in the right format so all you need to do is to copy he console window and paste it into an Arduino IDE tab.

Hi,

A am a new student to wavetables and and DDS with arduino (or anything), but I think that what I am looking at are representations of voltages (as used in an analog voltage controlled oscillator).

I thought if I could create my own custom list of values I could replace this (this is from the original code): There are several of these arrays (Sine, triangle, square, ramp and noise.) The items in the arrays all have a range 0-255, i.e., SinTable[255].

Below is the SinTable[] array

PROGMEM char SinTable[]=
{
0, //0
3, //1
6, //2
9, //3
12, //4
15, //5
18, //6
21, //7
24, //8
27, //9
30, //10
33, //11
36, //12
39, //13
42, //14
45, //15
48, //16
51, //17
54, //18
57, //19
59, //20
62, //21
65, //22
67, //23
70, //24
73, //25
75, //26
78, //27
80, //28
82, //29
85, //30
87, //31
89, //32
91, //33
94, //34
96, //35
98, //36
100, //37
102, //38
103, //39
105, //40
107, //41
108, //42
110, //43
112, //44
113, //45
114, //46
116, //47
117, //48
118, //49
119, //50
120, //51
121, //52
122, //53
123, //54
123, //55
124, //56
125, //57
125, //58
126, //59
126, //60
126, //61
126, //62
126, //63
127, //64
126, //65
126, //66
126, //67
126, //68
126, //69
125, //70
125, //71
124, //72
123, //73
123, //74
122, //75
121, //76
120, //77
119, //78
118, //79
117, //80
116, //81
114, //82
113, //83
112, //84
110, //85
108, //86
107, //87
105, //88
103, //89
102, //90
100, //91
98, //92
96, //93
94, //94
91, //95
89, //96
87, //97
85, //98
82, //99
80, //100
78, //101
75, //102
73, //103
70, //104
67, //105
65, //106
62, //107
59, //108
57, //109
54, //110
51, //111
48, //112
45, //113
42, //114
39, //115
36, //116
33, //117
30, //118
27, //119
24, //120
21, //121
18, //122
15, //123
12, //124
9, //125
6, //126
3, //127
0, //128
-3, //129
-6, //130
-9, //131
-12, //132
-15, //133
-18, //134
-21, //135
-24, //136
-27, //137
-30, //138
-33, //139
-36, //140
-39, //141
-42, //142
-45, //143
-48, //144
-51, //145
-54, //146
-57, //147
-59, //148
-62, //149
-65, //150
-67, //151
-70, //152
-73, //153
-75, //154
-78, //155
-80, //156
-82, //157
-85, //158
-87, //159
-89, //160
-91, //161
-94, //162
-96, //163
-98, //164
-100, //165
-102, //166
-103, //167
-105, //168
-107, //169
-108, //170
-110, //171
-112, //172
-113, //173
-114, //174
-116, //175
-117, //176
-118, //177
-119, //178
-120, //179
-121, //180
-122, //181
-123, //182
-123, //183
-124, //184
-125, //185
-125, //186
-126, //187
-126, //188
-126, //189
-126, //190
-126, //191
-127, //192
-126, //193
-126, //194
-126, //195
-126, //196
-126, //197
-125, //198
-125, //199
-124, //200
-123, //201
-123, //202
-122, //203
-121, //204
-120, //205
-119, //206
-118, //207
-117, //208
-116, //209
-114, //210
-113, //211
-112, //212
-110, //213
-108, //214
-107, //215
-105, //216
-103, //217
-102, //218
-100, //219
-98, //220
-96, //221
-94, //222
-91, //223
-89, //224
-87, //225
-85, //226
-82, //227
-80, //228
-78, //229
-75, //230
-73, //231
-70, //232
-67, //233
-65, //234
-62, //235
-59, //236
-57, //237
-54, //238
-51, //239
-48, //240
-45, //241
-42, //242
-39, //243
-36, //244
-33, //245
-30, //246
-27, //247
-24, //248
-21, //249
-18, //250
-15, //251
-12, //252
-9, //253
-6, //254
-4, //255

I thought that those arrays (SinTable[], SquareTable[], etc. were actual sound samples converted into decimal number form.

Still learning, sincere thanks for the advice and help, much appreciated.

TonyA

I think what I'm looking at in the original code are representations of voltages, like those used in voltage controlled oscillators, however used here for the arduino in a range of 0-255.

There are several arrays: SinTable[256], Triangle[256], etc. all within a range of 256 elements in the array.

Here is a snippet of the the TriangleTable[];

type or paste code here

const PROGMEM char TriangleTable[]=
{
0, //0
1, //1
3, //2
5, //3
7, //4
9, //5
11, //6
13, //7
15, //8
17, //9
19, //10
21, //11
23, //12
25, //13
27, //14
29, //15
31, //16
33, //17
35, //18
37, //19
39, //20
41, //21
43, //22
45, //23
47, //24
49, //25
51, //26
53, //27
55, //28
57, //29
59, //30
61, //31
etc.

I've never done DDS with the arduino (or anything else). But, I thought I could replace those arrays with my own to create my own custom sounds.

Thanks again for the advice and help while I am learning about this, sincerely appreciate.
TonyAm

To have your own custom sounds you need a big array, much bigger than 256 bytes. The Arduino UNO can store only about 3 seconds of sound.

A 256 byte array is enough to store a wave table to allow you to generate your own shaped wave table, but that will not necessarily sound much different from the Sin, Square, triangle and sawtooth waveform you have.

(Sorry for the double post)
I see. I believe I need to study more on sound synthesis with the arduino to get more of an understanding. I know that the real voo-doo of the code I'm trying to decipher uses pure embedded C programming to do all of the Timer/counter bit-manipulation to process those tables and make sound.

Should someone (like me) look into pure C, or C++ to understand that stuff?
Thanks again,
TonyAm

I usually use a spreadsheet. Generate the required number of values from the desired formula. Copy the values. Paste them into a text file. Add formatting to make them into a C++ declaration.

The spreadsheet isn't good at hexadecimal so I usually use decimal.

const int8_t sinetable[64] =
{
  0,   12,   25,   37,   49,   60,   71,   81,
  90,   98,  106,  112,  117,  122,  125,  126,
  127,  126,  125,  122,  117,  112,  106,   98,
  90,   81,   71,   60,   49,   37,   25,   12,
  0,  -12,  -25,  -37,  -49,  -60,  -71,  -81,
  -90,  -98, -106, -112, -117, -122, -125, -126,
  -127, -126, -125, -122, -117, -112, -106,  -98,
  -90,  -81,  -71,  -60,  -49,  -37,  -25,  -12
};

I have read that that is the way some people have done this, however I don't know what the "formula" is to create the data. (Still learning).
Thanks very much for your insight.

All that C++ does is to extend C to allow you to use classes. What you need to understand is the digital nature of sound.
A free book on the basics of Audio can be found at
Download pdf Book on the basics of Audio

Then there is my book on MIDI, sound and sound manipulation:-
Arduino Sound and projects

Here is a video, from my book of the Arduino saying YES or NO by pressing a button.

Here is some code that creates one of the four types of wave table There are some missing definitions like the wave table deceleration but I am sure you can see that it just fills an array with numbers, in this case floating point according to the function it is trying to create.

void makeWave(int8_t type){ // type 0 = sine, 1 = saw, 2 = triangle, 3 = square
    float increment = 0.0;
    float point = 0.0;
    if(type == 0){ // sine wave
        for (int16_t i = 0; i < WAVE_TABLE_LEN; i++) {
            wave_table[i] = cosf(i * 2 * (float)(M_PI / (float)(WAVE_TABLE_LEN)));
    }
   }
    if(type == 1){ // saw tooth
        point = 0.0;
        increment = 1.0 / (WAVE_TABLE_LEN / 2);
        for (int16_t i = 0; i < WAVE_TABLE_LEN; i++) {
            wave_table[i] = point;
            point += increment;
            if(i == 256) {point = -0.99;}
    }
   }
   if(type == 2){ // triangle
       point = 0.0;
       increment = 2.0 / (WAVE_TABLE_LEN / 2);
       for (int16_t i = 0; i < WAVE_TABLE_LEN; i++) {
           wave_table[i] = point;
           point += increment;
           if(i == 127) increment = - increment;
           if(i == 383) increment = - increment;            
    }
   }
   if(type == 3){ // square
       point = 0.9999;
       for (int16_t i = 0; i < WAVE_TABLE_LEN; i++) {
           wave_table[i] = point;
           if(i == 255) point = - 0.9999;
       }
   }

}

Here is a waveform that is half a saw tooth and half a sin wave. Looks grovy on a scope but just sounds like a buzz.

Well look at the code I posted above to see the formula for each of the four basic wave shapes.

Having designed the silicon for a number of "professional" music synthesizers over the years, I can tell you an AVR-based Arduino is an absolutely awful platform for any kind of audio work. You would be FAR better off using a much more powerful processor, with much more memory. That would allow more samples, better quality samples, and MUCH more flexiblty in playback, using a real 16-bit, or even 24-bit, I2S DAC with DMA data delivery, and some real-time signal processing to do interpolation, filtering, mixing, etc. An AVR will never produce good quality sound. A RaspberryPi would be able to do, in software, nearly everything a dedicated hardware synthesizer from Roland, Yamaha, Korg, Emu, Ensoniq, etc. could do 20 years ago.

If you want a sinewave the function would be based on the sin() function. What do you want the waveform to look like? If you don't know what you want it will be hard to calculate the values.

Thanks for all of that, I will study this for awhile.
TonyAm

I was thinking of percussion sounds, but I see that I have more studying to do.
I
Thanks very much,
TonyAm