Go Down

Topic: A bunch of questions about playback sampled sounds (Read 9211 times) previous topic - next topic

Grumpy_Mike

Quote
What if I messed up the Timer 0 and set it faster?
You should not be playing with Timer 0.

Grumpy_Mike

Also in your code you have:-
Code: [Select]
delayMicroseconds(3968);
Assuming that is the only delay this means you are working on a sample rate of 252 Hz, I thought your samples were at 16KHz? It is no wonder you here nothing.

Grumpy_Mike

#32
Feb 10, 2016, 12:43 am Last Edit: Feb 10, 2016, 12:47 am by Grumpy_Mike
Basically the only thing right about that code was the setting of the PWM frequency.
You were using the wrong pin, I have changed it to pin 9.
You had the wrong delay value - I changed that.
You had the for loop wrong like AWOL tried to tell you.
But most of all you were reading the program memory incorrectly.

I think he is saying "my life for iera" although not ever watching films it means nothing to me.

Mended code attached.

Lucario448

Man... I'm so excited that I don't know how to thank you, for the patience, and all the help.
I CAN FINALLY LISTEN MY SOUND YAAAAAAAAAAY!!!

Basically the only thing right about that code was the setting of the PWM frequency.
You were using the wrong pin, I have changed it to pin 9.
You had the wrong delay value - I changed that.
You had the for loop wrong like AWOL tried to tell you.
But most of all you were reading the program memory incorrectly.
  • (First line): And I thought that the board doesn't executed the function.
  • So, isn't necessary at all to have a very fast PWM?
  • Yeah I know. The actual delayMicroseconds should be of 62, not 50 (hence the sound has a slightly higher pitch that expected)
  • Exactly why? Because the variable i hasn't initialized from the beginning or what else?
  • So. The freaking problem all this time... WAS ONLY A MISPLACED MEMORY POINTER!!!??? Oh well...  :o


Quote
I think he is saying "my life for iera" although not ever watching films it means nothing to me.
Actually, my sound says "My life for Aiur!". It appears in a "old-school" PC game called "StarCraft".

And I think that's it. I'm satisfied right now.
In a future, I wanna do that but with a complete song, but first I need my SD card module of course.


PD:
  • My low-pass filter worked fine all this time then.
  • Seriously, thank you very much!
  • Now I'm gonna play around with different sounds at different sample rates...

Grumpy_Mike

Quote
So, isn't necessary at all to have a very fast PWM?
The faster the better but it needs to be at least twice as faster than the sample rate. As the sample rate is 16KHz that puts it at 32KHz. Having it faster makes it easier to filter out with a simple filter like you are using but as the PWM is way over the hearing frequency limit it is not so important. However such a strong out of band signal could screw up the electronics in the audio amplifier so it is best to leave it in. For the tests I just used a high impedance "ear bud" touched onto the pin directly.

Quote
The actual delayMicroseconds should be of 62, not 50
Only 62 if the for loop overhead, writing to the A/D, and fetching the sample byte from program memory takes zero time. I was trying it slightly shorter to compensate for these.

Quote
Exactly why? Because the variable i hasn't initialized from the beginning
Basically yes, also the short variable type, while part of C is not used much in this world.

Quote
It appears in a "old-school" PC game called "StarCraft".
Never had a PC so I wouldn't know.


Lucario448

However such a strong out of band signal could screw up the electronics in the audio amplifier so it is best to leave it in. For the tests I just used a high impedance "ear bud" touched onto the pin directly.
So my earbuds have lower impedance? Because I could barely hear my sound without using my LM386-based amplifier (which comes in handy because I can power it from the 5V pin of my board). Also, I think you mean for long periods of time, right? Using an amplifier for this purpose for a half of a minute doesn't destroy anything, or does it?

Quote
Only 62 if the for loop overhead, writing to the A/D, and fetching the sample byte from program memory takes zero time. I was trying it slightly shorter to compensate for these.
I noticed that the analogWrite function (plus the pgm_read_byte and the for testing condition) takes around 9 microseconds to execute (in a 16 MHz clock rate); thus at 62, the sound got a lower pitch than expected. In my "trial and error" testing, the value used to make it sound as it's supposed to, was 53 (and that's how I deducted how long takes that functions to execute, is that right or I'm wrong?)

Quote
Basically yes, also the short variable type, while part of C is not used much in this world.
So, for a "good programming practice", should I keep using int type variables for looping statements?

Quote
Never had a PC so I wouldn't know.
Well, now you know it haha.

Grumpy_Mike

