Audio Library

Status
Not open for further replies.
I've uploaded a new version of the flash code to:
http://members.shaw.ca/el_supremo/flash_a.zip

The sketch which records from line-in does not erase the chip now. It appends the new recording onto the end of whatever is already in the chip. There is a separate sketch which erases the chip.

I hope I haven't missed anything in the new zip file.
Have fun.

Pete
 
For the last couple weeks, I've been prepping for Maker Faire. The booth will be about the audio library. Sadly, that's meant a lot of work here on making the already-made demos into sturdy stuff that can (hopefully) survive a weekend of kids and adults playing on them.

I'm hoping to make a sound record & play demo with Pete's code, which I'll merge into the library soon in object oriented format.

Sadly, getting ready means working on a lot of stuff that isn't coding. Yesterday I made the signs we'll have in the booth. If you're at Maker Faire in 2 weeks, here's what you'll see hanging on the back side of the booth.

mk2014_poster1.jpg mk2014_poster2.jpg mk2014_poster3.jpg
 
I have changed a few things in the flash code and uploaded a new version.
http://members.shaw.ca/el_supremo/flash_b.zip

- the functions which write/erase the chip now set a flag to indicate that a write is in progress but return immediately to the caller to permit processing to be overlapped with I/O. All functions (with two exceptions) check the flag before they do their I/O and if the flag is set they wait for the Write-In-Progress to finish before they do their thing.The write_pause() function is used to check the flag and wait if necessary. I am now getting glitch-free recordings with this feature added.

- The chip erase function uses the write in progress flag, as mentioned above, but the user now specifies a boolean "wait" flag argument to indicate whether the function should wait for the write to terminate before returning to the user. This is the only function which has this feature because it takes so long that you can't do much else anyway. If the "wait" argument is false the function sets the write in progress flag and returns immediately. If the "wait" argument is true the function waits for the erase to finish before returning.

- record_flash_wav has been modified so that it terminates recording at page 65534. This allows the recording sketches to use page 65535 as a filename.

- the record_flash_linein function records for a specified amount of time. If the flash is filled before the time expires the sketch wasn't terminating, but now it also checks that recording is still in progress.
NOTE that there are various other ways that recording can be controlled. For example, instead of recording for a specified period of time, the recording could be terminated when a button is pushed. I'm leaving this as an exercise for the reader :)

- the relevant *.md files and example sketches have been updated.


@Paul: This will be my last major update to this code so that you don't have a "moving target" while you convert it to OO format. I would do the conversion myself except that I don't have the necessary experience with OO and C++. If you have any questions, gimme a yell.

Pete
 
@Paul: BTW I wrote a sketch which should record some audio and then play it back but the sketch hangs when it starts up. I presume there's some sort of initialization problem in the audio library but can't figure out where it is occurring.

Pete
 
This will be my last major update to this code so that you don't have a "moving target" while you convert it to OO format. I would do the conversion myself except that I don't have the necessary experience with OO and C++.

I'm planning to work on this in a few days, and use it in one of the Maker Faire demos if time permits.

If anything goes off schedule here, this might slip until after Maker Faire, but either way I'm definitely going to integrate this into the library.

I really appreciate all your hard work on this. :)
 
I can't figure out what is causing the glitches during a recording and I wouldn't like it to glitch in a public demo! Sometimes I can record 95 seconds of pristine glitch-free audio and other times it will have glitches scattered throughout the recording.

Pete
 
Hello together,
I'm playing with the audio shield and the FFT example and I have a Question.
I connected my smartphone to the line in and I get the FFT and when I have direct access to the output the values are so little. Especially with high tones this is a problem like you can see in the picture.
I thought the values are: "Direct access to the raw FFT data is possible with this array. Values range from 0 to 32767. " What I am doing wrong? (I have the maximum Volume on my phone...)
Here you can see the first 64 Outputs of the FFT.
FFT.jpg
Thanks
 
For the last couple weeks, I've been prepping for Maker Faire. The booth will be about the audio library. Sadly, that's meant a lot of work here on making the already-made demos into sturdy stuff that can (hopefully) survive a weekend of kids and adults playing on them.

I'm hoping to make a sound record & play demo with Pete's code, which I'll merge into the library soon in object oriented format.

