ソースを参照

Add arbitrary waveform and offset to AudioSynthWaveform

dds
PaulStoffregen 10年前
コミット
8996df5142
5個のファイルの変更75行の追加48行の削除
  1. +6
    -0
      keywords.txt
  2. +1
    -2
      synth_sine.cpp
  3. +3
    -0
      synth_sine.h
  4. +35
    -31
      synth_waveform.cpp
  5. +30
    -15
      synth_waveform.h

+ 6
- 0
keywords.txt ファイルの表示

updateCoefs KEYWORD2 updateCoefs KEYWORD2
frequency KEYWORD2 frequency KEYWORD2
amplitude KEYWORD2 amplitude KEYWORD2
offset KEYWORD2
resonance KEYWORD2 resonance KEYWORD2
octaveControl KEYWORD2 octaveControl KEYWORD2
modify KEYWORD2 modify KEYWORD2
FILTER_LOSHELF LITERAL1 FILTER_LOSHELF LITERAL1
FILTER_HISHELF LITERAL1 FILTER_HISHELF LITERAL1


WAVEFORM_SINE LITERAL1
WAVEFORM_SAWTOOTH LITERAL1
WAVEFORM_SQUARE LITERAL1
WAVEFORM_TRIANGLE LITERAL1
WAVEFORM_ARBITRARY LITERAL1



+ 1
- 2
synth_sine.cpp ファイルの表示

* THE SOFTWARE. * THE SOFTWARE.
*/ */


#include "Audio.h"
#include "arm_math.h"
#include "synth_sine.h"
#include "utility/dspinst.h" #include "utility/dspinst.h"


// data_waveforms.c // data_waveforms.c

+ 3
- 0
synth_sine.h ファイルの表示

#ifndef synth_sine_h_ #ifndef synth_sine_h_
#define synth_sine_h_ #define synth_sine_h_


#include "AudioStream.h"
#include "arm_math.h"

// TODO: investigate making a high resolution sine wave // TODO: investigate making a high resolution sine wave
// using Taylor series expansion. // using Taylor series expansion.
// http://www.musicdsp.org/showone.php?id=13 // http://www.musicdsp.org/showone.php?id=13

+ 35
- 31
synth_waveform.cpp ファイルの表示

// PAH 140314 - change t_hi from int to float // PAH 140314 - change t_hi from int to float




boolean AudioSynthWaveform::begin(float t_amp,float t_hi,short type)
{
tone_type = type;
amplitude(t_amp);
tone_freq = t_hi > 0.0;
if(t_hi <= 0.0)return false;
if(t_hi >= AUDIO_SAMPLE_RATE_EXACT/2)return false;
tone_phase = 0;
frequency(t_hi);
if(0) {
Serial.print("AudioSynthWaveform.begin(tone_amp = ");
Serial.print(t_amp);
Serial.print(", tone_hi = ");
Serial.print(t_hi);
Serial.print(", tone_incr = ");
Serial.print(tone_incr,HEX);
// Serial.print(", tone_hi = ");
// Serial.print(t_hi);
Serial.println(")");
}
return(true);
}

void AudioSynthWaveform::update(void) void AudioSynthWaveform::update(void)
{ {
audio_block_t *block; audio_block_t *block;
short *bp;
short *bp, *end;
int32_t val1, val2, val3; int32_t val1, val2, val3;
uint32_t index, scale; uint32_t index, scale;
uint32_t mag; uint32_t mag;
short tmp_amp; short tmp_amp;
if(tone_freq == 0)return;
if(tone_amp == 0) return;
block = allocate(); block = allocate();
if(block) {
if (block) {
bp = block->data; bp = block->data;
switch(tone_type) { switch(tone_type) {
case TONE_TYPE_SINE:
case WAVEFORM_SINE:
for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) { for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
// Calculate interpolated sin // Calculate interpolated sin
index = tone_phase >> 23; index = tone_phase >> 23;
if(tone_phase & 0x80000000)tone_phase &= 0x7fffffff; if(tone_phase & 0x80000000)tone_phase &= 0x7fffffff;
} }
break; break;

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;
case TONE_TYPE_SQUARE:
case WAVEFORM_SQUARE:
for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) { for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
if(tone_phase & 0x40000000)*bp++ = -tone_amp; if(tone_phase & 0x40000000)*bp++ = -tone_amp;
else *bp++ = tone_amp; else *bp++ = tone_amp;
} }
break; break;
case TONE_TYPE_SAWTOOTH:
case WAVEFORM_SAWTOOTH:
for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) { for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
*bp++ = ((short)(tone_phase>>15)*tone_amp) >> 15; *bp++ = ((short)(tone_phase>>15)*tone_amp) >> 15;
// phase and incr are both unsigned 32-bit fractions // phase and incr are both unsigned 32-bit fractions
} }
break; break;