#36
Feb 10, 2016, 05:40 pm Last Edit: Feb 10, 2016, 05:41 pm by Grumpy_Mike
Quote
(and that's how I deducted how long takes that functions to execute, is that right or I'm wrong?
It is as good a technique as you can use in the circumstances. The delayMicroseconds call is only accurate to 4uS anyway so the technique is not very good for precise reproduction of a sample. For that you need to set another timer going (not timer 0 ) so that it generates an interrupt at exactly the sample frequency. Then the interrupt service routine does the fetches and loading of the PWM register. This means that you can do other stuff while the sample is playing, like LED animation or looking for a button press to set the sample going again. Like n.n.n.nineteen, that song from Paul Hardcastle.

Quote
So, for a "good programming practice", should I keep using int type variables for looping statements?
Yes if an int is big enough, you could use a byte, or a long, but always initialise the loop variable. It could start off with junk in it.

Quote
So my earbuds have lower impedance? Because I could barely hear my sound without using .....
Looks like it. These were the cheapest in a cheap shop I visited when I went to New York for the 2011 Maker fair, I don't have to put them in my ear to here the sound. ( Note I live in the UK so a visit to NY was a big deal for me )

Lucario448

For that you need to set another timer going (not timer 0 ) so that it generates an interrupt at exactly the sample frequency. Then the interrupt service routine does the fetches and loading of the PWM register. This means that you can do other stuff while the sample is playing, like LED animation or looking for a button press to set the sample going again. Like n.n.n.nineteen, that song from Paul Hardcastle.
So do you mean that the process of fetching a byte from the flash memory to the PWM register will not disrupt the sampling rate? Sweet! I wanna learn more about that, because it would be a useful knowledge for another project, like sensing the push of a button while playing an animation for a RGB LED strip (but not those that I can control each LED individually). Is that like simulating a multi-threaded (aka multi-task) process from a single-core CPU? 

Quote
Yes if an int is big enough, you could use a byte, or a long, but always initialise the loop variable. It could start off with junk in it.
Lesson learned!

Quote
Looks like it. These were the cheapest in a cheap shop I visited when I went to New York for the 2011 Maker fair, I don't have to put them in my ear to here the sound.
Are there one of those on Amazon, eBay or whatever? Or at least the brand and model name.
If that sensitive are those, I guess they can pick up the weak signal of a dynamic microphone without any sort of amplification.

Grumpy_Mike

Quote
Is that like simulating a multi-threaded (aka multi-task) process from a single-core CPU?
Yes that is called a state machine.

See my
http://www.thebox.myzen.co.uk/Tutorial/State_Machine.html
Or Robin2's several things at once
http://forum.arduino.cc/index.php?topic=223286.0

Quote
like sensing the push of a button while playing an animation for a RGB LED strip
Yes. Have you seen this project of mine?
http://youtu.be/pL0pMAPkkVw
The animated face is made by sampling the envelope of the sound output and using the number to control what size mouth to display.

Quote
I guess they can pick up the weak signal of a dynamic microphone without any sort of amplification.
No I just tried it. I could barely see the signal when I whistle as loud as I can into the ear bud. It gives about 20mV. It says Panasonic on them but given the price and where I got it from it is almost certainly fake.

Lucario448

Yes that is called a state machine.
I got the point, but I'm confused in one thing. Why before you used the word "interrupt" if none of those tutorials used it?
They mostly used the millis function instead. So how that will improve the timing of my sound player?. Remember, the delay is in Microseconds, not milliseconds.

Quote
No I just tried it. I could barely see the signal when I whistle as loud as I can into the ear bud. It gives about 20mV. It says Panasonic on them but given the price and where I got it from it is almost certainly fake.
Ohhh that's a shame :/
If it is difficult to find one online, then would you mind if you suggest me an amplifier? (I know you already did it, but just keep reading)
I have in mind one that is small, easy to power-up, low consumption, stereo, cheap enough in case of unintentionally destroying it, and the most important: a lot less noisier than a LM386-based one.


Thanks beforehand!

Grumpy_Mike

#40
Feb 12, 2016, 06:18 am Last Edit: Feb 12, 2016, 06:19 am by Grumpy_Mike
The reason you use an interrupt is so the task, which in this case is outputting the next sample, can be done at precisely the right moment. Because there is such a small interval between fetches then polling to see if the time is right is not only inefficient but does not give you fine enough control. The microseconds timer only gets updated every four microsecond for a start and then the other task or tasks in the Sate machine have to be completed in under the time between samples, which puts a lot of limitations on them. For example it means you can't do an analogRead while playing a sample without disturbing the timing.

By using an interrupt any other task gets suspended and your sample is changed on time. I would not say that non of the tutorials use this technique but as I said at the start of the thread there is a lot of crap out there. And an Instructables url is one way you can spot crap.

Lucario448

Correct me if I'm wrong. Do you mean that many mandatory functions inevitably consume a significant amount of time and it's impossible to achieve a 100% perfect timing? Well... at least is comprehensible that even delayMicroseconds is accurate enough, but not perfect (I guess due to clock rate).

Good tutorials though.

Grumpy_Mike

Quote
Do you mean that many mandatory functions inevitably consume a significant amount of time and it's impossible to achieve a 100% perfect timing?
Yes. And that is with a task that contains only the one instruction, you will have to insure that all your tasks complete in significantly shorter time than the sample rate. Even then there will be a jitter of a time period equal to the length of your longest task. Using a delay is just a "baby" stop gap used as a demonstration or where you don't want to do anything else while a sound is playing.

Quote
at least is comprehensible that even delayMicroseconds is accurate enough
Any delay is blocking so your processor can not do anything else while it is waiting. A jitter of 4uS might not be noticeable at the low quality you have at the moment but it will soon show up as noise on your output. Remember 4uS equates to 64 clock cycles, about the same time as a digital write function call.

Lucario448

And that is with a task that contains only the one instruction, you will have to insure that all your tasks complete in significantly shorter time than the sample rate. Even then there will be a jitter of a time period equal to the length of your longest task.
Now I understand your point even better. You mean that I have a kind of "time budget" to do other things without compromising the sample rate, right?
If so, then I just have 53 microseconds to do other stuff (the time I'm "wasting" in a delay, in order to provide to the runtime a "time gap").
Is that enough time to do a AnalogRead and map functions? Because I wanna give to my current player a new feature: adjust the pitch (and speed along the way) with a potentiometer. Yeah, I had that crazy idea in my head since yesterday. It sounds like a something called "circuit bending"...

Quote
A jitter of 4uS might not be noticeable at the low quality you have at the moment but it will soon show up as noise on your output.
What kind of noise? A "waveform glitch" or something worse enough to blow off an amplifier?

CrossRoads

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up