Need Help with a compilation error

Some Background:
This project uses ESP32 to record and playback audio.
When the sensor is triggered and a button is pressed it will record audio. And with another button it will play the audio.

I get a compilation error saying I didn't declare a variable. Any help on this will be extremely appreciated. I've tried everything I could, declaring it as a class, a string, an integer etc. it still will not accept it and gives another type of error.

This is the error log:

C:\Users\Shah\Desktop\New folder (2)\CodeVentxCasefinal\CodeVentxCasefinal.ino: In function 'void loop()':
C:\Users\Shah\Desktop\New folder (2)\CodeVentxCasefinal\CodeVentxCasefinal.ino:113:8: error: 'output' was not declared in this scope
   play(output, "/sdcard/tone.wav");
        ^
C:\Users\Shah\Desktop\New folder (2)\CodeVentxCasefinal\CodeVentxCasefinal.ino:115:10: error: 'input' was not declared in this scope
   record(input, "/sdcard/recorded.wav");
          ^
C:\Users\Shah\Desktop\New folder (2)\CodeVentxCasefinal\CodeVentxCasefinal.ino: In function 'void Read_Button()':
C:\Users\Shah\Desktop\New folder (2)\CodeVentxCasefinal\CodeVentxCasefinal.ino:138:16: error: 'output' was not declared in this scope
         { play(output, "/sdcard/recorded.wav"); }
                ^
C:\Users\Shah\Desktop\New folder (2)\CodeVentxCasefinal\CodeVentxCasefinal.ino: In function 'void Read_Sensor()':
C:\Users\Shah\Desktop\New folder (2)\CodeVentxCasefinal\CodeVentxCasefinal.ino:169:17: error: 'output' was not declared in this scope
         {  play(output, "/sdcard/standard.wav"); 
                 ^
C:\Users\Shah\Desktop\New folder (2)\CodeVentxCasefinal\CodeVentxCasefinal.ino:175:17: error: 'output' was not declared in this scope
            play(output, "/sdcard/recorded.wav"); 
                 ^

Using library BLE at version 1.0.1 in folder: C:\Users\Shah\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\BLE 
Using library SPIFFS at version 1.0 in folder: C:\Users\Shah\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\SPIFFS 
Using library FS at version 1.0 in folder: C:\Users\Shah\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\FS 
exit status 1

Compilation error: 'output' was not declared in this scope

Here is the complete code if someone needs it:

#include <Arduino.h>
#include <stdio.h>
#include <FreeRTOS.h>
#include <string>
#include "I2SMEMSSampler.h"
#include "ADCSampler.h"
#include "I2SOutput.h"
#include "DACOutput.h"
#include "SDCard.h"
#include "SPIFFS.h"
#include "WAVFileReader.h"
#include "WAVFileWriter.h"
#include "config.h"

//------------------------Variables Initialization---------------------------
    
bool Lock=true, Lock1=true, Lock2=true, Lock3=true, Lock4=true,
     timer=false, Play=false, state=true;     
int recordd=0;

unsigned long cm=0, pm=0;
//---------------------------------------------------------------------------

void record(I2SSampler *input, const char *fname)
{
  int16_t *samples = (int16_t *)malloc(sizeof(int16_t) * 1024);
  ESP_LOGI(TAG, "Start recording");
  input->start();
  // open the file on the sdcard
  FILE *fp = fopen(fname, "wb");
  // create a new wave file writer
  WAVFileWriter *writer = new WAVFileWriter(fp, input->sample_rate());
  // keep writing until the user releases the button
  while (recordd==1)
  {
    int samples_read = input->read(samples, 1024);
    int64_t start = esp_timer_get_time();
    writer->write(samples, samples_read);
    int64_t end = esp_timer_get_time();
    ESP_LOGI(TAG, "Wrote %d samples in %lld microseconds", samples_read, end - start);

    Read_Stop_Button ();    
  }

  
  // stop the input
  input->stop();
  // and finish the writing
  writer->finish();
  fclose(fp);
  delete writer;
  free(samples);
  ESP_LOGI(TAG, "Finished recording");
}

void play(Output *output, const char *fname)
{ 
  int16_t *samples = (int16_t *)malloc(sizeof(int16_t) * 1024);
  // open the file on the sdcard
  FILE *fp = fopen(fname, "rb");
  // create a new wave file writer
  WAVFileReader *reader = new WAVFileReader(fp);
  ESP_LOGI(TAG, "Start playing");
  output->start(reader->sample_rate());
  ESP_LOGI(TAG, "Opened wav file");
  // read until theres no more samples
  while (true)
  {
    int samples_read = reader->read(samples, 1024);
    if (samples_read == 0)
    {
      break;
    }
    if (digitalRead(GPIO_BUTTON_2)==LOW)
    break;
    ESP_LOGI(TAG, "Read %d samples", samples_read);
    output->write(samples, samples_read);
    ESP_LOGI(TAG, "Played samples");
  } 
  // stop the input
  output->stop();
  fclose(fp);
  delete reader;
  free(samples);
  ESP_LOGI(TAG, "Finished playing");
}



void setup()
{
  Serial.begin(115200);
  pinMode(GPIO_BUTTON_1, INPUT_PULLUP);
  pinMode(GPIO_BUTTON_2, INPUT_PULLUP);
  pinMode(GPIO_BUTTON_3, INPUT_PULLUP);
  pinMode(PIR_Sensor, INPUT); 
  xTaskCreate(main_task, "Main", 4096, NULL, 0, NULL);

}

void loop()
{
 
  cm = millis();

 Read_Button ();  
 Read_Sensor ();


 if (recordd==1)
 {
  delay(3000); 
  play(output, "/sdcard/tone.wav");
  delay(1000);
  record(input, "/sdcard/recorded.wav");
  recordd = 0;
  }       

}



//--------------------------------------------------------------------------


void Read_Button ()
{
  if (digitalRead(GPIO_BUTTON_1)==LOW&&Lock1==true)
       {  Lock1=false;
        Lock=!Lock; }
  else if (digitalRead(GPIO_BUTTON_1)==HIGH&&Lock1==false)
       { Lock1=true;   }


    if (digitalRead(GPIO_BUTTON_2)==LOW&&Lock2==true)
       { Lock2=false;
        if (state==true)
        { play(output, "/sdcard/recorded.wav"); }
        state=!state;
        }
   else if (digitalRead(GPIO_BUTTON_2)==HIGH&&Lock2==false)
       { Lock2=true; }


     if (digitalRead(GPIO_BUTTON_3)==LOW&&Lock3==true)
       {
        Lock3=false;
        if (recordd == 0)
        recordd=1;
        else
        {recordd=3; 
        }
       }
   else if (digitalRead(GPIO_BUTTON_3)==HIGH&&Lock3==false)
       { Lock3=true; }
 
  }


//---------------------------------Looking for PIR detection------------------------------


void Read_Sensor ()
{
  if (digitalRead(PIR_Sensor)==HIGH&&Lock4==true)
       {
        Lock4=false;
        if (Lock==true)
        {  play(output, "/sdcard/standard.wav"); 
           delay(1000);
           play(output, "/sdcard/standard.wav");       
          }
        else if (Lock==false)
            {
           play(output, "/sdcard/recorded.wav"); 
           delay(1000);
           play(output, "/sdcard/recorded.wav");  
              }  
        }
   else if (digitalRead(PIR_Sensor)==LOW&&Lock4==false)
       {
        Lock4=true; 
        }
   
  }


void Read_Stop_Button ()
{
   
     if (digitalRead(GPIO_BUTTON_3)==LOW&&Lock3==true)
       {
        Lock3=false;
        if (recordd == 0)
        recordd=1;
        else
        {recordd=3; 
        }
       }
   else if (digitalRead(GPIO_BUTTON_3)==HIGH&&Lock3==false)
       { Lock3=true; }
 
  }




void main_task(void *param)
{
  ESP_LOGI(TAG, "Starting up");

#ifdef USE_SPIFFS
  ESP_LOGI(TAG, "Mounting SPIFFS on /sdcard");
  SPIFFS.begin(true, "/sdcard");
#else
  ESP_LOGI(TAG, "Mounting SDCard on /sdcard");
  new SDCard("/sdcard", PIN_NUM_MISO, PIN_NUM_MOSI, PIN_NUM_CLK, PIN_NUM_CS);
#endif

  ESP_LOGI(TAG, "Creating microphone");
#ifdef USE_I2S_MIC_INPUT
  I2SSampler *input = new I2SMEMSSampler(I2S_NUM_0, i2s_mic_pins, i2s_mic_Config);
#else
  I2SSampler *input = new ADCSampler(ADC_UNIT_1, ADC1_CHANNEL_7, i2s_adc_config);
#endif

#ifdef USE_I2S_SPEAKER_OUTPUT
  Output *output = new I2SOutput(I2S_NUM_0, i2s_speaker_pins);
#else
  Output *output = new DACOutput(I2S_NUM_0);
#endif
}

You don’t declare input nor output. What are those supposed to be?

This is a pretty clear error message...


I have to make some assumptions, but from

Would indicate that 'input' is a pointer to an object of type I2SSampler ...

And 'output' as a pointer to an object of type 'Output'...

These both need to be instantiated before use...

Might want to think about this for clarity...
Something like

while (samples_read = reader->read(samples, 1024)) {
...

If it doesn't read anything it returns 0 and it doesn't go through the loop... Eliminates the two if statements making the logic more clear...


People use spaces to delimit things, it's how our brains works ... Take < 1/2 sec and use the space bar between things... the compiler doesn't care, but the human reader trying to help you does...

howwouldyoulikemetoaskquestionsthisway?

Good luck

:smiley_cat:

1 Like

And how do I do that? I've tried, but it gives me other errors when I declare them. (Am I mot grasping the meaning of "instantiated"?) They call back to a custom library. They store the path of the file to be interacted with. They are used throughout the code error free (If you check in void(record) as an example), but when used in void (loop) they give this error. As if void (loop) has no idea of their existence. Now if I initialize or declare them in void(loop), as a String for example, it suddenly recognizes it and says I'm passing an illegal argument through it. But if I don't declare them the program doesn't see it and just says that it's not declared.
I'm pretty sure I'm messing up something very simple, but I cannot figure it out.

If I declare them, I get other error messages. They are supposed to be the file path to the recorded files.

A good high level computer language has rules that keep you from hanging yourself, at least up to a point.

You can use variables you don't declare, that's part of programming... it prevents you from getting something you are unaware of...

Do you have a description of the library you're using...?

I'm guessing but if the I2SSampler object is declared somewhere you would have to do something like;

I2SSampler input;  // type (I2SSampler) followed by the variable (input)
int        x;      // no different, type (int) followed by the variable (x)....

I'd make it a habit to avoid names like input, output ... etc sometimes these are reserved and can bite you... Might try 'input_file' or ...

When you allocate memory, you must check for success...

These kind of bugs are hard to find...


I think you've picked a rather complicated project .... I'm sure you'll find other issues along the way...

Good luck

:smiley_cat:

1 Like

It only means that you have other errors in your program besides this one. However, you must declare them.

As I see, you tried to do this, but you put the declaration of these and other objects in a procedure main_task(). This is mistake. An object declared within a procedure is local to that procedure and is not visible to the main program. You must move these declarations to the global scope.
After you do this, you will have other errors, because there is still a lot of strange and illogical code in the program, for example as @jkwilborn pointed out.

1 Like

I'm using 13 different libraries... And I am completely aware I bit more than I could chew..

This specific input is from I2SSampler. It starts taking samples from the I2C interface with the mic

Seems like a good habit to have. I ran into problems with this already and had to rectify it.

Somehow I do not doubt you one bit. I've already encountered way many before I reached this point. But here, I'm completely stumped.

By this I meant if I declare them, I get issues in the same line as before like "passing invalid arguments through I2SSampler *input, const char *fname cxxn_gnc something like that.

You my dear, are a LIFE SAVER. It worked. Somehow I overlooked something so basic. I guess when I was trying to rectify the issue on line 113 I was looking for the issue in the upper portion of the code. I didn't even try to look down there thinking the compiler hasn't reached there yet anyway. I see that was not the right thing to do. I hadn't written this code I was given the code to repair it. I still don't know the complete logic of the code, I was just eliminating the compilation errors.
I just moved the void (maintask) declarations into the global declarations and everything worked like a charm.

In my defence, I did not write the entire code :smiley: I always take care of things like this, And I am sorry if it caused any unnecessary discomfort to you. You have been nothing but helpful to me.

@shah0301 please can I get the circuit diagram of your connection between your esp32 and your sd card module as I am trying to achieve the same by recording but keep getting this error:
E (171) vfs_fat_sdmmc: slot init failed (0x103). E (171) SDC: Failed to initialize the card (ESP_ERR_INVALID_STATE). Make sure SD card lines have pull-up resistors in place. Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.

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