{"id":385,"date":"2019-02-03T20:41:34","date_gmt":"2019-02-03T19:41:34","guid":{"rendered":"https:\/\/next-hack.com\/?p=385"},"modified":"2020-09-08T08:38:08","modified_gmt":"2020-09-08T06:38:08","slug":"how-to-play-a-video-on-arduino-uno-5-6-playing-a-16-bit-20ksps-audio-from-the-sd-card","status":"publish","type":"post","link":"https:\/\/next-hack.com\/index.php\/2019\/02\/03\/how-to-play-a-video-on-arduino-uno-5-6-playing-a-16-bit-20ksps-audio-from-the-sd-card\/","title":{"rendered":"How to play a video on Arduino Uno (5\/6): playing a 16 bit 20ksps audio from the SD card"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p>Hi there! <\/p>\n\n\n\n<p><a href=\"https:\/\/next-hack.com\/index.php\/2017\/08\/14\/how-to-play-a-video-on-arduino-uno-46-playing-a-20-fps-animation-from-sd-card\/\" target=\"_blank\" rel=\"noreferrer noopener\">Last time we finally managed to get the Arduino playing a 20 fps (or more) 16-bit per pixel 160&#215;128 video from an SD card.<\/a><\/p>\n\n\n\n<p>Is our\njourney finished? Of course not.&nbsp; We\npromised you a full audio+video, therefore two more steps are required.<\/p>\n\n\n\n<p>In this post we are going to show you how to play a 16-bit audio on the Arduino with very limited external components. In the last post we will modify the software so that you can play a file containing the audio and the video.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">File format<\/h3>\n\n\n\n<p>We will again use uncompressed data, for some reasons. <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>First, the computing power and the RAM of the ATMEGA328 are limited, so we must forget anything like MP3, unless we use an external dedicated MP3 decoder.<\/li><li> Second, we want each audio section with a constant size, which will simplify the data readout to the display. <\/li><li>Third, the amount of data required for audio playback at 20ksps is almost negligible with respect to the video. And if you stumbled across this post only to play an audio file from an SD, then you\u2019ll realize that in a 4-GB&nbsp; SD card you can store more than a DAY of continuous 16-bit mono audio data :). <\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Audio quality: sample rate\nand bits per sample.<\/h3>\n\n\n\n<p>There are\ntwo main parameters that determine the audio quality. The number of bits per\nsamples, and the actual sample rate. The first parameter determine the number\nof levels with which we can represent our audio.<\/p>\n\n\n\n<p>&nbsp;The second one represent how fast we can\ngenerate the samples. <\/p>\n\n\n\n<p>Both\nparameter determine the fidelity of the generated signal, in terms of dynamics\nand spectrum (frequency content).<\/p>\n\n\n\n<p>You can\nappreciate this with your ears:<\/p>\n\n\n\n<p><a href=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/sine_440Hz_3s-44k1sps-16bit.wav\">This is a high quality 440 Hz sinewave, with 44.1 ksps, 16 bit.<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/sine_440Hz_3s-4ksps-16bit.wav\">This is the same sine, sampled at 4ksps.<\/a> &nbsp;Since the sampling frequency is relatively high, and the bits per sample is still high, it\u2019s different to spot the difference!<\/p>\n\n\n\n<p><a href=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/sine_440Hz_3s-4ksps-8bit.wav\">This is the same sine, sampled at 4 ksps and quantized to 8 bit.<\/a> &nbsp;A good ear could spot the difference now.<\/p>\n\n\n\n<p><a href=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/sine_440Hz_3s-4ksps-4bit.wav\">This is the same sine wave, sampled at 4 ksps quantized at 4 bit.<\/a> Now, definitely anyone can tell the difference!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Producing the analog\noutput: the PWM<\/h3>\n\n\n\n<p>Since\nATMEGA328 has no DAC output, we will be forced to use PWM. A detailed analysis\nof PWM is outside the scope of this post, and we just briefly give an intuitive\ndescription.<\/p>\n\n\n\n<p>The main idea is that, instead of actually directly producing an analog voltage corresponding to the sample to be created, we can use a rectangular wave, whose duty cycle (i.e. the ratio between the total time the voltage is \u201chigh\u201d and the wave period) is proportional to the voltage we actually want to produce. Then we use a filter to take the average value, so we get the analog voltage value we wanted. This not only works for constant voltage values: if the frequency of the rectangular wave is \u201chigh enough\u201d, we can also produce a non-constat signal such as an audio signal.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"948\" height=\"507\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/analogpwm.jpg\" alt=\"\" class=\"wp-image-422\"\/><\/figure>\n\n\n\n<p>Great! So how do we produce that rectangular wave? <\/p>\n\n\n\n<p>Well, first of all, instead of an analog PWM and an analog input voltage, we have a digital PWM and an input number, respectively. Instead of the sawtooth generator, we use a counter, which counts up, on every clock cycle, from to a maximum number, say, 7 (3 bit counter). After this maximum value is reached, the counter starts from 0. Then there is a register, called compare register, which is continuously compared with the counter value. When the counter value is reached, the microcontroller pull an output pin (called output compare) high. When the counter starts from 0, the pin is pulled down. The compare register holds the input number that represents our sample.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"954\" height=\"477\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/3bitdpwm.jpg\" alt=\"\" class=\"wp-image-406\"\/><\/figure>\n\n\n\n<p>After this\nbrief explanation, you\u2019ll have realized that the PWM frequency (i.e. the rate\nat which you can update the compare register, which determines the duty cycle\nand therefore the average value) is simply the clock frequency of the counter\ndivided by number of steps of the counter. In our example, we&nbsp; go from 0 to 7, which corresponds to 8 steps,\nhence the frequency is Fcounter\/8.<\/p>\n\n\n\n<p>You\u2019ll have\nalso realized by now that if you want to produce with a single PWM a 16-bit\nvalue, you must have a PWM frequency of Fcounter\/65536. In our Arduino,\nFcounter can be at most 16MHz, yielding only 244Hz, i.e. totally useless! On\nthe other hand, if you want to go at 20kHz, you should have a Fcounter equal to\n1.31 GHz! That\u2019s insane!<\/p>\n\n\n\n<p>However, we\nstill have some tricks. The math!<\/p>\n\n\n\n<p>In fact, as we can write 37 as 3*10 + 7*1, we can express a 16-bit number as the sum of two separate 8-bit numbers, each one multiplied for a \u201cweight\u201d. In other words, a 16-bit number N can be written as HH*256 + LL, where HH and LL are 8-bit numbers.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"909\" height=\"188\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/16bitformula.jpg\" alt=\"\" class=\"wp-image-405\"\/><\/figure>\n\n\n\n<p>This is\nclearer considering the hexadecimal form: 0xnnmm = 0xnn * 0x100 + 0xmm*0x1 &nbsp;(0xnnmm denotes that nnmm is in hexadecimal\nform. 0x100 is 256 in decimal). Very simple! For instance 0x1234 = 0x12 * 0x100\n+ 0x34. <\/p>\n\n\n\n<p>Therefore we can use two 8-bit PWMs and then sum them:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"894\" height=\"219\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/pwmsum.jpg\" alt=\"\" class=\"wp-image-434\"\/><\/figure>\n\n\n\n<p>This is actually achieved using a couple of resistors! The capacitor filters out some of the PWM high frequency signals.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"691\" height=\"367\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/pwmsumCirc.jpg\" alt=\"\" class=\"wp-image-435\"\/><\/figure>\n\n\n\n<p>Before we continue, we must also introduce the frequency and phase correct PWM. In fact, if you have a changing compare value, you\u2019ll end up in a square wave similar to the figure below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"851\" height=\"501\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/phaseerror.jpg\" alt=\"\" class=\"wp-image-433\"\/><\/figure>\n\n\n\n<p>As you can see, the \u201ccenter of mass\u201d of the pulses is in position, which is not constant over every period. Although this still works, it negatively impact on the output quality. <br>The solution is the so called phase-correct PWM, which is obtained with an up-down counter: the counter counts up from 0 to the maximum value and then it counts down back to 0.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"954\" height=\"512\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/phasecorrect.jpg\" alt=\"\" class=\"wp-image-430\"\/><\/figure>\n\n\n\n<p>The output signal now has the center of mass of each sample always at a constant interval.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"816\" height=\"501\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/phasecorrectex.jpg\" alt=\"\" class=\"wp-image-431\"\/><\/figure>\n\n\n\n<p>This has one major drawback: the PWM frequency is almost half, given the same clock. In fact, the cycle is now from 0 to 255 (256 steps)&nbsp; plus 254 to 1 (other 254 steps). This gives 510 steps. However, even if the frequency is almost halved, the quality will be better.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"947\" height=\"522\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/phasecorrectvsfast.jpg\" alt=\"\" class=\"wp-image-432\"\/><\/figure>\n\n\n\n<p>Back to the summation of the two PWMs, we need to choose the value of R1 and R2. The resistor (R2) connected to the PWM which will output the \u201c0xLL\u201d value must be 256 times smaller than the resistor connected to the PWM outputting \u201c0xHH\u201d. Also, to avoid distortion, this ratio should be very precise, better than 1\/256, i.e. with a tolerance smaller than 0.39%.&nbsp; We verified that you can use 1% resistors provided that you measure them with a DMM and make sure that the ratio between their values is 1:256 with a maximum error less than 0.39%. Since many DMMs do not have enough precision (and number of digits), it\u2019s better to use 0.1% resistors.<\/p>\n\n\n\n<p>That said,\nwe must find a couple of resistors, which are exactly in ratio 1:256. Well, if\nyou calculate 1\/256 you achieve 0.00390625. That is, if you take 100kOhm, you\ncan use a 390 Ohm resistor!<\/p>\n\n\n\n<p>However, 390 Ohm is too small. In fact, from the ATMEGA328P datasheet, you\u2019ll find that the output resistance of the pin is between 40 and 50 Ohm. Therefore, instead of connecting 390 Ohm, you are effectively connecting 430-440 Ohm. Do not try to correct this by lowering the resistor value. In fact, the output resistance of the GPIO pin is not constant. The solution is to use much larger resistors, such as 39k and 10M. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Noise considerations<\/h3>\n\n\n\n<p>Larger\nresistors are much noisier, but they make the output resistance less impactful.\n&nbsp;For instance, given a signal bandwidth,\nthe noise power generated by 10MOhm metal film resistor is 10 times larger than\nthe noise of a 1MOhm resistor.&nbsp; To\ncalculate the effective number of bits (ENOB), we use the well-known formula:<\/p>\n\n\n\n<p>ENOB =\n(SINAD \u2013 1.76)\/6.02<\/p>\n\n\n\n<p>Where:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>&nbsp;6.02 is the number of decibels per each bit. <\/li><li>1.76\nis the quantization error, in dB.<\/li><li>SINAD\nis the signal (including noise+distortion) to noise+distortion ratio, expressed\nin dB.<\/li><\/ul>\n\n\n\n<p>Assuming no\ndistortion and no other forms of noise, we have, with 10 MOhm, about 15 bits.\nThis would improve to 16 bit with 1 MOhms, but you must face the problem of the\nGPIO output resistance, which cannot be neglected if you use 3900 Ohm, instead\nof 39kOhm.<\/p>\n\n\n\n<p>Still, note\nthat the distortion caused by the PWM is much larger than the noise of a 10MOhm\nresistor.&nbsp; Furthermore, the noise coming\nfrom the power supply might exceed as well the noise generated by the 10MOhm\nresistor. To reduce the effects of the latter problem, one might need to use\nsome buffers powered with a good filtered low noise supply. However, this would\nincrease a lot the circuit complexity only to get a minor advantage, and it\nwon\u2019t be covered in this post.<\/p>\n\n\n\n<p>In any case, we strongly suggest to power the Arduino with a good quality power supply, to avoid excessive noise (we found that many laptop have a very noisy USB power supply!).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Further audio quality improvements<\/h3>\n\n\n\n<p>It might be\nbetter to sacrifice 2 to 4 bits (i.e. achieving 14 or 12 bits) and use lower\nduty cycle values. In some cases, despite the reduced number of bits, this\nwould improve the audio quality. Of course the ratio of the resistors should be\nadjusted accordingly.<\/p>\n\n\n\n<p>Another way\nto improve is to use the circuit shown in the schematics above. But we think\nthat, at this point, using a cheap SPI DAC (remember? We won\u2019t use the SPI port\nso it\u2019s free!) could even be a much better idea. <\/p>\n\n\n\n<p>All this is\noutside the scope of this post, where we simply wanted to add audio for our\nvideo!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Other considerations<\/h3>\n\n\n\n<p>The\ntheoretical maximum sample rate of this player is about 31 ksps. This will give\nyou the best audio quality, so feel free to try to set the sample rate to 31373\nin the sketch below (don\u2019t forget to use a 31373 sps audio file!). However, in\nour final application we will be forced to play the audio at only 20 kHz, due\nto synchronization reasons. <\/p>\n\n\n\n<p>In other\nwords, when we want to play a 20ksps audio, we need to use two timers. One (Timer\n0) will be used as PWM, while the other (Timer 1) is used to generate a 20 kHz\ninterrupt, required to update the compare registers of Timer 0. However this\nwill create some additional noise, which can be seen in the example below!<\/p>\n\n\n\n<p>Let\u2019s consider the following 20 ksps signal:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"957\" height=\"346\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/originalSignal.jpg\" alt=\"\" class=\"wp-image-429\"\/><\/figure>\n\n\n\n<p>If we use Timer\n0, the PWM will run at about 31kHz (30kHz in our example, for sake of\nsimplicity!). This means that even if the PWM is running at 31kHz, we update\nthe compare registers only at 20kHz. <\/p>\n\n\n\n<p>The result is an error in the actual produced waveform, which can be seen below:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"871\" height=\"426\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/noise30k.jpg\" alt=\"\" class=\"wp-image-428\"\/><\/figure>\n\n\n\n<p>To avoid\nthis, &nbsp;we suggest a possible\nmodification. However it involves the use of Timer 1\u2019s compare outputs. These pins\nare on PB1 and PB2, i.e. on digital pins 9 and 10, which are located in the\noff-grid IOH connectors, requiring a small hack if you want to create your\nshield using the prototyping board.<\/p>\n\n\n\n<p>Therefore\nyou have two possible solutions:<\/p>\n\n\n\n<p><strong>Solution 1:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Just ignore the problem and use the sketch we uploaded (see below) without modifications.  <br>This will still give a decent audio quality, but in some cases the noise, i.e. the green signal in our example, could be very noticeable.<\/li><\/ul>\n\n\n\n<p><strong>Solution 2:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Use timer 1, by defining in the sketch \u201cUSETIMER1PWM\u201d. <br>This will give a perfect 20 ksps PWM, but you\u2019ll need to add some wires to connect PB1 and PB2 (See in the followings). Also, you might want to adjust the volume, as we will explain later.<\/li><\/ul>\n\n\n\n<p> So, how we manage to create a 20 ksps PWM using timer 1?  <br>Timer 1 is a 16 bit timer. Actually we won&#8217;t use all its 16 bits. In fact timer 1 is quite flexible and it allows to set the maximum counter value, by setting the register ICR1. We just have to choose a counter value that gives us the correct PWM period.   <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"695\" height=\"52\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/ICR1.jpg\" alt=\"\" class=\"wp-image-420\"\/><\/figure>\n\n\n\n<p>The above\nformula shows that 400 is the correct maximum timer value.<\/p>\n\n\n\n<p>In this way\nwe also save one timer, as the 20-kHz interrupt, required to refresh the\ncompare register can be generated by Timer 1 itself!<\/p>\n\n\n\n<p>Still, be\naware that despite our sample values range from 0 to 255, the timer goes up to\n400. This means that we can achieve only a maximum duty cycle of 255\/400, which\nis about 63%. This is not a problem, we just need to adjust the value of the\ngain resistor in the output stage, see schematics.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Amplification?<\/h3>\n\n\n\n<p>In this\npost we want to produce an audio for the earpieces. A typical earpiece will\ndeliver 15mW or less, so there is no point of having a large amplification. On\nthe contrary, we need to attenuate our signal!<\/p>\n\n\n\n<p>However, we still need an amplifier, to be able to drive the relatively low impedance of the earpieces. We can connect the two earpieces in series, actually doubling the impedance :). However, if you plan to connect the system to some amplified speakers, you should connect the audio to both channels and connect the center pin to ground. You can use, if you want, two jumpers, as shown in the schematics.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Hardware\/software requirements<\/h1>\n\n\n\n<h3 class=\"wp-block-heading\">Hardware requirements:<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>An Arduino Uno or compatible. Alternatively, you can use any MCU (microcontroller) of your choice. We haven\u2019t tested this on PICs yet, but they might work as well.<\/li><li>A bunch of components (see schematics for the actual values).<\/li><li>Some wires.<\/li><li>A jumper required to keep the ATMEGA16U2 in the reset state while the audio is playing.&nbsp;<strong>This is mandatory!<\/strong><\/li><li>The Display + SD card reader board. You can also use two separate boards: one for the SD, one for the display. Note: if you use the same display we have shown you, be sure to hack it how we did in the&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/next-hack.com\/index.php\/2017\/07\/09\/how-to-play-a-20-fps-video-on-arduino-26-enabling-high-speed-sd-transfers-on-a-1-8-tftsd-module\/\" target=\"_blank\">second episode<\/a>. If you just want to play audio, there is of course no need for the display.<\/li><li><a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/next-hack.com\/index.php\/2017\/08\/14\/how-to-play-a-video-on-arduino-uno-46-playing-a-20-fps-animation-from-sd-card\/\" target=\"_blank\">The shield created last time<\/a>.<\/li><li>A breadboard or a prototyping board (and a soldering iron). Like last time, we preferred using a prototyping board, because it yields a cleaner layout.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"5111\" height=\"1463\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/ComponentsForAudio.jpg\" alt=\"\" class=\"wp-image-416\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Software requirements:<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Arduino IDE \u2013 you can also choose the IDE you like!<\/li><li>Audacity<\/li><\/ul>\n\n\n\n<p><a href=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/08\/audio-sd-test-usart.zip\" target=\"_blank\" rel=\"noreferrer noopener\">The source code for this sketch is available here!<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Let\u2019s go for our next hack!<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: the hardware<\/h3>\n\n\n\n<p>The\nschematics is shown below. Basically the two compare outputs of timer 0 (or,\noptionally, timer 1, see text on the schematics) are connected summed by R7 and\nR1 and filtered by C8. Then we use a high pass filter (C3) to block DC, and\nthen we buffer (and filter again) the resulting signal through the OP AMP. In\nthe schematics we show LM358, but if you are going to use a headphone, then we\nstrongly suggest to use something with a larger output current driving\ncapability such as TLC072, otherwise you\u2019ll face a lot of distortion!<\/p>\n\n\n\n<p>We used two back-to-back capacitors (C6-C7) to form a non cheap polarized-one. This allows you to directly connect the shield to almost any input, regardless their DC polarization. The jumper allows to connect either the earpiece (in this case we suggest to connect the jumper in position 1-2, so that both earpieces will be in series, so both of them produce sound) , or an amplified speaker or the line input of your PC (jumper position 2-3).<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1822\" height=\"840\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/AudioSchematics-1.png\" alt=\"\" class=\"wp-image-451\"\/><\/figure>\n\n\n\n<p>As we did in the previous post, we built a shield for the audio using a prototyping board.&nbsp; The layout is shown below.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1498\" height=\"723\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/Layout-1.png\" alt=\"\" class=\"wp-image-452\"\/><\/figure>\n\n\n\n<p>Green traces are at the bottom layer and you just need these if you want to adopt solution 1. <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"698\" height=\"434\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/finishedshield.jpg\" alt=\"\" class=\"wp-image-453\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"867\" height=\"513\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/BackSolution1.jpg\" alt=\"\" class=\"wp-image-415\"\/><\/figure>\n\n\n\n<p>As written in the text note on the layout, if you want to implement the solution 2, i.e. with better audio quality, you need also to to mount a 24-AWG wire, so that it can be bent, and it will fit to the correct positions of connector IOH. Of course you also need to put the traces marked in red!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"743\" height=\"343\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/FinishedBoardSolution2Profile.jpg\" alt=\"\" class=\"wp-image-419\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: file preparation<\/h3>\n\n\n\n<p>Use\naudacity to convert your favorite audio file to a 16-bit mono WAV, and select\nthe frequency to 20kHz. <\/p>\n\n\n\n<p>To do this:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Install <a href=\"https:\/\/www.audacityteam.org\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Audacity (opens in a new tab)\">Audacity<\/a>.<\/li><li>Import the audio file you want to convert, by selecting menu File-&gt;Import-&gt;Audio<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"482\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/AudacityImportAudio.png\" alt=\"\" class=\"wp-image-410\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Find your audio file press ok, and, in case this dialog appears, we suggest to choose the first option (make a copy).<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"513\" height=\"366\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/audacityImportRequest.png\" alt=\"\" class=\"wp-image-425\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>In the case you choose a stereo audio, click on the track, and choose Track-&gt;Mix-&gt;Mix Stereo Down To Mono.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"727\" height=\"707\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/AudacityMixStereoMono.png\" alt=\"\" class=\"wp-image-411\"\/><\/figure>\n\n\n\n<p>After this, the track will be shown as mono:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"726\" height=\"706\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/AudacityTrackIsMono.png\" alt=\"\" class=\"wp-image-413\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Now, change the project rate (at the\nbottom) to 20000 Hz, as shown below:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"727\" height=\"707\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/AudacityProjectRate20k.png\" alt=\"\" class=\"wp-image-412\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Finally, choose menu\nFile-&gt;Export-&gt;Export Audio <\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"727\" height=\"707\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/AudacityExportAudio.png\" alt=\"\" class=\"wp-image-407\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>Save the file as audio.raw. Be sure\nto select as: file type \u201cother uncompressed files\u201d, header: \u201cRAW (header-less)\u201d\nand Encoding: \u201csigned 16-bit PCM\u201d.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"557\" height=\"613\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/AudacityExportFileFormat.png\" alt=\"\" class=\"wp-image-409\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li>The meta-data request will appear.\nIgnore it by clicking OK. <\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"532\" height=\"409\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/AudacityExportAudioMetaData.png\" alt=\"\" class=\"wp-image-408\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Step 3: Download the sketch program<\/h3>\n\n\n\n<p>The sketch is very simple and can be found <a href=\"https:\/\/next-hack.com\/wp-content\/uploads\/2020\/08\/audio-sd-test-usart.zip\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p>It simply\nsets up the PWM and instructs, via an interrupt, to set the correct compare\nvalues. The interrupt is generated using timer 1. <\/p>\n\n\n\n<p>In the interrupt we put the least significant byte of our sample to one compare register, and the most significant byte to the other compare register. Actually, to the latter we add \u201c128\u201d, as we need a 16-bit unsigned signal (i.e. a number ranging from 0 to 65535), whereas the sample format is 16-bit signed (i.e. a number ranging from -32768 to 32767). To do this, we need to add 32768, that is just 128 to the most significant byte, and 0 to the other :).<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"964\" height=\"593\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/arduinoCodeMSBLSB.png\" alt=\"\" class=\"wp-image-424\"\/><\/figure>\n\n\n\n<p>The system\nuse 2 512-byte bank to implement a double buffering: while we are reading one\nbank, we will output the samples of the other bank. In this way, we can achieve\na smooth continuous playback without too much effort.<\/p>\n\n\n\n<p><strong>Uncomment the highlighted line, if you want to use the solution 2, which will allow for better audio!<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"964\" height=\"593\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/arduinoCode.png\" alt=\"\" class=\"wp-image-423\"\/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Step 4: Program the Arduino<\/h3>\n\n\n\n<p>This is like the previous <a rel=\"noreferrer noopener\" aria-label=\"post (opens in a new tab)\" href=\"https:\/\/next-hack.com\/index.php\/2017\/08\/14\/how-to-play-a-video-on-arduino-uno-46-playing-a-20-fps-animation-from-sd-card\/\" target=\"_blank\">post<\/a>. <strong>The jumper (as well as the shields) must be removed before programming! Remember to put back the jumper after you finished programming, to avoid contentionon the USART lines <\/strong>! <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1277\" height=\"661\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2017\/08\/A3I18.jpg\" alt=\"\" class=\"wp-image-223\"\/><figcaption>Fig. 18. Be sure to put the jumper in the shown position when you want to play the video. Remove the jumper when you want to program your Arduino!<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Step 5: Enjoy!<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Remove the power<\/li><li>Put the new shield (pay attention for the two wires if you used solution 2!<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"823\" height=\"827\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/finishedshieldoverarduin.jpg\" alt=\"\" class=\"wp-image-454\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li> Put the display shield on top of it, with the SD card already inserted.<br><\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"835\" height=\"845\" src=\"https:\/\/next-hack.com\/wp-content\/uploads\/2019\/02\/oneshieldoverother.jpg\" alt=\"\" class=\"wp-image-455\"\/><\/figure>\n\n\n\n<ul class=\"wp-block-list\"><li> Insert your headphone or amplified speakers jack<br>Power your Arduino  <\/li><\/ul>\n\n\n\n<p>You should hear your audio! <\/p>\n\n\n\n<p>Of course the display will stay black. Nothing\nprevents you to improve this sketch and drive the display, to show some fancy\nthings or a file selector.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Possible improvements!<\/h2>\n\n\n\n<p>It\u2019s very\nstraightforward to modify the sketch to accept directly WAV files! We leave it\nas exercise :).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Video<\/h2>\n\n\n\n<iframe loading=\"lazy\" width=\"600\" height=\"338\" src=\"https:\/\/www.youtube.com\/embed\/WD_pcs4BV3o\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\"><\/iframe>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Hi there! Last time we finally managed to get the Arduino playing a 20 fps (or more) 16-bit per pixel 160&#215;128 video from an SD card. Is our journey finished? Of course not.&nbsp; We promised you a full audio+video,&#8230; <a class=\"read-more-button\" href=\"https:\/\/next-hack.com\/index.php\/2019\/02\/03\/how-to-play-a-video-on-arduino-uno-5-6-playing-a-16-bit-20ksps-audio-from-the-sd-card\/\">(READ MORE)<\/a><\/p>\n","protected":false},"author":2,"featured_media":453,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[29],"tags":[8,11,9,10],"class_list":["post-385","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-video-arduino-uno","tag-arduino","tag-audacity","tag-audio-player","tag-wave"],"_links":{"self":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts\/385"}],"collection":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/comments?post=385"}],"version-history":[{"count":17,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts\/385\/revisions"}],"predecessor-version":[{"id":879,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/posts\/385\/revisions\/879"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/media\/453"}],"wp:attachment":[{"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/media?parent=385"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/categories?post=385"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/next-hack.com\/index.php\/wp-json\/wp\/v2\/tags?post=385"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}