<?xml-stylesheet type="text/xsl" href="https://community.element14.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>A QT Py Christmas - add Sound</title><link>/challenges-projects/project14/holidayspecial20/b/blog/posts/a-qt-py-christmas---add-sound</link><description>For the final element of my QT Py Christmas ornament, I&amp;#39;d like to add the ability to play some Christmas music. The SAMD21 has a single DAC output that I&amp;#39;ll use to generate tones, but I&amp;#39;ll also need to add an audio amplifier to drive a speaker a...</description><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>RE: A QT Py Christmas - add Sound</title><link>https://community.element14.com/challenges-projects/project14/holidayspecial20/b/blog/posts/a-qt-py-christmas---add-sound</link><pubDate>Mon, 18 Jul 2022 23:24:22 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:7ce9ce3a-56b1-40f1-b3ad-0f11c837d6a3</guid><dc:creator>sobellinni</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;/*&lt;br /&gt;I made my own sound driver&amp;nbsp; because the one in this blog does not&amp;nbsp; work&amp;nbsp; &lt;br /&gt;&lt;br /&gt;this sketch will play random files&amp;nbsp; labeled with&lt;/p&gt;
&lt;p&gt;numbers&amp;nbsp; */&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#include &amp;lt;Arduino.h&amp;gt;&lt;br /&gt;#include &amp;lt;SPI.h&amp;gt;&lt;br /&gt;#include &amp;quot;SdFat.h&amp;quot;&lt;br /&gt;#include &amp;quot;Adafruit_SPIFlash.h&amp;quot;&lt;br /&gt;#include &amp;quot;Adafruit_ZeroTimer.h&amp;quot;&lt;/p&gt;
&lt;p&gt;// Uncomment to run example with custom SPI and SS e.g with FRAM breakout&lt;br /&gt;// #define CUSTOM_CS A5&lt;br /&gt;// #define CUSTOM_SPI SPI&lt;/p&gt;
&lt;p&gt;#if defined(CUSTOM_CS) &amp;amp;&amp;amp; defined(CUSTOM_SPI)&lt;br /&gt; Adafruit_FlashTransport_SPI flashTransport(CUSTOM_CS, CUSTOM_SPI);&lt;/p&gt;
&lt;p&gt;#elif CONFIG_IDF_TARGET_ESP32S2&lt;br /&gt; // ESP32-S2 use same flash device that store code.&lt;br /&gt; // Therefore there is no need to specify the SPI and SS&lt;br /&gt; Adafruit_FlashTransport_ESP32 flashTransport;&lt;/p&gt;
&lt;p&gt;#else&lt;br /&gt; // On-board external flash (QSPI or SPI) macros should already&lt;br /&gt; // defined in your board variant if supported&lt;br /&gt; // - EXTERNAL_FLASH_USE_QSPI&lt;br /&gt; // - EXTERNAL_FLASH_USE_CS/EXTERNAL_FLASH_USE_SPI&lt;br /&gt; #if defined(EXTERNAL_FLASH_USE_QSPI)&lt;br /&gt; Adafruit_FlashTransport_QSPI flashTransport;&lt;/p&gt;
&lt;p&gt;#elif defined(EXTERNAL_FLASH_USE_SPI)&lt;br /&gt; Adafruit_FlashTransport_SPI flashTransport(EXTERNAL_FLASH_USE_CS, EXTERNAL_FLASH_USE_SPI);&lt;/p&gt;
&lt;p&gt;#else&lt;br /&gt; #error No QSPI/SPI flash are defined on your board variant.h !&lt;br /&gt; #endif&lt;br /&gt;#endif&lt;br /&gt;Adafruit_SPIFlash flash(&amp;amp;flashTransport);&lt;/p&gt;
&lt;p&gt;// file system object from SdFat&lt;br /&gt;FatFileSystem fatfs;&lt;br /&gt;File myFile;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;// This example can have just about any frequency for the callback&lt;br /&gt;// automatically calculated!&lt;br /&gt;float freq = 8000.0; // 8 KHz&lt;br /&gt;int phase = 0;&lt;br /&gt;int fnote = 0;&lt;br /&gt;int val =0;&lt;br /&gt;int writebufcounter = 0;&lt;br /&gt;int writebufpointer = 0;&lt;br /&gt;int readbufcounter = 0;&lt;br /&gt;int readbufpointer = 0;&lt;br /&gt;byte bval=0;&lt;br /&gt;byte fval=0;&lt;br /&gt;byte soundbuffer[2][256];&lt;br /&gt;bool bufferfull[2];&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;int soundbytes;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;int whichbuf =0;&lt;br /&gt;int filenumb;&lt;br /&gt;char filenumber[10];&lt;br /&gt;char filename[10];&lt;/p&gt;
&lt;p&gt;// timer tester&lt;br /&gt;Adafruit_ZeroTimer zerotimer = Adafruit_ZeroTimer(3);&lt;/p&gt;
&lt;p&gt;void TC3_Handler() {&lt;br /&gt; Adafruit_ZeroTimer::timerHandler(3);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;// the timer callback&lt;/p&gt;
&lt;p&gt;void TimerCallback0(void){&lt;br /&gt; digitalWrite(9, LOW);&lt;br /&gt; //read buffer till all read and make it not full &lt;br /&gt; if (bufferfull[readbufpointer]==true){&lt;br /&gt; bval = soundbuffer[readbufpointer][readbufcounter];&lt;br /&gt; readbufcounter++;&lt;br /&gt; if (readbufcounter&amp;gt;255){&lt;br /&gt; &lt;br /&gt; bufferfull[readbufpointer] = false; //enable file to write &lt;br /&gt; if (readbufpointer==0) digitalWrite(6, LOW); &lt;br /&gt; if (readbufpointer==1) digitalWrite(7, LOW); &lt;br /&gt; &lt;br /&gt; readbufcounter = 0;&lt;br /&gt; readbufpointer = 1 &amp;amp; (readbufpointer ^1); // point to the other buffer &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; }&lt;br /&gt; else { &lt;br /&gt; bval = 0x80; &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; &lt;br /&gt; val = ((int)bval&amp;lt;&amp;lt;2)&amp;amp;0x3ff;&lt;br /&gt; analogWrite(0, val );&lt;/p&gt;
&lt;p&gt;digitalWrite(9, HIGH);&lt;br /&gt; }&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;void play(const char *fname) {&lt;br /&gt;bufferfull[0]=false;&lt;br /&gt;bufferfull[1]=false; &lt;br /&gt;writebufpointer =0;&lt;br /&gt;readbufpointer =0; &lt;br /&gt;digitalWrite(8, HIGH);&lt;br /&gt;myFile = fatfs.open(fname);&lt;br /&gt;if (myFile) {&lt;br /&gt; Serial.println(fname);&lt;br /&gt; Serial.println(myFile.size());&lt;br /&gt; Serial.println(&amp;quot;b4readin&amp;quot;);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;for(int i =0; i&amp;lt;44; i++)&lt;br /&gt; myFile.read(); // eliminate header&lt;br /&gt; Serial.println(&amp;quot;counted44&amp;quot;);&lt;br /&gt; &lt;br /&gt; while (soundbytes = myFile.available()) { // find out how may bytes are still available &lt;br /&gt; &lt;br /&gt; if (bufferfull[writebufpointer]==false){ //buffer available&lt;br /&gt; fval= myFile.read();&lt;br /&gt; //Serial.write(fval);&lt;br /&gt; soundbuffer[writebufpointer][writebufcounter] = fval; // fill sound buffer&lt;br /&gt; writebufcounter++;&lt;br /&gt; if (writebufcounter&amp;gt;255){&lt;br /&gt; bufferfull[writebufpointer] = true; //stop file to write &lt;br /&gt; if (writebufpointer==0) digitalWrite(6, HIGH); &lt;br /&gt; if (writebufpointer==1) digitalWrite(7, HIGH); &lt;br /&gt; writebufcounter = 0;&lt;br /&gt; writebufpointer = 1 &amp;amp; (writebufpointer ^1);; // point to the other buffer &lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; // file is done reading, see if there is still a buffer to fill &lt;br /&gt; &lt;br /&gt; while (bufferfull[writebufpointer]=false){&lt;br /&gt; &lt;br /&gt; soundbuffer[writebufpointer][writebufcounter] = 0x80; // fill sound buffer with audio 0&lt;br /&gt; writebufcounter++;&lt;br /&gt; if (writebufcounter&amp;gt;255){&lt;br /&gt; bufferfull[writebufpointer] = true;&lt;br /&gt; if (writebufpointer==0) digitalWrite(6, HIGH); &lt;br /&gt; if (writebufpointer==1) digitalWrite(7, HIGH); &lt;br /&gt; writebufcounter = 0;&lt;br /&gt; }&lt;br /&gt; //DONE&lt;br /&gt;}&lt;br /&gt;digitalWrite(8, LOW);&lt;br /&gt; }&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;void setup() {&lt;/p&gt;
&lt;p&gt;// Open serial communications and wait for port to open:&lt;br /&gt; Serial.begin(115200);&lt;br /&gt; while (!Serial) {&lt;br /&gt; delay(1); // wait for serial port to connect. Needed for native USB port only&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; Serial.print(&amp;quot;Initializing Filesystem on external flash...&amp;quot;);&lt;br /&gt; &lt;br /&gt; // Init external flash&lt;br /&gt; flash.begin();&lt;br /&gt; &lt;br /&gt; // Open file system on the flash&lt;br /&gt; if ( !fatfs.begin(&amp;amp;flash) ) {&lt;br /&gt; Serial.println(&amp;quot;Error: filesystem is not existed. Please try SdFat_format example to make one.&amp;quot;);&lt;br /&gt; while(1) yield();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; Serial.println(&amp;quot;initialization done.&amp;quot;);&lt;br /&gt; pinMode(6, OUTPUT);&lt;br /&gt; pinMode(7, OUTPUT);&lt;br /&gt; pinMode(8, OUTPUT);&lt;br /&gt; pinMode(9, OUTPUT);&lt;/p&gt;
&lt;p&gt;tc_clock_prescaler prescaler = TC_CLOCK_PRESCALER_DIV1;&lt;/p&gt;
&lt;p&gt;zerotimer.enable(false);&lt;br /&gt; zerotimer.configure(prescaler, // prescaler =1&lt;br /&gt; TC_COUNTER_SIZE_16BIT, // bit width of timer/counter&lt;br /&gt; TC_WAVE_GENERATION_MATCH_PWM // frequency or PWM mode&lt;br /&gt; );&lt;/p&gt;
&lt;p&gt;zerotimer.setCompare(0, 6000); // 48000000/8000 = 6000&lt;br /&gt; zerotimer.setCallback(true, TC_CALLBACK_CC_CHANNEL0, TimerCallback0);&lt;br /&gt; zerotimer.enable(true);&lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;void loop() {&lt;/p&gt;
&lt;p&gt;filename[0]=0;&lt;br /&gt; filenumb = random(36);&lt;br /&gt; itoa(filenumb,filenumber,10);&lt;/p&gt;
&lt;p&gt;strcat(filename,filenumber); &lt;br /&gt;strcat(filename, &amp;quot;.wav&amp;quot;);&lt;/p&gt;
&lt;p&gt;&lt;br /&gt; &lt;br /&gt; Serial.println(filename);&lt;br /&gt; &lt;br /&gt; play(filename);&lt;br /&gt;delay(1000);&lt;/p&gt;
&lt;p&gt;}&lt;/p&gt;&lt;img src="https://community.element14.com/aggbug?PostID=10561&amp;AppID=278&amp;AppType=Weblog&amp;ContentType=0" width="1" height="1"&gt;</description></item></channel></rss>