Skip to content

Commit

Permalink
NEW DELAY
Browse files Browse the repository at this point in the history
very usable delay program...somehow had not gotten uploaded
  • Loading branch information
SnazzyBlanket committed Jul 19, 2012
1 parent 41fed72 commit c23f652
Show file tree
Hide file tree
Showing 39 changed files with 2,739 additions and 5 deletions.
Binary file modified Snazzy_FX/.DS_Store
Binary file not shown.
288 changes: 288 additions & 0 deletions Snazzy_FX/FAC sketches/fac_drums/fac_drums.pde
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
// ============================================================
//
// Program: ArdCore Drum Sample Player
//
// Description:
//
// This is a very lo-fi drum sample player for 8 sounds.
//
// I/O Usage:
// Knob A0: Sound selector (summed with input A2)
// Knob A1: Pitch (summed with input A3). Center value is normal pitch.
// Analog In A2: Sound selection (summed with value of knob A0)
// Analog In A3: VC Pitch (summed with value of knob A1)
// Digital Out D0: Not used
// Digital Out D1: Not used
// Clock In: Trigger sound
// Analog Out: Audio out
//
// This sketch was generated by the drum sketch
// generator, programmed by Alfonso Alba (fac)
// E-mail: [email protected]
//
// ============================================================
//
// License:
//
// This software is licensed under the Creative Commons
// Attribution-NonCommercial license. This license allows you
// to tweak and build upon the code for non-commercial purposes,
// without the requirement to license derivative works on the
// same terms. If you wish to use this (or derived) work for
// commercial work, please contact 20 Objects LLC at our website
// (www.20objects.com).
//
// For more information on the Creative Commons CC BY-NC license,
// visit http://creativecommons.org/licenses/
//
// ================= start of global section ==================


// Here we include the sample data files, which were automatically
// generated by a custom C program. In the future, I may release
// an executable version of this program so you can make your
// own sample banks

#include <avr/pgmspace.h>

#include "pitch_table.h"
#include "sample0.h"
#include "sample1.h"
#include "sample2.h"
#include "sample3.h"
#include "sample4.h"
#include "sample5.h"
#include "sample6.h"
#include "sample7.h"

// constants related to the Arduino Nano pin use
#define clkIn 2 // the digital (clock) input
#define digPin0 3 // the digital output pin D0
#define digPin1 4 // the digital output pin D1
#define pinOffset 5 // the first DAC pin (from 5-12)

// constants related to the sample player
#define NUM_SAMPLES 8 // number of samples stored in flash RAM
#define MAX_SAMPLE_SIZE 1632 // maximum length of each sound

// This array stores pointers to sample data in flash RAM
prog_uchar *sample_data[NUM_SAMPLES] = {
sample0_data, sample1_data, sample2_data, sample3_data,
sample4_data, sample5_data, sample6_data, sample7_data
};

// This one stores the size of each sample
short sample_size[NUM_SAMPLES] = {
sample0_size, sample1_size, sample2_size, sample3_size,
sample4_size, sample5_size, sample6_size, sample7_size
};

// This one stores the samplerate of each sound in samples per microsecond
float sample_fs_micro[NUM_SAMPLES] = {
sample0_fs_micro, sample1_fs_micro, sample2_fs_micro, sample3_fs_micro,
sample4_fs_micro, sample5_fs_micro, sample6_fs_micro, sample7_fs_micro
};


// This is the SRAM buffer where the sound being played is stored
unsigned char sample[MAX_SAMPLE_SIZE];

// Some global variables
char curSample = -1; // current sample number (0 to NUM_SAMPLES-1)
short curSize = 0; // size in samples of current sound
long curFSmicro = 0; // sample rate of current sound
float envStart = 0; // offset where decay starts (in samples)

short curVal0 = 0; // stores the value of analog input 0
short curVal1 = 0; // stores the value of analog input 1
short curVal2 = 0; // stores the value of analog input 2
short curVal3 = 0; // stores the value of analog input 3
unsigned long curTime = 0; // current time in microseconds
unsigned long trigTime = 0; // time at which the sound was triggered
char trigState = 0; // indicates if a sound is being played

// variables for interrupt handling of the clock input
volatile char clkState = LOW;


// This function updates the sample buffer when a new sound is selected
// and also computes the playback samplerate according to the pitch
// Inputs: n = new sample number, pitch = pitch factor
void UpdateSample(int n, long pitch) {
// limit n according to the maximum number of stored sounds
if (n >= NUM_SAMPLES) n = NUM_SAMPLES - 1;

// check if we really need to load a new waveform
if (n != curSample) {
// samples stored in flash RAM may be larger than the available buffer
// so we must crop the sample when needed
curSize = (sample_size[n] < MAX_SAMPLE_SIZE) ? sample_size[n] : MAX_SAMPLE_SIZE;

// copy the sample in flash RAM to the buffer in SRAM
memcpy_P(sample, sample_data[n], curSize);

// update current sample number
curSample = n;
}

// compute the playback samplerate taking the pitch factor into account;
// this is specified in samples per microsecond
curFSmicro = (long)(sample_fs_micro[curSample] * pitch);
}


