Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue after latest update. #484

Open
rickyelqasem opened this issue May 30, 2024 · 17 comments
Open

Issue after latest update. #484

rickyelqasem opened this issue May 30, 2024 · 17 comments

Comments

@rickyelqasem
Copy link

I'm using the TMRPcm library and previously sat 2.1.2 with no problems. After updating sdfat to latest version I get the following errors on compile:

TMRpcm.cpp:1442:61: error: use of deleted function 'SdFile::SdFile(const SdFile&)'

SdFat.h:468:7: error: use of deleted function 'PrintFile::PrintFile(const PrintFile&)'

ArduinoFiles.h:43:7: error: 'constexpr FatFile::FatFile(const FatFile&)' is private within this context

Could you point me in the right direction? and Sorry if its been documented.

@gioreva
Copy link

gioreva commented May 30, 2024

I had the same problem.
Thanks to codeium.com IA, I solved it this way:
void AudioZeroClass::play(FsFile myFile) {
to
void AudioZeroClass::play(FsFile& myFile) {

@gioreva
Copy link

gioreva commented May 30, 2024

Ok, compiler no not give me error, but function do not read the file.
I cannot find a solution.

@greiman
Copy link
Owner

greiman commented May 30, 2024

In the latest version of SdFat the copy constructor for File classes is private to prevent multiple copies of a file object.

A function with this signature will create copy of myFile on the stack.

void AudioZeroClass::play(FsFile myFile) {

This can cause bugs since the File object in the calling program is not updated.

With this call by reference only one copy of the file object exists:

void AudioZeroClass::play(FsFile& myFile) {

I you really want to have multiple, maybe inconsistent, copies of a file object you can edit SdFatConfig.h here.

@gioreva
Copy link

gioreva commented May 30, 2024

void AudioZeroClass::play(FsFile& myFile) {

By changing only the definition of audiozero, the file is played, but only the first time.
The following times it does not play.
As if close and open does not it restart.

In the previous version, this did not happen.

`void AudioZeroClass::play(File myFile) {
dacConfigure();
tcConfigure(__sampleRate);
__StartFlag = false;
while (myFile.available()) {
if (!__StartFlag) // Prima volta
{
__SampleIndex = 45; // 45 byte sono l'Header del Wav con le informazioni
myFile.read(__WavSamples, __NumberOfSamples);
__HeadIndex = 0;

  /*once the buffer is filled for the first time the counter can be started*/
   tcStartCounter();
   __StartFlag = true;
}
else  // Successive volte
{
   uint32_t current__SampleIndex = __SampleIndex;
  
   if (current__SampleIndex > __HeadIndex) {   //mentre esce il buffer salendo
     myFile.read(&__WavSamples[__HeadIndex], current__SampleIndex - __HeadIndex);
     __HeadIndex = current__SampleIndex;        
  }
  else if (current__SampleIndex < __HeadIndex) {  //Quando il puntatore dei dati che escono torna a zero
    myFile.read(&__WavSamples[__HeadIndex], __NumberOfSamples -1 - __HeadIndex);  // riempe la fine
    myFile.read(__WavSamples, current__SampleIndex);
    __HeadIndex = current__SampleIndex;
    __HeadIndex = 0;
  }  // analogWrite(A0, __WavSamples[__SampleIndex++]<<2);
}

}
myFile.close();
delay(100);
tcDisable();
tcReset();
analogWrite(A0, 512);
}`

@greiman
Copy link
Owner

greiman commented May 30, 2024

By changing only the definition of audiozero, the file is played, but only the first time.
The following times it does not play.
As if close and open does not it restart.

This is because of the change from call by value to call by reference. The file object in the calling program now used instead of a copy so play now closes the file object in the calling program.

Generally having multiple copies of a file object for an open file causes bugs.

If you don't want to fix the multiple copy problem just edit SdFatConfig.h and allow multiple copies.

@gioreva
Copy link

gioreva commented May 30, 2024

How do I get the file to play again?

@greiman
Copy link
Owner

greiman commented May 30, 2024

How do I get the file to play again?

See the above link to the place to change in SdFatConfig.h.

@gioreva
Copy link

gioreva commented May 30, 2024 via email

@greiman
Copy link
Owner

greiman commented May 30, 2024

at line 68 of SdFatConfig.h
change

#define FILE_COPY_CONSTRUCTOR_SELECT FILE_COPY_CONSTRUCTOR_PRIVATE

to

#define FILE_COPY_CONSTRUCTOR_SELECT FILE_COPY_CONSTRUCTOR_PUBLIC 

@rickyelqasem
Copy link
Author

at line 68 of SdFatConfig.h change

#define FILE_COPY_CONSTRUCTOR_SELECT FILE_COPY_CONSTRUCTOR_PRIVATE

to

#define FILE_COPY_CONSTRUCTOR_SELECT FILE_COPY_CONSTRUCTOR_PUBLIC 

Does this fix my issue too?

@rickyelqasem
Copy link
Author

FILE_COPY_CONSTRUCTOR_PUBLIC

looks like it did... now compiles without error.

@greiman
Copy link
Owner

greiman commented May 30, 2024

Does this fix my issue too?

It doesn't fix the fundamental issue of multiple copies of a file object but it will allow call by value.

@rickyelqasem
Copy link
Author

It's been a long time since I looked at my code, but am I creating multiple instances?

SdFat sd;
SdFile file;
File dir;

is SdFile an inherited class of File ?

By the way, I'm a novice at C++, so it's a miracle how I managed to get my coding working in the first place.

@greiman
Copy link
Owner

greiman commented May 30, 2024

is SdFile an inherited class of File ?

File is a typedef. The whole class structure has become very complex to allow SdFat to run on many boards. Many of the definitions are here.

There are two basic ways to create a copy of an object. The copy constructor which makes a copy on the stack for call by value.

void AudioZeroClass::play(FsFile myFile)

And the assignment operator:

File file = sd.open("name.txt", O_RDWR | O_CREAT);
File fileCopy = file;  // second copy

The state of the file is in the File object so multiple objects for a file can cause problems. If one object is used for write and the file is closed with another object, file system corruption is likely.

@rickyelqasem
Copy link
Author

I had the same problem. Thanks to codeium.com IA, I solved it this way: void AudioZeroClass::play(FsFile myFile) { to void AudioZeroClass::play(FsFile& myFile) {

@gioreva BTW I added sdfat to the AudioZero library 5 years ago. Just interested re you using my library https://github.com/rickyelqasem/AudioZeroSdFat or did you modify it yourself?

@gioreva
Copy link

gioreva commented May 30, 2024

I think I made a lot of changes.
Especially to use more available wav, e.g. stereophonic, generated online.

But I haven't figured out how I can loop the playback, leaving SdFat private.
Now it only plays the message the first time.

@greiman
Copy link
Owner

greiman commented Jun 1, 2024

But I haven't figured out how I can loop the playback, leaving SdFat private.
Now it only plays the message the first time.

I would put a rewind at the start of void AudioZeroClass::play(FsFile& myFile) like this:

myFile.rewind();

and remove the myFile.close() at the end.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants