Introduction: Simple Sample Rate Adjustable Device
Project Name: Drop.
This is a very simple project and this is also my first Instructables…..
Project Description:
A sound box that plays a file of my voice and allows for the viewer to lower the pitch of my voice as the file is playing.
What motivated the making of the piece:
A growing interest in educational platforms such Instructables and Maker communities to share resources and skills- fostering curiosity. I am interested in the ways in which technology is used, shared, fictionalized and applied. I chose to focus on acoustic fiction as a starting place for a conversation on agency: I placed a diagram above the “player” that mapped out in a relatively accurate manner the physiological effects, myths and applications that result from sound (pitch and loudness) depending on its lowering in Hz and loudness in dB; with everything from frequency zone corresponding to ghost sightings, the Brown Note, Vladimir Gavreau’s sonic weapon and acoustic testing, the sound of a baby crying, grenades, a motorcycle, human voice, etc.
Parts List:
1. waveshield from adafruit: http://www.adafruit.com/products/94
2. arduino uno
3. perf board
4. LED
5. Pushbutton
6. 10 K ohm resistor (brown black orange gold)
7. Any small speaker// I used a tech & go rechargeable speaker: http://www.drugstore.com/tech-and-go-rechargable-portable-speaker-blue/qxp460069
8. Project box
9. Box for speaker
10. Sugru http://sugru.com
11. Audio foam// foam
12. Soldering iron
First Step:
Solder wave shield and format SD card accordingly. Great tutorials provided here:
http://www.robotshop.com/content/PDF/adafruit-wave-shield-user-guide.pdf
Note that the library used in this tutorial is now obsolete. Refer to gitHub to download the new WaveHC library http://code.google.com/p/sdfatlib/downloads/list
Second Step:
Circuit:
Because I wanted to make my little player as intuitive as possible, I decided to add a ‘play’ button that would only play the file (not interrupt it), a light that would turn on only while the file is playing and a potentiometer to slow down the sample rate of the file while it is playing.
Code:
/*................... Adafruit SampleRateMod.pde example modified to use WaveHC.
File plays when button is pressed. Slows sample rate with pot on analog 0.
Many thanks to WaveHC Library, Adafruit, David Casey, Tom Jennings!!!!!
Project: LEVEL by DB
last modified on April 30, 2013............................*/
#include
#include
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the volumes root directory
FatReader file; // This object represent the WAV file
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
/*
* Define macro to put error messages in flash memory
*/
#define error(msg) error_P(PSTR(msg))
int buttonValue;
const int ledPin = 15; // this is really analog 1 on arduino
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("Wave test!");
// try card.init(true) if errors occur on V1.0 Wave Shield
if (!card.init()) {
error("Card init. failed!");
}
// enable optimize read - some cards may timeout
card.partialBlockRead(true);
if (!vol.init(card)) {
error("No partition!");
}
if (!root.openRoot(vol)) {
error("Couldn't open root");
}
putstring_nl("Files found:");
root.ls();
}
// forward declarition
void playcomplete(FatReader &file);
void loop() {
uint8_t i, r;
char c, name[15];
dir_t dir;
buttonValue = digitalRead(7);
root.rewind();
// scroll through the files in the directory
while (root.readDir(dir) > 0) {
// only play .WAV files
if (!strncmp_P((char *)&dir.name[8]. PSTR("WAV"))) continue;
if (!file.open(vol, dir)){
putstring("Can't open ");
printEntryName(dir);
Serial.println();
continue;
}
putstring("\n\rPlaying ");
printEntryName(dir);
Serial.println();
if (buttonValue == HIGH) {
playcomplete(file);
}
digitalWrite (ledPin, LOW); // must be outside the f to turn led OFF
}
}
/////////////////////////////////// HELPERS
/*
* print error message and halt
*/
void error_P(const char *str) {
PgmPrint("Error: ");
SerialPrint_P(str);
sdErrorCheck();
while(1);
}
/*
* print error message and halt if SD I/O error, great for debugging!
*/
void sdErrorCheck(void) {
if (!card.errorCode()) return;
PgmPrint("\r\nSD I/O error: ");
Serial.print(card.errorCode(), HEX);
PgmPrint(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
int16_t lastpotval = 0;
#define HYSTERESIS 3
/*
* play file with sample rate changes
*/
void playcomplete(FatReader &file) {
int16_t potval;
uint32_t newsamplerate;
if (!wave.create(file)) {
putstring_nl(" Not a valid WAV");
return;
}
wave.play();
if (wave.isplaying) {
digitalWrite(ledPin, HIGH);
}
while (wave.isplaying) {
potval = analogRead(0);
if ( ((potval - lastpotval) > HYSTERESIS) || ((lastpotval - potval) > HYSTERESIS)) {
putstring("pot = ");
Serial.println(potval, DEC);
putstring("tickspersam = ");
Serial.print(wave.dwSamplesPerSec, DEC);
putstring(" -> ");
newsamplerate = wave.dwSamplesPerSec;
newsamplerate *= potval;
newsamplerate /= 512; // we want to 'split' between sped up and slowed down.
if (newsamplerate > 24000) {
newsamplerate = 24000;
}
if (newsamplerate < 1000) {
newsamplerate = 1000;
}
wave.setSampleRate(newsamplerate);
Serial.println(newsamplerate, DEC);
lastpotval = potval;
}
delay(10);
}
sdErrorCheck();
file.close();
}
Third Part:
Adjust the guts to the design of your enclosure. Drill holes accordingly. Because I am using a small speaker, I can power the whole thing off of a 9V battery which just makes it easier to install as power source is a consistent issue.
Here is a link to working documentation:
https://vimeo.com/66703542
This is a very simple project and this is also my first Instructables…..
Project Description:
A sound box that plays a file of my voice and allows for the viewer to lower the pitch of my voice as the file is playing.
What motivated the making of the piece:
A growing interest in educational platforms such Instructables and Maker communities to share resources and skills- fostering curiosity. I am interested in the ways in which technology is used, shared, fictionalized and applied. I chose to focus on acoustic fiction as a starting place for a conversation on agency: I placed a diagram above the “player” that mapped out in a relatively accurate manner the physiological effects, myths and applications that result from sound (pitch and loudness) depending on its lowering in Hz and loudness in dB; with everything from frequency zone corresponding to ghost sightings, the Brown Note, Vladimir Gavreau’s sonic weapon and acoustic testing, the sound of a baby crying, grenades, a motorcycle, human voice, etc.
Parts List:
1. waveshield from adafruit: http://www.adafruit.com/products/94
2. arduino uno
3. perf board
4. LED
5. Pushbutton
6. 10 K ohm resistor (brown black orange gold)
7. Any small speaker// I used a tech & go rechargeable speaker: http://www.drugstore.com/tech-and-go-rechargable-portable-speaker-blue/qxp460069
8. Project box
9. Box for speaker
10. Sugru http://sugru.com
11. Audio foam// foam
12. Soldering iron
First Step:
Solder wave shield and format SD card accordingly. Great tutorials provided here:
http://www.robotshop.com/content/PDF/adafruit-wave-shield-user-guide.pdf
Note that the library used in this tutorial is now obsolete. Refer to gitHub to download the new WaveHC library http://code.google.com/p/sdfatlib/downloads/list
Second Step:
Circuit:
Because I wanted to make my little player as intuitive as possible, I decided to add a ‘play’ button that would only play the file (not interrupt it), a light that would turn on only while the file is playing and a potentiometer to slow down the sample rate of the file while it is playing.
Code:
/*................... Adafruit SampleRateMod.pde example modified to use WaveHC.
File plays when button is pressed. Slows sample rate with pot on analog 0.
Many thanks to WaveHC Library, Adafruit, David Casey, Tom Jennings!!!!!
Project: LEVEL by DB
last modified on April 30, 2013............................*/
#include
#include
SdReader card; // This object holds the information for the card
FatVolume vol; // This holds the information for the partition on the card
FatReader root; // This holds the information for the volumes root directory
FatReader file; // This object represent the WAV file
WaveHC wave; // This is the only wave (audio) object, since we will only play one at a time
/*
* Define macro to put error messages in flash memory
*/
#define error(msg) error_P(PSTR(msg))
int buttonValue;
const int ledPin = 15; // this is really analog 1 on arduino
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
Serial.println("Wave test!");
// try card.init(true) if errors occur on V1.0 Wave Shield
if (!card.init()) {
error("Card init. failed!");
}
// enable optimize read - some cards may timeout
card.partialBlockRead(true);
if (!vol.init(card)) {
error("No partition!");
}
if (!root.openRoot(vol)) {
error("Couldn't open root");
}
putstring_nl("Files found:");
root.ls();
}
// forward declarition
void playcomplete(FatReader &file);
void loop() {
uint8_t i, r;
char c, name[15];
dir_t dir;
buttonValue = digitalRead(7);
root.rewind();
// scroll through the files in the directory
while (root.readDir(dir) > 0) {
// only play .WAV files
if (!strncmp_P((char *)&dir.name[8]. PSTR("WAV"))) continue;
if (!file.open(vol, dir)){
putstring("Can't open ");
printEntryName(dir);
Serial.println();
continue;
}
putstring("\n\rPlaying ");
printEntryName(dir);
Serial.println();
if (buttonValue == HIGH) {
playcomplete(file);
}
digitalWrite (ledPin, LOW); // must be outside the f to turn led OFF
}
}
/////////////////////////////////// HELPERS
/*
* print error message and halt
*/
void error_P(const char *str) {
PgmPrint("Error: ");
SerialPrint_P(str);
sdErrorCheck();
while(1);
}
/*
* print error message and halt if SD I/O error, great for debugging!
*/
void sdErrorCheck(void) {
if (!card.errorCode()) return;
PgmPrint("\r\nSD I/O error: ");
Serial.print(card.errorCode(), HEX);
PgmPrint(", ");
Serial.println(card.errorData(), HEX);
while(1);
}
int16_t lastpotval = 0;
#define HYSTERESIS 3
/*
* play file with sample rate changes
*/
void playcomplete(FatReader &file) {
int16_t potval;
uint32_t newsamplerate;
if (!wave.create(file)) {
putstring_nl(" Not a valid WAV");
return;
}
wave.play();
if (wave.isplaying) {
digitalWrite(ledPin, HIGH);
}
while (wave.isplaying) {
potval = analogRead(0);
if ( ((potval - lastpotval) > HYSTERESIS) || ((lastpotval - potval) > HYSTERESIS)) {
putstring("pot = ");
Serial.println(potval, DEC);
putstring("tickspersam = ");
Serial.print(wave.dwSamplesPerSec, DEC);
putstring(" -> ");
newsamplerate = wave.dwSamplesPerSec;
newsamplerate *= potval;
newsamplerate /= 512; // we want to 'split' between sped up and slowed down.
if (newsamplerate > 24000) {
newsamplerate = 24000;
}
if (newsamplerate < 1000) {
newsamplerate = 1000;
}
wave.setSampleRate(newsamplerate);
Serial.println(newsamplerate, DEC);
lastpotval = potval;
}
delay(10);
}
sdErrorCheck();
file.close();
}
Third Part:
Adjust the guts to the design of your enclosure. Drill holes accordingly. Because I am using a small speaker, I can power the whole thing off of a 9V battery which just makes it easier to install as power source is a consistent issue.
Here is a link to working documentation:
https://vimeo.com/66703542