expo-juce 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,13 +8,9 @@
8
8
  #include "PolySynthProcessor.h"
9
9
  #include "TransportEngine.h"
10
10
 
11
- // Initialize JUCE at dylib load timeBEFORE any static C++ objects run.
12
- // This is critical: without MessageManager, JUCE statics crash.
13
- __attribute__((constructor))
14
- static void initJuceEarly() {
15
- juce::MessageManager::getInstance();
16
- juce::initialiseJuce_GUI();
17
- }
11
+ // JUCE init moved to setup()raw pointers at file scope eliminate
12
+ // the static init problem, and constructor doesn't guarantee main thread.
13
+ static bool sJuceInitialized = false;
18
14
 
19
15
  // Lightweight AudioIODeviceCallback that drives an AudioProcessorGraph.
20
16
  // Replaces juce::AudioProcessorPlayer (from juce_audio_utils, which we don't use).
@@ -107,12 +103,19 @@ static TransportEngine* sTransport = nullptr;
107
103
 
108
104
  NSLog(@"[BeeperAudioEngine] Initializing JUCE audio stack...");
109
105
 
110
- // 0. Configure AVAudioSession before JUCE takes over
106
+ // 0. Initialize JUCE on main thread (must happen before any JUCE API use)
107
+ if (!sJuceInitialized) {
108
+ NSLog(@"[BeeperAudioEngine] Initializing JUCE MessageManager on main thread...");
109
+ juce::MessageManager::getInstance();
110
+ juce::initialiseJuce_GUI();
111
+ sJuceInitialized = true;
112
+ }
113
+
114
+ // 1. Configure AVAudioSession — Playback only (no microphone needed)
111
115
  NSError *sessionError = nil;
112
116
  AVAudioSession *session = [AVAudioSession sharedInstance];
113
- [session setCategory:AVAudioSessionCategoryPlayAndRecord
114
- withOptions:(AVAudioSessionCategoryOptionMixWithOthers |
115
- AVAudioSessionCategoryOptionDefaultToSpeaker)
117
+ [session setCategory:AVAudioSessionCategoryPlayback
118
+ withOptions:AVAudioSessionCategoryOptionMixWithOthers
116
119
  error:&sessionError];
117
120
  if (sessionError) {
118
121
  NSLog(@"[BeeperAudioEngine] AVAudioSession category error: %@", sessionError);
@@ -123,9 +126,6 @@ static TransportEngine* sTransport = nullptr;
123
126
  NSLog(@"[BeeperAudioEngine] AVAudioSession activation error: %@", sessionError);
124
127
  }
125
128
 
126
- // 1. Initialize MessageManager (attaches to existing CFRunLoop)
127
- juce::MessageManager::getInstance();
128
-
129
129
  // 2. Create transport
130
130
  sTransport = new TransportEngine();
131
131
 
@@ -143,12 +143,12 @@ static TransportEngine* sTransport = nullptr;
143
143
  return;
144
144
  }
145
145
 
146
- // 5. Create AudioProcessorGraph
146
+ // 5. Create AudioProcessorGraph and add nodes BEFORE preparing
147
+ double sr = sDeviceManager->getAudioDeviceSetup().sampleRate;
148
+ int bufSize = sDeviceManager->getAudioDeviceSetup().bufferSize;
149
+
147
150
  sGraph = new juce::AudioProcessorGraph();
148
- sGraph->setPlayConfigDetails(0, 2, sDeviceManager->getAudioDeviceSetup().sampleRate,
149
- sDeviceManager->getAudioDeviceSetup().bufferSize);
150
- sGraph->prepareToPlay(sDeviceManager->getAudioDeviceSetup().sampleRate,
151
- sDeviceManager->getAudioDeviceSetup().bufferSize);
151
+ sGraph->setPlayConfigDetails(0, 2, sr, bufSize);
152
152
 
153
153
  // 6. Add PolySynthProcessor node
154
154
  auto synthProcessor = std::make_unique<PolySynthProcessor>();
@@ -171,7 +171,10 @@ static TransportEngine* sTransport = nullptr;
171
171
  {outputNode->nodeID, 1}
172
172
  });
173
173
 
174
- // 9. Create player and attach to device
174
+ // 9. Prepare graph AFTER all nodes/connections are set up
175
+ sGraph->prepareToPlay(sr, bufSize);
176
+
177
+ // 10. Create player and attach to device
175
178
  sPlayer = new GraphPlayer();
176
179
  sPlayer->setProcessor(sGraph);
177
180
  sDeviceManager->addAudioCallback(sPlayer);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-juce",
3
- "version": "0.4.1",
3
+ "version": "0.5.0",
4
4
  "description": "Realtime DSP w/C++ & JUCE",
5
5
  "type": "module",
6
6
  "main": "build/index.js",