Sadly, getting ready means working on a lot of stuff that isn't coding. Yesterday I made the signs we'll have in the booth. If you're at Maker Faire in 2 weeks, here's what you'll see hanging on the back side of the booth.

View attachment 1914 View attachment 1915 View attachment 1916


Paul, these look really really good - simple but effective ...
 
What I don't get of the audio library is the AudioMemory function that is used in the examples.
From the name I guess it has something to do with memory, but what is the number for?
It is preceded by a comment that for usage I should look into the MemoryAndCpuUsage example, but I can't find it.
 
One of my early examples does not compile anymore - looks like something changed in the audio library ...

/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp: In member function 'void AudioOutputAnalog::begin()':
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:56:2: error: 'DMA_TCD4_SADDR' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:57:2: error: 'DMA_TCD4_SOFF' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:58:2: error: 'DMA_TCD4_ATTR' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:59:2: error: 'DMA_TCD4_NBYTES_MLNO' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:60:2: error: 'DMA_TCD4_SLAST' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:61:2: error: 'DMA_TCD4_DADDR' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:62:2: error: 'DMA_TCD4_DOFF' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:63:2: error: 'DMA_TCD4_CITER_ELINKNO' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:64:2: error: 'DMA_TCD4_DLASTSGA' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:65:2: error: 'DMA_TCD4_BITER_ELINKNO' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:66:2: error: 'DMA_TCD4_CSR' was not declared in this scope
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp: In function 'void dma_ch4_isr()':
/Users/ALFA/Documents/Arduino/libraries/Audio/output_dac.cpp:117:20: error: 'DMA_TCD4_SADDR' was not declared in this scope

This example compiled fine with an older version....
Can please somebody point me in the right direction ?
Thanks much !

This is the example



#include <Audio.h>
#include <Wire.h>
#include <SD.h>

// Create the Audio components. These should be created in the
// order data flows, inputs/sources -> processing -> outputs
AudioSynthWaveformSine mysine;
AudioOutputI2S audioOutput; // audio shield: headphones & line-out

// Create Audio connections between the components

AudioConnection c1(mysine, 0, audioOutput,0);
AudioConnection c2(mysine, 1, audioOutput, 1);

// Create an object to control the audio shield.
//
AudioControlSGTL5000 audioShield;

int volume = 0;

void setup() {

// Serial.println("Begin AudioTest");
// Audio connections require memory to work. For more
// detailed information, see he MemoryAndCpuUsage example
AudioMemory(15);

audioShield.enable();
audioShield.volume(70);

//Serial.println("setup done");

mysine.frequency(440);
mysine.amplitude(0.1);
}


void loop() {

}
 
Figured it out - was working on another computer with an older version of Teensyduino .... thanks
 
Hi everyone,

I would be very glad, if someone could tell me why this code is not working. I'm working with the Teensy 3.1, the audio shield and the latest audio library. The teensy just crashes and does nothing at all if I upload this code. I lokated the problem (or at least a way to make it work) at the line, where the audio connection from the "audioInput" to the first channel of the "mixSources"-mixer is made. If I delete this line everything works fine. The problem is, I defenetly need the audio Input! :)

Thanks already a lot for every helpful advice.

Luke

Code:
#include <Audio.h>
#include <Wire.h>
#include <stdio.h>
#include <SPI.h>
#include <SD.h>

#include <Metro.h>
#include "Tone.h"

//___________________________________________________________________________________
/////////////////////////
//AUDIO CONFIGURATION

int ToneFilter1[]={0,0,0,0,0,0,0};
int ToneFilter2[]={0,0,0,0,0,0,0};
int ToneFilter3[]={0,0,0,0,0,0,0};

int updateFilter[5];

//const int myInput = AUDIO_INPUT_LINEIN;
const int myInput = AUDIO_INPUT_MIC;

AudioInputI2S       audioInput;  // audio shield: mic or line-in 

AudioSynthWaveform 	osc1;
AudioSynthWaveform 	osc2;
AudioSynthWaveform	osc3;

AudioMixer4			mixSources;

AudioFilterBiquad    formantFilter1(ToneFilter1);
AudioFilterBiquad    formantFilter2(ToneFilter2);
AudioFilterBiquad    formantFilter3(ToneFilter3);