// ==================== start of setup() ======================

// This setup routine should be used in any ArdCore sketch that
// you choose to write; it sets up the pin usage, and sets up
// initial state. Failure to properly set up the pin usage may
// lead to damaging the Arduino hardware, or at the very least
// cause your program to be unstable.

void setup()
{
// set up the digital (clock) input
pinMode(clkIn, INPUT);

// set up the digital outputs
pinMode(digPin0, OUTPUT);
digitalWrite(digPin0, LOW);
pinMode(digPin1, OUTPUT);
digitalWrite(digPin1, LOW);

// set up the 8-bit DAC output pins
for (int i=0; i<8; i++) {
pinMode(pinOffset+i, OUTPUT);
digitalWrite(pinOffset+i, LOW);
}

// Make sure some sample is loaded
UpdateSample(0, 1);
dacOutputFast(128);

// set up an interrupt handler for the clock in. If you
// aren't going to use clock input, you should probably
// comment out this call.
// Note: Interrupt 0 is for pin 2 (clkIn)
attachInterrupt(0, isr, RISING);
}


// This is the main loop

void loop()
{
unsigned long deltaT = 0;;
long p, s, n, out = 128;

// check to see if the clock as been set
if (clkState == HIGH) {
clkState = LOW; // clock pulse acknowledged
trigState = 1; // a sound has been triggered
trigTime = micros(); // remember starting time

// Poll the analog inputs and update their values
// This is only done at sample-start to save resources
curVal0 = deJitter(analogRead(0), curVal0);
curVal1 = deJitter(analogRead(1), curVal1);
curVal2 = deJitter(analogRead(2), curVal2);
curVal3 = deJitter(analogRead(3), curVal3);

// Read pitch factor from lookup table
p = pgm_read_dword_near(pitch_table + (curVal1 + curVal3));

// Load new sample if necessary and update playback samplerate
UpdateSample((curVal0 + curVal2) >> 7, p);
}

// Check if a sound is being played
if (trigState) {
// Obtain current time
curTime = micros();

// Obtain time since the sound was triggered;
// a correction is made in the unlikely case the clock overflows
deltaT = (curTime >= trigTime) ? (curTime - trigTime) : ((0xFFFFFFFF - trigTime + curTime) + 1);

// Convert time to samples and separate integer from fractional part
s = deltaT * curFSmicro;
n = s >> 16;
p = s & 0xFFFF;

// Check if the sound hasn't reached its end
if (n < curSize - 1) {
// Compute output by linear interpolation and apply envelope
out = ((65536 - p) * sample[n] + p * sample[n+1]) >> 16;
} else {
out = 128;
trigState = 0; // sample has ended
}

dacOutputFast(out);
}
}


// =================== convenience routines ===================

// These routines are some things you will need to use for
// various functions of the hardware. Explanations are provided
// to help you know when to use them.

// isr() - quickly handle interrupts from the clock input
// ------------------------------------------------------
void isr()
{
// Note: you don't want to spend a lot of time here, because
// it interrupts the activity of the rest of your program.
// In most cases, you just want to set a variable and get
// out.
clkState = HIGH;
}

// dacOutput(long) - deal with the DAC output
// ------------------------------------------
void dacOutput(long v)
{
// feed this routine a value between 0 and 255 and teh DAC
// output will send it out.
int tmpVal = v;
for (int i=0; i<8; i++) {
digitalWrite(pinOffset + i, tmpVal & 1);
tmpVal = tmpVal >> 1;
}
}


// This routine was taken from the Ardcore Oscillator example
// and it's supposed to be faster than dacOutput
void dacOutputFast(long v)
{
int tmpVal = v;
bitWrite(PORTD, 5, tmpVal & 1);
bitWrite(PORTD, 6, (tmpVal & 2) > 0);
bitWrite(PORTD, 7, (tmpVal & 4) > 0);
bitWrite(PORTB, 0, (tmpVal & 8) > 0);
bitWrite(PORTB, 1, (tmpVal & 16) > 0);
bitWrite(PORTB, 2, (tmpVal & 32) > 0);
bitWrite(PORTB, 3, (tmpVal & 64) > 0);
bitWrite(PORTB, 4, (tmpVal & 128) > 0);
}


// deJitter(int, int) - smooth jitter input
// ----------------------------------------
int deJitter(int v, int test)
{
// this routine just make sure we have a significant value
// change before we bother implementing it. This is useful
// for cleaning up jittery analog inputs.
if (abs(v - test) > 8) {
return v;
}
return test;
}



// ===================== end of program =======================
Loading

0 comments on commit c23f652

Please sign in to comment.