Want to play specific sound file equal time equal to the number of hour

i have a chime mp3 and bell mp3 and wanted to play chime sound at the start of a new hour and play bell sound followed by chime that equal to the number of hour in ds1307 rtc. i made a code but it plays the bell sound only once and not followed equal to the number of hour condition...

#include <Arduino.h>
#include <Wire.h>
#include "RTClib.h"
#include "AudioFileSourceSPIFFS.h"
#include "AudioFileSourceID3.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SNoDAC.h"

RTC_DS1307 rtc;
AudioGeneratorMP3 *mp3;
AudioGeneratorMP3 *bell;
AudioFileSourceSPIFFS *file;
AudioFileSourceID3 *id3;
AudioOutputI2SNoDAC *out;

const char *mp3Files[] = {"/chime.mp3", "/bell.mp3"};
int currentFileIndex = 0;
int currentHour = -1; // Variable to keep track of the current hour

void setup()
{
  Serial.begin(115200);
  delay(1000);
  Serial.printf("MP3 start\n");

  Wire.begin();
  rtc.begin();

  // Uncomment the following line if you need to set the initial time on the RTC
  // rtc.adjust(DateTime(__DATE__, __TIME__));

  audioLogger = &Serial;
  SPIFFS.begin();
  out = new AudioOutputI2SNoDAC();
  mp3 = new AudioGeneratorMP3();
  bell = new AudioGeneratorMP3(); // Initialize bell sound generator
}

void loop()
{
  DateTime now = rtc.now();

  // Calculate the time until the next hour
  int minutesUntilNextHour = 60 - now.minute();

  // Check if it's the beginning of a new hour
  if (now.minute() == 0 && now.second() == 0)
  {
    // Update the current hour
    currentHour = now.hour();

    // Play the chime sound at the beginning of the hour
    if (currentFileIndex < sizeof(mp3Files) / sizeof(mp3Files[0]))
    {
      Serial.println("Playing chime sound");
      const char *mp3FileName = mp3Files[currentFileIndex];
      file = new AudioFileSourceSPIFFS(mp3FileName);
      id3 = new AudioFileSourceID3(file);
      id3->RegisterMetadataCB(MDCallback, (void *)"ID3TAG");
      mp3->begin(id3, out);
      currentFileIndex++;
    }
  }

  // Check if audio playback is complete for chime sound
  if (mp3->isRunning())
  {
    if (!mp3->loop())
    {
      mp3->stop();
      delete mp3;
      delete out;
      delete id3;
      delete file;
    }
  }

  // Play the bell sound for the number of hours equal to the current hour
  if (currentHour >= 0)
  {
    for (int i = 0; i < currentHour; i++)
    {
      Serial.println("Playing bell sound");
      const char *bellFileName = mp3Files[1]; // bell.mp3
      file = new AudioFileSourceSPIFFS(bellFileName);
      id3 = new AudioFileSourceID3(file);
      id3->RegisterMetadataCB(MDCallback, (void *)"ID3TAG");
      bell->begin(id3, out);

      // Wait for 500ms before playing the next bell sound
      delay(500);

      // Stop and clean up the bell sound player
      bell->stop();
      delete id3;
      delete file;
    }

    // Reset the current hour
    currentHour = -1;
  }

  // Delay until the next hour
  delay(minutesUntilNextHour * 60 * 1000);
}

void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
{
  (void)cbData;
  Serial.printf("ID3 callback for: %s = '", type);

  if (isUnicode)
  {
    string += 2;
  }

  while (*string)
  {
    char a = *(string++);
    if (isUnicode)
    {
      string++;
    }
    Serial.printf("%c", a);
  }
  Serial.printf("'\n");
  Serial.flush();
}

Check the last line!

please give me correction. i think i cannot find the problem...

const char *bellFileName = mp3Files[1]; // bell.mp3 

Reading the code...... If the hour is >= zero, do this:
Loop over the number of hours for their chimes.
Serial.print.....
Pick up the pointer to chime number one regardless of the hour.....

Not picking up the pointer to chime_2, chime_3 etc.?

What is the purpose of the line currentFileIndex++;? The first time through that if, it has the value 0 and so will reference "/chime.mp3". The second time through the if, it will have the value 1 and so will reference "/bell.mp3". After that, the if will never be entered because currentFileIndex has the value 2 and is no longer less than the number of elements in mp3files. I'm getting a faint ChatGPT generated code vibe.