AudioMixer4        mixFormants;
AudioOutputI2S      audioOutput;        // audio shield: headphones & line-out

// Create Audio connections between the components

AudioConnection c1(audioInput, 0, mixSources, 0);  // ************* this line causes the problem ****************

AudioConnection c2(osc1, 0, mixSources, 1);
AudioConnection c3(osc2, 0, mixSources, 2);
AudioConnection c4(osc3, 0, mixSources, 3);

AudioConnection c5(mixSources, 0, formantFilter1, 0);
AudioConnection c6(mixSources, 0, formantFilter2, 0);
AudioConnection c7(mixSources, 0, formantFilter3, 0);

AudioConnection c8(mixSources, 0, mixFormants, 0);
AudioConnection c9(formantFilter1, 0, mixFormants, 1);
AudioConnection c10(formantFilter2, 0, mixFormants, 2);
AudioConnection c11(formantFilter3, 0, mixFormants, 3);

AudioConnection c12(mixFormants, 0, audioOutput, 0);

AudioControlSGTL5000 audioShield;

// sopran a
void setSopranA() {
	// calcBiquad(FilterType,FrequencyC,dBgain,BW,QuantizationUnit,SampleRate,int*);
	calcBiquad(FILTER_BANDPASS,800,0,0,0.5,2147483648,44100,updateFilter);
	formantFilter1.updateCoefs(updateFilter);
	calcBiquad(FILTER_BANDPASS,1150,-6,0,0.4,2147483648,44100,updateFilter);
	formantFilter2.updateCoefs(updateFilter);
	calcBiquad(FILTER_BANDPASS,2900,-32,0,0.3,2147483648,44100,updateFilter);
	formantFilter3.updateCoefs(updateFilter);	
}


//___________________________________________________________________________________
void setup() 
{

  Serial.begin(57600);
  
    //___________________________________________________________________________________
  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  
	AudioMemory(15);

	audioShield.enable();
	audioShield.inputSelect(myInput);
	audioShield.volume(90);
	
	mixFormants.gain(0, 0.0001);
	mixFormants.gain(1, 0.5);
	mixFormants.gain(2, 0.5);
	mixFormants.gain(3, 0.5);
	
	mixSources.gain(0, 0.3);
	mixSources.gain(1, 0.3);
	mixSources.gain(2, 0.3);
	mixSources.gain(3, 0.3);
	
	
	osc1.set_ramp_length(88);
	osc2.set_ramp_length(88);
	osc3.set_ramp_length(88);
	
	osc1.amplitude(0);
	osc2.amplitude(0);
	osc3.amplitude(0);
	
	osc1.begin(0.1,tune_frequencies2_PGM[30], TONE_TYPE_SQUARE);
	osc2.begin(0.1,tune_frequencies2_PGM[37], TONE_TYPE_SQUARE);
	osc3.begin(0.1,tune_frequencies2_PGM[44], TONE_TYPE_SQUARE);
	
	setSopranA();
	
	Serial.println("audio setup done");
}

//___________________________________________________________

//Metros

Metro MonitorMetro = Metro(1000);
Metro VolMetro = Metro(10);

// audio volume
int mainVolume = 0;
int oldValue = 0;



void loop() {

  //___________________________________________________________________________________
  //AUDIO
  // volume control
  // every 10 ms, check for adjustment
  // volume control
  
	// every 10 ms, check for adjustment
	if (VolMetro.check() == 1) {
		int n = analogRead(15);
		if (n != mainVolume) {
			mainVolume = n;
			audioShield.volume((float)n / 10.23);
		}
	}
	
  //////////////////
  //Mem and CPU Usage

  /*
  For PlaySynthMusic this produces:
   Proc = 20 (21),  Mem = 2 (8)
   */
  if (MonitorMetro.check() == 1) {
    Serial.print("Proc = ");
    Serial.print(AudioProcessorUsage());
    Serial.print(" (");    
    Serial.print(AudioProcessorUsageMax());
    Serial.print("),  Mem = ");
    Serial.print(AudioMemoryUsage());
    Serial.print(" (");    
    Serial.print(AudioMemoryUsageMax());
    Serial.println(")");
  }
}
 
