I'm interested in picking up C++ programming, and your fpl seemed like fun thing to start tinkering with :)
I got as far as trying to compile your Simple Audio Playback example here:
https://libfpl.org/docs/page_example_simple_audio.html
However that seems to be for an earlier version of fpl. I managed to patch it up so it at least compiles with v0.9.4 beta, but I couldn't get it to actually play audio (g++, cdt, Ubuntu 20.04). I included my the updated example code below, in case you can use it for something :)
If anyone has any ideas on why I don't get sound, I'll put my debugging attempts below.
The issue seems to be that thread #4 segfaults. Stepping into this line in the example:
1 | if (fplPlayAudio() == fplAudioResultType_Success) { |
I get to here:
1 | fpl__WaitForAudioEvent(&audioState->startEvent); |
...where if I "step in", thread #4 to segfaults at this line in fplMemoryClear:
1 | FPL__MEMORY_CLEAR(uint64_t, mem, size, FPL__MEM_SHIFT_64, FPL__MEM_MASK_64); |
and if I try to "step in" the program just exits with code 0.
I have several audio devices available if that matters, but just changing device doesn't seem to help.
As you can see in my updated example code below, I added a few lines (under "Find audio device", now commented out) that print out what audio devices are available. For me that gives:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Multiple audio devices available: 0: Playback/recording through the PulseAudio sound server 1: PulseAudio Sound Server 2: HDA Intel PCH, ALC3266 Analog 2.1 Surround output to Front and Subwoofer speakers 3: HDA Intel PCH, ALC3266 Analog 4.0 Surround output to Front and Rear speakers 4: HDA Intel PCH, ALC3266 Analog 4.1 Surround output to Front, Rear and Subwoofer speakers 5: HDA Intel PCH, ALC3266 Analog 5.0 Surround output to Front, Center and Rear speakers 6: HDA Intel PCH, ALC3266 Analog 5.1 Surround output to Front, Center, Rear and Subwoofer speakers 7: HDA Intel PCH, ALC3266 Analog 7.1 Surround output to Front, Center, Side, Rear and Woofer speakers 8: HDA Intel PCH, HDMI 0 HDMI Audio Output 9: HDA Intel PCH, HDMI 1 HDMI Audio Output 10: HDA Intel PCH, HDMI 2 HDMI Audio Output 11: HDA Intel PCH, HDMI 3 HDMI Audio Output 12: HDA Intel PCH, HDMI 4 HDMI Audio Output 13: HDA Intel PCH, HDMI 0 Direct sample mixing device 14: HDA Intel PCH, HDMI 1 Direct sample mixing device 15: HDA Intel PCH, HDMI 2 Direct sample mixing device Using audio device: Playback/recording through the PulseAudio sound server |
Here's the my updated example code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #define FPL_IMPLEMENTATION #define FPL_NO_WINDOW #include "final_platform_layer.h" #include <math.h> // sinf struct AudioTest { uint32_t toneHz; uint32_t toneVolume; uint32_t runningSampleIndex; uint32_t wavePeriod; bool useSquareWave; }; static const float PI32 = 3.14159265359f; static uint32_t FillAudioBuffer(const fplAudioDeviceFormat *nativeFormat, const uint32_t frameCount, void *outputSamples, void *userData) { AudioTest *audioTest = (AudioTest *)userData; fplAssert(audioTest != nullptr); fplAssert(nativeFormat->type == fplAudioFormatType_S16); uint32_t result = 0; int16_t *outSamples = (int16_t *)outputSamples; uint32_t halfWavePeriod = audioTest->wavePeriod / 2; for (uint32_t frameIndex = 0; frameIndex < frameCount; ++frameIndex) { int16_t sampleValue; if (audioTest->useSquareWave) { sampleValue = ((audioTest->runningSampleIndex++ / halfWavePeriod) % 2) ? (int16_t)audioTest->toneVolume : -(int16_t)audioTest->toneVolume; } else { float t = 2.0f * PI32 * (float)audioTest->runningSampleIndex++ / (float)audioTest->wavePeriod; sampleValue = (int16_t)(sinf(t) * audioTest->toneVolume); } for (uint32_t channelIndex = 0; channelIndex < nativeFormat->channels; ++channelIndex) { *outSamples++ = sampleValue; ++result; } } return result; } int main(int argc, char **argv) { int result = -1; // Initialize to default settings which is 48 KHz and 2 Channels fplSettings settings; fplSetDefaultSettings(&settings); // Optionally overwrite audio settings if needed // Setup some state for the sine/square wave generation AudioTest audioTest = {}; audioTest.toneHz = 256; audioTest.toneVolume = 1000; audioTest.wavePeriod = settings.audio.targetFormat.sampleRate / audioTest.toneHz; audioTest.useSquareWave = false; // Provide client read callback and optionally user data settings.audio.clientReadCallback = FillAudioBuffer; settings.audio.userData = &audioTest; settings.audio.targetFormat.type = fplAudioFormatType_S16; settings.audio.targetFormat.channels = 2; settings.audio.targetFormat.sampleRate = 48000; // Disable auto start/stop of audio playback settings.audio.startAuto = false; settings.audio.stopAuto = false; // Find audio device if (fplPlatformInit(fplInitFlags_Audio, &settings)) { fplAudioDeviceInfo audioDevices[16] = {}; uint32_t deviceCount = fplGetAudioDevices(audioDevices, fplArrayCount(audioDevices)); if (deviceCount > 0) { //fplConsoleFormatOut("Multiple audio devices available:\n"); //for (int i = 0; i < deviceCount; i++) { // fplConsoleFormatOut("%i: %s\n", i, audioDevices[i].name); //} settings.audio.targetDevice = audioDevices[0]; fplConsoleFormatOut("Using audio device: %s\n", settings.audio.targetDevice.name); } fplPlatformRelease(); } // Initialize the platform with audio enabled and the settings if (fplPlatformInit(fplInitFlags_Audio, &settings)) { // You can overwrite the client read callback and user data if you want to fplSetAudioClientReadCallback(FillAudioBuffer, &audioTest); // Start audio playback (This will start calling clientReadCallback regulary) if (fplPlayAudio() == fplAudioResultType_Success) { fplConsoleFormatOut("Success!\n"); // Print out the native audio format fplAudioDeviceFormat nativeFormat; fplGetAudioHardwareFormat(&nativeFormat); fplConsoleFormatOut("Audio with %lu KHz and %lu channels is playing, press any key to stop playback...\n", nativeFormat.sampleRate, nativeFormat.channels); // Wait for any key presses fplConsoleWaitForCharInput(); // Stop audio playback fplStopAudio(); } // Release the platform fplPlatformRelease(); result = 0; } return(result); } |