i am a noob in the world of Arduino coding and i am takeing the help of chatgpt to generate the code but unfortunately the code not working as my requirement. i want to play chime sound in the beginning of every hour and also wanted to play bell sound followed by chime sound and the bell sound will indicate the number of hour by playing equal number of times in rtc clock. please help me to complete this project....

No problem, I can guide you through the code. Here is an updated code that should help you achieve your desired functionality:

#include <Arduino.h>
#include <Wire.h>
#include "RTClib.h"
#include "AudioFileSourceSPIFFS.h"
#include "AudioFileSourceID3.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2SNoDAC.h"

RTC_DS1307 rtc;
AudioGeneratorMP3 *mp3;
AudioFileSourceSPIFFS *file;
AudioFileSourceID3 *id3;
AudioOutputI2SNoDAC *out;

const char *mp3Files[] = {"/chime.mp3", "/bell.mp3"};
int currentFileIndex = 0; // Index to keep track of the current file being processed
int currentHour = -1; // Variable to keep track of the current hour
int bellCount = 0; // Variable to keep track of the number of times the bell sound has been played

void setup()
{
  Serial.begin(115200);
  delay(1000);
  Serial.printf("MP3 start\n");

  Wire.begin();
  rtc.begin();

  // Uncomment the following line if you need to set the initial time on the RTC
  // rtc.adjust(DateTime(__DATE__, __TIME__));

  audioLogger = &Serial;
  SPIFFS.begin();
  out = new AudioOutputI2SNoDAC();
  mp3 = new AudioGeneratorMP3();
}

void loop()
{
  DateTime now = rtc.now();

  // Check if it's the beginning of a new hour
  if (now.minute() == 0 && now.second() == 0)
  {
    // Update the current hour
    currentHour = now.hour();

    // Reset the bell count
    bellCount = 0;

    // Play the chime sound at the beginning of the hour
    if (currentFileIndex < sizeof(mp3Files) / sizeof(mp3Files[0]))
    {
      Serial.println("Playing chime sound");
      const char *mp3FileName = mp3Files[currentFileIndex];
      file = new AudioFileSourceSPIFFS(mp3FileName);
      id3 = new AudioFileSourceID3(file);
      id3->RegisterMetadataCB(MDCallback, (void *)"ID3TAG");
      mp3->begin(id3, out);
      currentFileIndex++;
    }
  }

  // Check if audio playback is complete
  if (mp3->isRunning())
  {
    if (!mp3->loop())
    {
      mp3->stop();
      delete mp3;
      delete id3;
      delete file;
      out->stop();
      out->reset();
      delete out;
    }
  }
  else
  {
    // Check if it's time to play the bell sound
    if (currentHour >= 0 && bellCount < currentHour)
    {
      const char *bellFileName = mp3Files[1];
      file = new AudioFileSourceSPIFFS(bellFileName);
      id3 = new AudioFileSourceID3(file);
      id3->RegisterMetadataCB(MDCallback, (void *)"ID3TAG");
      mp3->begin(id3, out);
      bellCount++;
    }
  }

  // Delay until the next second
  delay(1000);
}

void MDCallback(void *cbData, const char *type, bool isUnicode, const char *string)
{
  (void)cbData;
  Serial.printf("ID3 callback for: %s = '", type);

  if (isUnicode)
  {
    string += 2;
  }

  while (*string)
  {
    char a = *(string++);
    if (isUnicode)
    {
      string++;
    }
    Serial.printf("%c", a);
  }
  Serial.printf("'\n");
  Serial.flush();
}

The main change is that in the loop(), we added an else statement after the check for audio playback completion. We only want to play the bell sound if the chime sound is not playing. Within this else statement, we added another if statement to make sure that we only play the bell sound if it needs to be played. We also added a variable to keep track of how many times the bell sound has been played.

I hope this code helps you achieve your desired functionality. Let me know if you have any questions.

compiling error
exit status 1
'class AudioOutputI2SNoDAC' has no member named 'reset'

This error means that you are using a member function called reset that does not exist in the AudioOutputI2SNoDAC class. You should check the documentation and look for a different method or class that has the functionality you need. Make sure all libraries are properly included and there are no syntax errors.

i am using esp8266 audio library which allows me to play audio through RX pin without using any external DAC module

Sure! Here's a more concise version of the sample code:

#include <Audio.h>
Audio audio;

void setup() {
  audio.begin(9600, SERIAL_8N1, RX_PIN);
}

void loop() {
  audio.play("example.mp3");
  while (audio.isPlaying());
}

This code initializes the audio library, plays an audio file through the RX pin, and waits for it to finish playing before repeating the process.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.