It starts up if I move AudioMemory(15) after audioShield.enable();
I also had to fix the calls to calcBiquad because there's one too many arguments in them.
e.g. change the first one to:
Code:
	calcBiquad(FILTER_BANDPASS,800,0,0.5,2147483648,44100,updateFilter);

Pete
 
Oh yea, I forgot to revert my modification of the biquads calculation. I've changed them a little in the library and added an overal gain.

But also with the reverted modification and the modification you mentioned (AudioMemory(15) after audioShield.enable()), it's not working. The only difference is, that the theensy now plays a single tone. But it is defenetly crashed, because not respondig on serial communication.
So, to be shure, this is the code you meant?

Code:
#include <Audio.h>
#include <Wire.h>
#include <stdio.h>
#include <SPI.h>
#include <SD.h>

#include <Metro.h>
#include "Tone.h"

//___________________________________________________________________________________
/////////////////////////
//AUDIO CONFIGURATION

int ToneFilter1[]={0,0,0,0,0,0,0};
int ToneFilter2[]={0,0,0,0,0,0,0};
int ToneFilter3[]={0,0,0,0,0,0,0};

int updateFilter[5];

//const int myInput = AUDIO_INPUT_LINEIN;
const int myInput = AUDIO_INPUT_MIC;

AudioInputI2S       audioInput;  // audio shield: mic or line-in 

AudioSynthWaveform 	osc1;
AudioSynthWaveform 	osc2;
AudioSynthWaveform	osc3;


AudioMixer4			mixSources;

AudioFilterBiquad    formantFilter1(ToneFilter1);
AudioFilterBiquad    formantFilter2(ToneFilter2);
AudioFilterBiquad    formantFilter3(ToneFilter3);

AudioMixer4        mixFormants;
AudioOutputI2S      audioOutput;        // audio shield: headphones & line-out

// Create Audio connections between the components

AudioConnection c1(audioInput, 0, mixSources, 0);

AudioConnection c2(osc1, 0, mixSources, 1);
AudioConnection c3(osc2, 0, mixSources, 2);
AudioConnection c4(osc3, 0, mixSources, 3);

AudioConnection c5(mixSources, 0, formantFilter1, 0);
AudioConnection c6(mixSources, 0, formantFilter2, 0);
AudioConnection c7(mixSources, 0, formantFilter3, 0);

AudioConnection c8(mixSources, 0, mixFormants, 0);
AudioConnection c9(formantFilter1, 0, mixFormants, 1);
AudioConnection c10(formantFilter2, 0, mixFormants, 2);
AudioConnection c11(formantFilter3, 0, mixFormants, 3);

AudioConnection c12(mixFormants, 0, audioOutput, 0);

AudioControlSGTL5000 audioShield;

// sopran a
void setSopranA() {
	// calcBiquad(FilterType,FrequencyC,dBgain,BW,QuantizationUnit,SampleRate,int*);
	calcBiquad(FILTER_BANDPASS,800,0,0.5,2147483648,44100,updateFilter);
	formantFilter1.updateCoefs(updateFilter);
	calcBiquad(FILTER_BANDPASS,1150,0,0.4,2147483648,44100,updateFilter);
	formantFilter2.updateCoefs(updateFilter);
	calcBiquad(FILTER_BANDPASS,2900,0,0.3,2147483648,44100,updateFilter);
	formantFilter3.updateCoefs(updateFilter);	
}


//___________________________________________________________________________________
void setup() 
{

  Serial.begin(57600);
  
    //___________________________________________________________________________________
  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
	
	audioShield.enable();

	AudioMemory(15); // ************ just changed the order of audioShield.enable() and AudioMemory(15) ***********
	
	audioShield.inputSelect(myInput);
	audioShield.volume(90);
	
	mixFormants.gain(0, 0.0001);
	mixFormants.gain(1, 0.5);
	mixFormants.gain(2, 0.5);
	mixFormants.gain(3, 0.5);
	
	mixSources.gain(0, 0.3);
	mixSources.gain(1, 0.3);
	mixSources.gain(2, 0.3);
	mixSources.gain(3, 0.3);
	
	
	osc1.set_ramp_length(88);
	osc2.set_ramp_length(88);
	osc3.set_ramp_length(88);
	
	osc1.amplitude(0);
	osc2.amplitude(0);
	osc3.amplitude(0);
	
	osc1.begin(0.1,tune_frequencies2_PGM[30], TONE_TYPE_SQUARE);
	osc2.begin(0.1,tune_frequencies2_PGM[37], TONE_TYPE_SQUARE);
	osc3.begin(0.1,tune_frequencies2_PGM[44], TONE_TYPE_SQUARE);
	
	setSopranA();
	
	Serial.println("audio setup done");
}

