Hi!
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:
| if (fplPlayAudio() == fplAudioResultType_Success) {
|
I get to here:
| fpl__WaitForAudioEvent(&audioState->startEvent);
|
...where if I "step in", thread #4 to segfaults at this line in fplMemoryClear:
| 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);
}
|