Advertisement
Guest User

JPEG display and MP3 play from SD card to internal DAC ESP32 CYD

a guest
Oct 29th, 2024
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.90 KB | Source Code | 0 0
  1. //
  2. // JPEG display and MP3 play from SD card to internal DAC
  3. // written by Larry Bank ([email protected])
  4. // Modified by Isolt
  5. //
  6. #include <Arduino.h>
  7. #include "AudioFileSourceSD.h"
  8. #include "AudioFileSourceID3.h"
  9. #include "AudioGeneratorMP3.h"
  10. #include "AudioOutputI2S.h"
  11. #include <bb_spi_lcd.h>
  12. #include <JPEGDEC.h>
  13. #include <SPI.h>
  14. #include <SD.h>
  15.  
  16.  
  17. // Static instances of the 2 classes
  18. // These can be allocated dynamically too (e.g. *jpg = new JPEGDEC(); )
  19. JPEGDEC jpg;
  20. BB_SPI_LCD lcd;
  21. SPIClass SD_SPI;
  22. AudioFileSourceSD *fileMP3;
  23. AudioGeneratorMP3 *mp3;
  24. AudioFileSourceSD *source;
  25. AudioOutputI2S *out;
  26. AudioFileSourceID3 *id3;
  27.  
  28. // GPIO pin assignments specifically for the CYD 2USB model
  29. // check your model if different
  30. #define SD_MOSI 23
  31. #define SD_MISO 19
  32. #define SD_SCK 18
  33. #define SD_CS 5
  34.  
  35. // Change this to the file you would like to display
  36. const char *jpeg_filename = "/10.jpg";
  37. char *mp3_filename = "/guitar.mp3";
  38. //
  39. // Draw callback from JPEG decoder
  40. //
  41. // called multiple times with groups of MCUs (minimum coded units)
  42. // these are 8x8, 8x16, 16x8 or 16x16 blocks of pixels depending on the
  43. // color subsampling option of the JPEG image
  44. // Each call can have a large group (e.g. 128x16 pixels)
  45. //
  46. int JPEGDraw(JPEGDRAW *pDraw) {
  47.   lcd.setAddrWindow(pDraw->x, pDraw->y, pDraw->iWidth, pDraw->iHeight);
  48.   lcd.pushPixels((uint16_t *)pDraw->pPixels, pDraw->iWidth * pDraw->iHeight);
  49.   return 1;
  50. } /* JPEGDraw() */
  51.  
  52. File file;
  53.  
  54. // Callback functions to access a file on the SD card
  55. void *myOpen(const char *filename, int32_t *size) {
  56.   file = SD.open(filename);
  57.   if (file) {
  58.     *size = file.size();
  59.   }
  60.   return (void *)&file;
  61. }
  62.  
  63. void myClose(void *pHandle) {
  64.   File *f = static_cast<File *>(pHandle);
  65.   if (f != NULL)
  66.     f->close();
  67. }
  68.  
  69. int32_t myRead(JPEGFILE *pFile, uint8_t *buffer, int32_t length) {
  70.   //  File *f = (File *)pFile->fHandle;
  71.   //  return f->read(buffer, length);
  72.   int32_t iBytesRead;
  73.   iBytesRead = length;
  74.   File *f = static_cast<File *>(pFile->fHandle);
  75.   // Note: If you read a file all the way to the last byte, seek() stops working
  76.   if ((pFile->iSize - pFile->iPos) < length)
  77.     iBytesRead = pFile->iSize - pFile->iPos - 1;  // <-- ugly work-around
  78.   if (iBytesRead <= 0)
  79.     return 0;
  80.   iBytesRead = (int32_t)f->read(buffer, iBytesRead);
  81.   pFile->iPos = f->position();
  82.   return iBytesRead;
  83. }
  84.  
  85. int32_t mySeek(JPEGFILE *pFile, int32_t iPosition) {
  86.   //  int i = micros();
  87.   File *f = static_cast<File *>(pFile->fHandle);
  88.   f->seek(iPosition);
  89.   pFile->iPos = (int32_t)f->position();
  90.   //  i = micros() - i;
  91.   //  Serial.printf("Seek time = %d us\n", i);
  92.   return pFile->iPos;
  93. } /* GIFSeekFile() */
  94.  
  95. void playMP3(char *filenameMP3) {
  96.   fileMP3 = new AudioFileSourceSD(filenameMP3);
  97.   id3 = new AudioFileSourceID3(fileMP3);
  98.   out = new AudioOutputI2S(0, 2, 8, -1); // Output to builtInDAC
  99.   out->SetOutputModeMono(true);
  100.   out->SetGain(0.2);
  101.   mp3 = new AudioGeneratorMP3();
  102.   mp3->begin(id3, out);
  103.   while (mp3->isRunning()) {
  104.     if (!mp3->loop()) mp3->stop();
  105.   }
  106. }
  107.  
  108. void setup() {
  109.   Serial.begin(115200);
  110.   lcd.begin(DISPLAY_CYD_2USB);  // set this to the correct display type for your board
  111.   lcd.fillScreen(TFT_BLACK);
  112.   lcd.setTextColor(TFT_GREEN, TFT_BLACK);
  113.   lcd.setFont(FONT_12x16);
  114.   lcd.println("JPEG Decoder Example");
  115.   SD_SPI.begin(SD_SCK, SD_MISO, SD_MOSI, SD_CS);
  116.   if (!SD.begin(SD_CS, SD_SPI, 10000000)) {  // Faster than 10MHz seems to fail on the CYDs
  117.     lcd.println("Card Mount Failed");
  118.     while (1) {};
  119.   } else {
  120.     lcd.println("Card Mount Succeeded");
  121.   }
  122. }
  123.  
  124. void loop() {
  125.   if (jpg.open(jpeg_filename, myOpen, myClose, myRead, mySeek, JPEGDraw)) {  // pass the data and its sizeENDIAN);
  126.     jpg.setPixelType(RGB565_BIG_ENDIAN); // bb_spi_lcd uses big-endian RGB565 pixels
  127.     jpg.decode(0, 0, 0);  // render image top left
  128.   }
  129.     delay(2000);
  130.   playMP3(mp3_filename);
  131.   delay(2000);
  132. }
  133.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement