Sound playback issues

Sound is working!!! I can get input and output...

I'm now trying to somehow play with sound. I want to create the "parrot game" ie. record and playback sound. The main problem I'm facing is that the Atmega8 has only 1K RAM (and 512 bytes EEPROM). For human voice, we need at least 6kHz ie. 6000 samples/second. Let's say I don't want to use EEPROM and I have 1k memory available, this means that I can record up to...

  • 1/6 second @ 8 bits
  • 1/3 second @ 4 bits
  • 1 1/3 second @ 1 bit (I found this nice method to encode sound at 1 bit)

... that looks pretty bad, even for 1 bit encoding.

Another way of dealing with it is maybe to model the sound. For instance, by estimating the fundamental frequency. There is a discussion on how to do that, but most of the methods aren't implemented and look kind of tough.

This paper proposes a fast algorithm to not only detect the fundamental frequency, but also distinguish between voice/unvoice. It is, however, difficult to understand for a neophyte.

Comments

Interpolation and downsampling

An interesting way to compress audio data is to downsample it. According to Shannon-Nyquist sampling theory, the sampling rate must simply be more than 2 times the bandwidth of a signal.

Human voice being around 200Hz-2000Hz, means that iot approximate it well we would need to sample approx. 3.6kHz (maybe less if we allow ourselves to cut it up at 1000-1200Hz for instance).

We could then use linear interpolation, but this is known to introduce aliasing. A better method is to use the Band-limited interpolation algorithm, explained here.

It would still not be so good however. Let's say we opt to get a bandwidth of 200Hz-1000Hz, it means we must sample at 1.6kHz. If we use 8 bits, with 1000bits memory we can record up to 0.625 sec., with 4 bits it's 1.25 and with 1 bit it's 5 seconds.

So to be a bit conservative, let's say max. 4 seconds but that would involve a lot of programming just to do that. So let's keep that in mind for a later improvement, but for now it would be better to concentrate on something much simpler.

tats

Square wave reaction

I've tried yet another very simple idea to start working with what is really at stake here: sound reaction.

When the sound goes higher than a certain threshold, the object reacts by playing a square wave sound that raises. Sounds like a video game!!!

Basically, I'm thinking about a very simple idea. Suppose that the actions available to the device are very simple choice of frequency/time pair ie. here, calls to the playSquare(int,int) function. These choices could then be combined with a reinforcment learning algorithm such as SARSA. It would be funny to try it out!!!


#define AUDIO_INPUT 0
#define AUDIO_OUTPUT 9

#define DEBUG 1

int audioIn;

void setup() {
pinMode(AUDIO_INPUT, INPUT);
pinMode(AUDIO_OUTPUT, OUTPUT);
TCCR1A = 1;
TCCR1B = 9;
#if DEBUG
Serial.begin(19200);
#endif
}

long THRESHOLD2 = square(200);

void loop() {
long mse;
audioIn = analogRead(AUDIO_INPUT);
mse = square(audioIn - 511);
#if DEBUG
Serial.println("Audio in, mse");
Serial.println(audioIn);
Serial.println(mse);
#endif
if (mse > THRESHOLD2)
{
#if DEBUG
Serial.println("Sound!!!");
#endif
playSquare(440, 100);
for (int i=0; i<100; i++)
playSquare(440+i, 100);
}
}

long square(long x) {
return x*x;
}

void playSquare(int freq, int t)
{
int hperiod; //calculate 1/2 period in us
long cycles, i;
hperiod = (500000 / freq) - 7; // subtract 7 us to make up for digitalWrite overhead - determined empirically
// calculate cycles
cycles = ((long)freq * (long)t) / 1000; // calculate cycles

for (i=0; i<= cycles; i++){ // play note for t ms
digitalWrite(AUDIO_OUTPUT, HIGH);
delayMicroseconds(hperiod);
digitalWrite(AUDIO_OUTPUT, LOW);
delayMicroseconds(hperiod - 1); // - 1 to make up for fractional microsecond in digitaWrite overhead
}
}

tats

Forget it?

One way to deal with it would also be to just forget about it and rely instead on more simple sound synthesis. What is at stake after all with this "parrot game" is more a way to interact, but it's just one way after all.

tats