1

I'd like to use this function to call the the PlaySoundA function, but the sound file I am trying to play does not open.

void AudioClass::playAudio(const char* incomingData, const char* filePath)
{

    char buffer[100]; // <- danger, only storage for 100 characters.
    strncpy_s(buffer, filePath, sizeof(buffer));
    strncat_s(buffer, incomingData, sizeof(buffer));

    PlaySoundA(buffer, NULL, SND_FILENAME);
}

As I found out, if the argument for the LPCSTR pszSound parameter of PlaySoundA() is given as a string (e.g. "C:/Users/User/Documents/sound.wav"), i.e. the full path of the file is given, the sound will play.

I would like to combine the incomingData parameter (file name) and the filePath parameter, for which I used a buffer.

If the file cannot be found, the default system sound should play (it was a beep in my case), but this is no longer the case; even though SND_NODEFAULT flag was not set, in which case PlaySoundA() would return silently, without playing the default system sound.

https://learn.microsoft.com/en-us/previous-versions/dd743680(v%3Dvs.85)

Is it possible that the argument I am trying to pass in not compatible with LPCSTR pszSound parameter?

While running the debugger, the buffer variable seems to hold the whole path (C:/Users/User/Documents/sound.wav\r\n), but why is there a \r\n prefix at the end?

Definitions:

#define MAX_DATA_LENGTH 255

char incomingData[MAX_DATA_LENGTH];

const char* filePath {"C:/Users/User/Desktop/"};

//Arduino SerialPort object
SerialPort *arduino;

//Audio file AudioClass object
AudioClass* audio;

playAudio() is called here:

void exampleReceiveData(void)
{
    int readResult = arduino->SerialPort::readSerialPort(incomingData, MAX_DATA_LENGTH);

    audio->AudioClass::playAudio(incomingData, filePath);

    Sleep(10000);
}

EDIT_1: the length of the real file path I use is shorter than 100 characters.

EDIT_2: I get this warning: String 'buffer' might not be zero-terminated.

  • `\r\n` those are special characters, when You write on the keyboard you don't see them but `\r` is carriage return and `\n` is new line character system adds them automatically use this to clear the input https://stackoverflow.com/questions/1488775/c-remove-new-line-from-multiline-string – Take_Care_ May 13 '20 at 11:23
  • There is an `"\r\n"` there because you read it from the serial port, so it must come from the other end. – molbdnilo May 13 '20 at 11:23
  • The library you are using is too primitive to be useful. As-is, you need to only read *one* byte, loop until you get \r\n. You can then also get rid of that giant sleep as well. Best to keep shopping for one that has a Readline() style function. – Hans Passant May 13 '20 at 11:46
  • @Hans Passant: yes, if the giant sleep stays giant, the sound stops playing after a while. Reducing sleep to a lower amount helps. – Marschall Gábor May 13 '20 at 12:16
  • Its just a hack to lower the odds for the bug. If the arduino happens to send a string several milliseconds before the sleep expires then it still won't work, you still get a partial string. Do it right and you don't need any sleep at all. – Hans Passant May 13 '20 at 13:12

1 Answers1

0

The \r\n at the end comes from the serial port: https://www.arduino.cc/reference/en/language/functions/communication/serial/println

You can skip the characters when copying:

    strncat_s(buffer, incomingData, strnlen(incomingData) - 2);
Cosmin
  • 21,216
  • 5
  • 45
  • 60