(I'm responding from a hotel and don't have a T3.1/audioboard in front of me)
I agree an example would be good to add. However, there is some information available.
Just checking that you read the documentation
http://www.pjrc.com/teensy/gui/?info=AudioSynthWaveform
which says
arbitraryWaveform(array, maxFreq);
Configure the waveform to be used with WAVEFORM_ARBITRARY. Array must be an array of 256 samples. Currently, the data is used without any filtering, which can cause aliasing with frequencies above 172 Hz. For higher frequency output, you must bandwidth limit your waveform data. Someday, "maxFreq" will be used to do this automatically.
The bandlimiting warning is not as serious as it sounds, since the built-in square, pulse, triangle and sawtooth waveforms are not bandlimited either. The limitation to 256 samples is better than it sounds, because linear interpolation is used between samples so the waveform is actually a 256-element piecewise linear approximation.
Turning now to the code, in (your arduino install location)/libraries/Audio/synth_waveform.h you see the definitions
Code:
void arbitraryWaveform(const int16_t *data, float maxFreq) {
arbdata = data;
}
and
As noted, maxFreq can be anything as it is ignored currently. The data for the arbitrary waveform is signed, 16-bit integers.
Now, C/C++ are languages which unfortunately consider arrays, pointers and addresses to all be the same thing so we look at synth_waveform.cpp to find out more about this array.
Code:
case WAVEFORM_ARBITRARY:
if (!arbdata) {
release(block);
return;
}
// len = 256
for (int i = 0; i < AUDIO_BLOCK_SAMPLES;i++) {
index = tone_phase >> 23;
val1 = *(arbdata + index);
val2 = *(arbdata + ((index + 1) & 255));
scale = (tone_phase >> 7) & 0xFFFF;
val2 *= scale;
val1 *= 0xFFFF - scale;
val3 = (val1 + val2) >> 16;
*bp++ = (short)((val3 * tone_amp) >> 15);
tone_phase += tone_incr;
tone_phase &= 0x7fffffff;
}
break;
OK, confirmation (in a comment) that it is an array of 256 elements (not 257, like the sine function uses. Comparing this code to that of the sine function in the same file may however be helpful as they are similar, differing only in how they wrap around the waveform data array).
The sine data contains a full 360 degrees of sine data. Similarly the arbitrary waveform table must contain a full period of the waveform data, meaning that the first sample will be used right after the last sample (they should be similar values to avoid a discontinuity). Only a single table is used, not multiple tables of progressively decreased harmonic content, so ensure the harmonics are sufficient for the lowest frequency you plan to use; if aliasing is apparent, a steep low-pass filter at 18-21kHz before the DAC can be beneficial.
One last hint. Software aimed at sampling may well allow you to save out one-cycle waveform tables, but is likely to want to know both the frequency of the sample and the sampling rate; it will then write out a table with as many samples as are needed. However, for use with the audio library both of those items are irrelevant. Just pick values such that it gives you a table with exactly 256 entries.
As an example, if the sampling rate is fixed at 44.1kHz then you would tell it the frequency is 44100 / 256 = 172.26Hz. (you saw that number earlier, in the documentation; this is why). Similarly for 48kHz, say the frequency is 187.5Hz. Both will give you a table of 256 entries.
Hope that helps.