//___________________________________________________________

//Metros

Metro MonitorMetro = Metro(1000);
Metro VolMetro = Metro(10);

// audio volume
int mainVolume = 0;
int oldValue = 0;



void loop() {

  //___________________________________________________________________________________
  //AUDIO
  // volume control
  // every 10 ms, check for adjustment
  // volume control
  
	// every 10 ms, check for adjustment
	if (VolMetro.check() == 1) {
		int n = analogRead(15);
		if (n != mainVolume) {
			mainVolume = n;
			audioShield.volume((float)n / 10.23);
		}
	}
	
  //////////////////
  //Mem and CPU Usage

  /*
  For PlaySynthMusic this produces:
   Proc = 20 (21),  Mem = 2 (8)
   */
  if (MonitorMetro.check() == 1) {
    Serial.print("Proc = ");
    Serial.print(AudioProcessorUsage());
    Serial.print(" (");    
    Serial.print(AudioProcessorUsageMax());
    Serial.print("),  Mem = ");
    Serial.print(AudioMemoryUsage());
    Serial.print(" (");    
    Serial.print(AudioMemoryUsageMax());
    Serial.println(")");
  }
}
 
Not quite. I had to remove VolMetro
Code:
//	if (VolMetro.check() == 1) {
		int n = analogRead(15);
		if (n != mainVolume) {
			mainVolume = n;
			audioShield.volume((float)n / 10.23);
		}
//	}

Pete
 