case TONE_TYPE_TRIANGLE:
case WAVEFORM_TRIANGLE:
for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) { for(int i = 0;i < AUDIO_BLOCK_SAMPLES;i++) {
if(tone_phase & 0x80000000) { if(tone_phase & 0x80000000) {
// negative half-cycle // negative half-cycle
} }
break; break;
} }
// send the samples to the left channel
if (tone_offset) {
bp = block->data;
end = bp + AUDIO_BLOCK_SAMPLES;
do {
val1 = *bp;
*bp++ = signed_saturate_rshift(val1 + tone_offset, 16, 0);
} while (bp < end);
}
transmit(block,0); transmit(block,0);
release(block); release(block);
} }

+ 30
- 15
synth_waveform.h ファイルの表示



#define DELAY_PASSTHRU -1 #define DELAY_PASSTHRU -1


#define WAVEFORM_SINE 0
#define WAVEFORM_SAWTOOTH 1
#define WAVEFORM_SQUARE 2
#define WAVEFORM_TRIANGLE 3
#define WAVEFORM_ARBITRARY 4

// todo: remove these...
#define TONE_TYPE_SINE 0 #define TONE_TYPE_SINE 0
#define TONE_TYPE_SAWTOOTH 1 #define TONE_TYPE_SAWTOOTH 1
#define TONE_TYPE_SQUARE 2 #define TONE_TYPE_SQUARE 2
public: public:
AudioSynthWaveform(void) : AudioSynthWaveform(void) :
AudioStream(0,NULL), AudioStream(0,NULL),
tone_freq(0), tone_phase(0), tone_incr(0), tone_type(0)
tone_phase(0), tone_incr(0), tone_type(0),
tone_offset(0), arbdata(NULL)
{ {
} }
void frequency(float t_hi)
{
if (t_hi > AUDIO_SAMPLE_RATE_EXACT / 2 || t_hi < 0.0) return;
tone_incr = ((0x80000000LL*t_hi)/AUDIO_SAMPLE_RATE_EXACT) + 0.5;
void frequency(float t_freq) {
if (t_freq < 0.0) t_freq = 0.0;
else if (t_freq > AUDIO_SAMPLE_RATE_EXACT / 2) t_freq = AUDIO_SAMPLE_RATE_EXACT / 2;
tone_incr = (t_freq * (0x80000000LL/AUDIO_SAMPLE_RATE_EXACT)) + 0.5;
} }
void amplitude(float n) { // 0 to 1.0 void amplitude(float n) { // 0 to 1.0
if (n < 0) n = 0; if (n < 0) n = 0;
else if (n > 1.0) n = 1.0; else if (n > 1.0) n = 1.0;
// Ramp code
if(tone_amp && (n == 0)) {
last_tone_amp = tone_amp;
}
else if((tone_amp == 0) && n) {
if ((tone_amp == 0) && n) {
// reset the phase when the amplitude was zero // reset the phase when the amplitude was zero
// and has now been increased. // and has now been increased.
tone_phase = 0; tone_phase = 0;
// set new magnitude // set new magnitude
tone_amp = n * 32767.0; tone_amp = n * 32767.0;
} }
boolean begin(float t_amp,float t_hi,short t_type);
void offset(float n) {
if (n < -1.0) n = -1.0;
else if (n > 1.0) n = 1.0;
tone_offset = n * 32767.0;
}
void begin(short t_type) {
tone_phase = 0;
tone_type = t_type;
}
void begin(float t_amp, float t_freq, short t_type) {
amplitude(t_amp);
frequency(t_freq);
begin(t_type);
}
virtual void update(void); virtual void update(void);
private: private:
short tone_amp; short tone_amp;
short last_tone_amp;
short tone_freq; short tone_freq;
uint32_t tone_phase; uint32_t tone_phase;
// volatile prevents the compiler optimizing out the frequency function // volatile prevents the compiler optimizing out the frequency function
volatile uint32_t tone_incr; volatile uint32_t tone_incr;
short tone_type; short tone_type;

int16_t tone_offset;
const int16_t *arbdata;
}; };





読み込み中…
キャンセル
保存