I have been trying for weeks to create a simple audio player app in flutter and JUCE, flutter does the UI ,whereas JUCE does the heavy lifting of playback. flutter sends a path of file to JUCE ,JUCE loads and plays the file.In JUCE i created a simple AudioPlayer .All seem to work so well,Flutter is able to call juce functions the only issue so far seen is that the app crashes immediately i call a function to create AudioPlayer in extern “C” block. error logs
I/JUCE (16555): Creating AudioPlayer…
I/JUCE (16555): JUCE Assertion failure in juce_Threads_android.cpp:67
F/libc (16555): Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid 16583 (1.ui), pid 16555 (tum_new_fluuter)
Build fingerprint: ‘google/sdk_gphone64_x86_64/emu64xa:15/AE3A.240806.036/12592187:user/release-keys’
Revision: ‘0’
ABI: ‘x86_64’
Timestamp: 2025-03-13 14:59:23.445518610+0300
Process uptime: 21s
Cmdline: com.example.tum_new_fluuter
pid: 16555, tid: 16583, name: 1.ui >>> com.example.tum_new_fluuter <<<
uid: 10209
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000
Cause: null pointer dereference’’
Extern “C” block;`extern “C” {
AudioPlayer* createAudioPlayer() {
DBG(“createAudioPlayer: Creating new instance…”);
return new AudioPlayer();
}
void destroyAudioPlayer(AudioPlayer* player) {
DBG(“destroyAudioPlayer: Destroying instance…”);
delete player;
}
void playAudioFile(AudioPlayer* player, const char* filePath) {
if (player && filePath) {
juce::MessageManager::callAsync(player, filePath {
player->loadFile(juce::File(filePath));
player->play();
});
}
}
void stopAudioFile(AudioPlayer* player) {
if (player) {
juce::MessageManager::callAsync(player {
player->stop();
});
}
}
int isAudioPlaying(AudioPlayer* player) {
if (player) {
return player->isPlaying() ? 1 : 0;
}
return 0;
}
}
AudioPlayer;
#include “AudioPlayer.h”
AudioPlayer::AudioPlayer() {
DBG(“AudioPlayer: Initializing…”);
formatManager.registerBasicFormats();
deviceManager.initialiseWithDefaultDevices(0, 2);
setAudioChannels(0, 2);
}
AudioPlayer::~AudioPlayer() {
DBG(“AudioPlayer: Shutting down…”);
transportSource.setSource(nullptr);
shutdownAudio();
}
void AudioPlayer::loadFile(const juce::File& file) {
transportSource.stop();
transportSource.setSource(nullptr);
DBG("Loading file: " + file.getFullPathName());
if (!file.existsAsFile()) {
DBG("ERROR: File does not exist!");
return;
}
auto* reader = formatManager.createReaderFor(file);
if (reader == nullptr) {
DBG("ERROR: Could not create reader for file! " + file.getFullPathName());
return;
}
auto newSource = std::make_unique<juce::AudioFormatReaderSource>(reader, true);
transportSource.setSource(newSource.get(), 0, nullptr, reader->sampleRate);
readerSource = std::move(newSource);
DBG("File loaded successfully!");
}
void AudioPlayer::play() {
if (!readerSource) {
DBG(“play: ERROR - No file loaded!”);
return;
}
transportSource.setPosition(0.0);
transportSource.start();
DBG("play: Playing audio...");
}
void AudioPlayer::stop() {
transportSource.stop();
DBG(“stop: Stopping audio…”);
}
bool AudioPlayer::isPlaying() const {
return transportSource.isPlaying();
}
void AudioPlayer::prepareToPlay(int samplesPerBlockExpected, double sampleRate) {
transportSource.prepareToPlay(samplesPerBlockExpected, sampleRate);
}
void AudioPlayer::getNextAudioBlock(const juce::AudioSourceChannelInfo& bufferToFill) {
if (readerSource) {
transportSource.getNextAudioBlock(bufferToFill);
} else {
bufferToFill.clearActiveBufferRegion();
}
}
void AudioPlayer::releaseResources() {
transportSource.releaseResources();
}` for now am considering android platform only