And I had to make two other changes (note that I am using the current version of the Audio library from Paul's github site)
Code:
	audioShield.volume(.9);

and I had to change the volume control a bit more
Code:
//  if (VolMetro.check() == 1) {
    int n = analogRead(15);
    if (n != mainVolume) {
      mainVolume = n;
      audioShield.volume(n / 1023.);
    }
//  }

If you're using an older version of the Audio Library you may not need either of these fixes.

Pete
 
Do you know why it's not working with the metro?

In fact, I have a little more complex code I'm working on. There are a few more metros, they are trigering some modulation sequences. And I had also always to do strange modifications to make it work. But I never understood why. So I thought there have to be a problem somehow deeper. And I thougth I could locate it at the AudioInput-connection.

I would be very happy to understand the problem a little deeper.

Luke
 
I have changed a few things in the flash code and uploaded a new version.
http://members.shaw.ca/el_supremo/flash_b.zip

Thanks for those developments... look useful... I'll check them out.

I have an issue with the previous version of the record_flash_linein example you may be able to advise on...

It seems to be with the AudioMixer4 object...

I've adapted the demo sketch to play the wav file once it's been written to the SD on a button press...

If I uncomment the #define MIX_TO_MONO I no longer hear the wav file... just a click and then nothing... it's works without.

I've tried to route the wav through the mixer to the audioOutput in this case... but it's not working.

Any suggestions?

Prodical

My code below:

// Create the Audio components. These should be created in the
// order data flows, inputs/sources -> processing -> outputs
AudioInputI2S audioInput; // audio shield: mic or line-in
AudioPlaySdWav wav;
AudioRecordFlashWav recorder;

// If this is defined, mix the stereo signal to mono
// and record and save that.
//#define MIX_TO_MONO
#ifdef MIX_TO_MONO
AudioMixer4 mixer;
#endif

AudioOutputI2S audioOutput; // audio shield: headphones & line-out

// Mix left and right channels together for recording to the flash
#ifdef MIX_TO_MONO
AudioConnection c1l(audioInput, 0, mixer, 0);
AudioConnection c1r(audioInput, 1, mixer, 1);
AudioConnection c2(mixer, 0, recorder, 0);
#else
AudioConnection c2l(audioInput, 0, recorder, 0);
AudioConnection c2r(audioInput, 1, recorder, 1);
#endif

// Create Audio connections between the components
#ifdef MIX_TO_MONO
AudioConnection c3l(wav, 0, mixer, 3);
AudioConnection c3r(wav, 1, mixer, 4);
AudioConnection c4l(mixer, 3, audioOutput, 0);
AudioConnection c4r(mixer, 4, audioOutput, 1);
#else
AudioConnection c3l(wav, 0, audioOutput, 0);
AudioConnection c3r(wav, 1, audioOutput, 1);
#endif

AudioControlSGTL5000 audioShield;
 
@ Prodical:
I can't see anything wrong with your setup. I have an even more complicated one which records mono/stereo to the flash and writes it to uSD. Then it plays the recording from the flash and then plays it from the uSD so that I can check both.
I was having a problem with it earlier today but the problem wasn't with the objects that you are using.

Pete
 
This won't work with the mixer object.

AudioConnection c3l(wav, 0, mixer, 3);
AudioConnection c3r(wav, 1, mixer, 4);

It has 4 inputs, numbered 0 to 3, and one output, number 0. Connecting to "4" won't do anything, since 3 is the maximum.

To combine those 2 channels of the WAV file together, you probably should feed them into mixer inputs 2 and 3.

AudioConnection c4l(mixer, 3, audioOutput, 0);
AudioConnection c4r(mixer, 4, audioOutput, 1);

The mixer has a single output, which is the same of all 4 inputs. There are no outputs "3" and "4". You need to change those to "0".
 
96K sampling on Audio Adapter POC.

Basic proof of concept, for now.

To test SGTL5000 at 96KSps anyone so interested can try the following;


Add the following snippet of code to <arduino-root>/libraries/Audio/control_sgtl5000.cpp, I added it just after the existing ::enable(void) routine but anywhere sensible will do.
Code:
bool AudioControlSGTL5000::master96k(void)
{

	// set MCLK output up, use of Audio*putI2Sslave is called for.
	I2S0_MCR = I2S_MCR_MICS(3) | I2S_MCR_MOE;
	I2S0_MDR = I2S_MDR_FRACT(1) | I2S_MDR_DIVIDE(16); // 11293900Hz, measured by Tektronix TDS2022.
	
	delay(100); // give it a moment, it only just got an MCLK.

	muted = true;
	Wire.begin();
	delay(5);

	write(CHIP_ANA_POWER, 0x4060);  // VDDD is externally driven with 1.8V
	write(CHIP_LINREG_CTRL, 0x006C);  // VDDA & VDDIO both over 3.1V
	write(CHIP_REF_CTRL, 0x01F2); // VAG=1.575, normal ramp, +12.5% bias current
	write(CHIP_LINE_OUT_CTRL, 0x0322); // LO_VAGCNTRL=1.65V, OUT_CURRENT=0.36mA
	write(CHIP_SHORT_CTRL, 0x4446);  // allow up to 125mA
	write(CHIP_ANA_CTRL, 0x0137);  // enable zero cross detectors
	write(CHIP_ANA_POWER, 0x40FF); // power up: lineout, hp, adc, dac
	write(CHIP_DIG_POWER, 0x0073); // power up all digital stuff
	delay(400);
	write(CHIP_LINE_OUT_VOL, 0x1515); // default approx 2 volts peak-to-peak
	
	modify(CHIP_ANA_POWER,1<<10|1<<8,1<<10|1<<8); // turn on PLL and VCOAMP power
	modify(CHIP_CLK_TOP_CTRL,0,1); // MCLK<17000000
	write(CHIP_PLL_CTRL, 17<<11|836); // MCLK=11293900; INT_DIVISOR=17, FRAC_DIVISOR=836
	write(CHIP_CLK_CTRL, 3<<2|3); // Using PLL, sampling at 96K
	
	write(CHIP_PAD_STRENGTH,0x3FF);
	
	write(CHIP_I2S_CTRL, 0x01B0); // SCLK=32*Fs, SGTL5000 as Master, 16bit, I2S format
	// default signal routing is ok?
	write(CHIP_SSS_CTRL, 0x0010); // ADC->I2S, I2S->DAC
	write(CHIP_ADCDAC_CTRL, 0x0000); // disable dac mute
	write(CHIP_DAC_VOL, 0x3C3C); // digital gain, 0dB
	write(CHIP_ANA_HP_CTRL, 0x7F7F); // set volume (lowest level)
	write(CHIP_ANA_CTRL, 0x0136);  // enable zero cross detectors
	semi_automated = true;
	return true;

}
Then add the necessary line in <arduino-root>/libraries/Audio/control_sgtl5000.h (I include couple of lines above and one below, you don't have to put it exactly where I put it but it does want to be in the public section)
Code:
public:
	bool enable(void);
	[b]bool master96k(void);[/b]
	bool disable(void) { return false; }
Now you can try the following modification of the original StereoPeakMeter sketch
Code:
/* Stereo peak meter example, assumes Audio adapter but just uses terminal so no more parts required.

This example code is in the public domain
*/

#include <Audio.h>
#include <Wire.h>
#include <SD.h>

const int myInput = AUDIO_INPUT_LINEIN;
// const int myInput = AUDIO_INPUT_MIC;

AudioInputI2Sslave        audioInput;         // audio shield: mic or line-in
AudioPeak            peak_L;
AudioPeak            peak_R;
AudioOutputI2Sslave       audioOutput;        // audio shield: headphones & line-out

AudioConnection c1(audioInput,0,peak_L,0);
AudioConnection c2(audioInput,1,peak_R,0);
AudioConnection c3(audioInput,0,audioOutput,0);
AudioConnection c4(audioInput,1,audioOutput,1);

AudioControlSGTL5000 audioShield;


void setup() {
  AudioMemory(6);
  audioShield.master96k();
  audioShield.inputSelect(myInput);
  audioShield.volume(0.75);
  audioShield.unmuteLineout();
  Serial.begin(Serial.baud());
}

elapsedMillis fps;
uint8_t cnt=0;

void loop() {
  
  if(fps>24) { // for best effect make your terminal/monitor a minimum of 62 chars wide and as high as you can.
    Serial.println();
    fps=0;
    uint8_t leftPeak=peak_L.Dpp()/2184.5321; // 65536 / 2184.5321 ~ 30.
    for(cnt=0;cnt<30-leftPeak;cnt++) Serial.print(" ");
    while(cnt++<30) Serial.print("<");
    Serial.print("||");
    uint8_t rightPeak=peak_R.Dpp()/2184.5321;
    for(cnt=0;cnt<rightPeak;cnt++) Serial.print(">");
    while(cnt++<30) Serial.print(" ");
    peak_L.begin(); // no need to call .stop if all you want
    peak_R.begin(); // is to zero it.
  }
}

To verify that it is running at 96K you can probe BCLK to see >3Mhz and LRCLK to see (micro fraction below) 96KHz

The objects in the library which operate independently of the sample rate (eg., AudioPeak, AudioMixer4 & AudioFilterBiquad*) or which accept the current sample rate as an argument (eg., calcBiquad*) are naturally compatible with this sample rate. Objects which create samples, like AudioSynthWaveform, are not compatible but making them so shouldn't be very dramatic at all.
 
Last edited:
This won't work with the mixer object.



It has 4 inputs, numbered 0 to 3, and one output, number 0. Connecting to "4" won't do anything, since 3 is the maximum.

To combine those 2 channels of the WAV file together, you probably should feed them into mixer inputs 2 and 3.



The mixer has a single output, which is the same of all 4 inputs. There are no outputs "3" and "4". You need to change those to "0".

Thanks Paul... that explains it... the one output threw me... have I missed something obvious in the documentation?
 
I'm planning to work on this in a few days, and use it in one of the Maker Faire demos if time permits.

If anything goes off schedule here, this might slip until after Maker Faire, but either way I'm definitely going to integrate this into the library.

I really appreciate all your hard work on this. :)

Likewise...

Is an ETA on this still a couple of weeks or so off Paul? I've been using Pete's flash code... but it seems to make sense to hold off on more development of my personal project if Pete's work is going to be integrated into the audio library relatively soon.
 
Status
Not open for further replies.
Back
Top