All Projects → audiooffler → JucyFluttering

audiooffler / JucyFluttering

Licence: GPL-3.0 license
A simple iOS &Android example for how to integrate Flutter (Dart) as user interface and JUCE (C++) as backend.

Programming Languages

c
50402 projects - #5 most used programming language
Objective-C++
1391 projects
dart
5743 projects
C++
36643 projects - #6 most used programming language
java
68154 projects - #9 most used programming language
objective c
16641 projects - #2 most used programming language
ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to JucyFluttering

juceSynths
Collection of JUCE synthesisers utilising the Maximilian library.
Stars: ✭ 78 (-4.88%)
Mutual labels:  juce
osmid
osmid is a tool to bridge MIDI and OSC. It is currently in use in Sonic Pi
Stars: ✭ 63 (-23.17%)
Mutual labels:  juce
pMix2
pMix - a preset interpolator, plug-in chainer and Faust IDE written with JUCE
Stars: ✭ 84 (+2.44%)
Mutual labels:  juce
melatonin audio sparklines
Sparklines For JUCE AudioBlocks
Stars: ✭ 60 (-26.83%)
Mutual labels:  juce
freesound-juce
A JUCE client for accessing the Freesound API
Stars: ✭ 17 (-79.27%)
Mutual labels:  juce
juce-plugin-ci
Cross-platform CI for JUCE audio plugins with Github Actions
Stars: ✭ 51 (-37.8%)
Mutual labels:  juce
juce-cookbook
Collection of tutorials & resources for the C++ library JUCE
Stars: ✭ 58 (-29.27%)
Mutual labels:  juce
PhaseVocoder
A C++ based phase vocoder example that allows pitch and timescale modifications of incoming signals. UI built with Juce.
Stars: ✭ 44 (-46.34%)
Mutual labels:  juce
Juce
JUCE is an open-source cross-platform C++ application framework for desktop and mobile applications, including VST, VST3, AU, AUv3, RTAS and AAX audio plug-ins.
Stars: ✭ 3,841 (+4584.15%)
Mutual labels:  juce
popsicle
Popsicle aims to bridge the JUCE c++ framework to python.
Stars: ✭ 102 (+24.39%)
Mutual labels:  juce
ChowPhaser
Phaser effect based loosely on the Schulte Compact Phasing 'A'
Stars: ✭ 51 (-37.8%)
Mutual labels:  juce
DarkMark
Marking up images for use with Darknet.
Stars: ✭ 62 (-24.39%)
Mutual labels:  juce
Amalgamate
A tool for creating an amalgamation from C and C++ sources. Forked from https://github.com/vinniefalco/Amalgamate.
Stars: ✭ 17 (-79.27%)
Mutual labels:  juce
DAFx19-Gamelanizer
Accompanying material for the paper 'A Real-Time Audio Effect Plug-In Inspired by the Processes of Traditional Indonesian Gamelan Music'
Stars: ✭ 33 (-59.76%)
Mutual labels:  juce
pamplejuce
A JUCE Plugin CI template. JUCE 7 & Catch2 with macOS notarization and Windows EV code signing on Github Actions
Stars: ✭ 115 (+40.24%)
Mutual labels:  juce
Lemons
A library of utilities and building blocks for JUCE-based apps and plugins
Stars: ✭ 28 (-65.85%)
Mutual labels:  juce
DSP-Testbench
A DSP Testbench for users of the JUCE framework
Stars: ✭ 40 (-51.22%)
Mutual labels:  juce
juce faustllvm
JUCE Module for the libfaust JIT compiler
Stars: ✭ 32 (-60.98%)
Mutual labels:  juce
AtomSynth
A modular synthesizer built using the juce api.
Stars: ✭ 20 (-75.61%)
Mutual labels:  juce
Roboverb
A VST / VST3 / AU / LV2 Reverb Plugin
Stars: ✭ 48 (-41.46%)
Mutual labels:  juce

Jucy Fluttering

A simple mobile app example (iOS, Android) that uses a Flutter (Dart) UI and JUCE (C++) as backend.

Project Setup and Boilerplates

  • Created a JUCE GUI project JucyFluttering with Android and iOS exporters (well it does not really show a GUI, but has a message loop running, to provide timers, event handling etc.)

  • Created a flutter plugin project (subfolder fluttering) for platforms android and iOs, using Java for android, and ObjectiveC for iOS

    • flutter create --template=plugin --platforms=android,ios -a java -i objc fluttering
    • the .dart source file are placed in fluttering/lib

JUCE is already does a good job at setting up all the platform-dependend boilerplate code to instantiate and run iOs and Android apps. Some adjustments had to be done to do the Flutter instantiation part too, as documented here:

Android Application and Android Activity

Made custom activity and application Java class files, placed in Sources/Android.

  • The Actvity extends the FlutteringActivity class
  • The Application initialises JUCE, but also and instantiates, pre-warms and caches the Flutter Engine, and sets the initial Flutter navigation route to '/'

Android Exporter Setup in Projucer Project and Android Gradle

Some manual configuration for the Projucers Android exporter was necessary:

  • Java Source code folders:

    Source/Android
    
  • Custom Android Activity:

    eu.selfhost.audiooffler.jucyfluttering.FlutteringActivity
    
  • Custom Android Application:

    eu.selfhost.audiooffler.jucyfluttering.FlutteringApplication
    
  • Module Dependencies:

    implementation project(':flutter')
    
  • Extra module's build.gradle content:

    defaultConfig {
        ndk {
            // filter for architectures supported by Flutter
            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
    }
    
    compileOptions {
        // Flutter Android engine uses Java 8 features
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
    
  • Custom settings.gradle content:

    setBinding(new Binding([gradle: this]))
    evaluate(new File(
        settingsDir.parentFile.parentFile,
        'fluttering/.android/include_flutter.groovy'
    ))
    
  • Android Theme:

    @android:style/Theme.NoTitleBar
    

Projucer can't create / manipulate a gradle.properties file, but this is needed for Flutter

  • The file with the following content was manually placed at Builds/Android folder of this repository, it won't get overwritten by the Projucre, just do not delete it manually:

    android.useAndroidX=true
    android.enableJetifier=true
    

iOS UIApplicationDelegate

Made a custom App Delegate class, placed at Sources/iOS. This is an UIApplicationDelegate for running JUCE and Flutter in an iOS app. It's .mm File also has the START_JUCE_APPLICATION_WITH_CUSTOM_DELEGATE call to automatically start the JUCEApplication with this Delegate, as documented in JUCE/modules/juce_events/messages/juce_Initialisation.h. The delegate takes care of:

  • Juce Initialisation and handling
  • Flutter Engine Initalisation and handling
  • UIWindow (showing the Flutter View)
  • FlutterViewController
  • FlutterPluginAppLifeCycleDelegate

iOS CocooaPods and iOS Exporter Setup in Projucer Project

CocoaPods is needed for FLutter integration.

  • If do not have it installed yet (check with which pod), do so with sudo gem install cocoapod
  • A Podfile was made manually and placed in this repository (Builds/iOS/Podfile), containing the following. The Projucer won't overwite it, just do not delete it manually.
      platform :ios, '9.0'
    
      flutter_application_path = '../../fluttering'
      load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
    
      target 'Jucy Fluttering - App' do
      
      install_all_flutter_pods(flutter_application_path)
    
      end
    

In Projucer, some iOS export settings had to be configured:

  • To make it work with CocoaPods (as found in adamski's thread in the JUCE forum), for all build target configuations (Release/Debug), set Binary Location:
    $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
    
  • Custom PList
    <plist>
        <dict>
            <key>UIBackgroundModes</key>
            <array>
                <string>fetch</string>
                <string>remote-notification</string>
            </array>
        </dict>
    </plist>
    

Build and Debug

Android

No extra steps needed building. The project can be opened with Android Studio from the Projucer or by opening the Builds/Android project folder in Android Studio. If dart support is enabled for the project in Android Studio, it even attaches the flutter debugger. Else, while running / debugging, one may call flutter attach from terminal (first go to cd ./fluttering).

iOS

After saving / exporting with Projucer, the XCode Project can't simply be build as usual for JUCE projects. Two more steps are necassary:

  • from terminal run pod install (first go to cd ./Builds/iOS)
  • then open the generated .xcworkspace project and build that
    • the .xcodeproj would fail, due to the missing Flutter dependencies

While running / debugging from xCode, one may call flutter attach from terminal (first go to cd ./fluttering).

Calls and Messages between JUCE/C++ and Flutter/Dart

Check out the Flutter/dart:ffi documentation for the basic setup of accessing nativ C++ code from Flutter/dart.

Some examples can be found in Sources/JucyFlutteringInterop.h and the dart counterparts in fluttering/lib/juce_fluttering_interop.dart.

Dart code for executing simple JUCE/C++ functions

  • Externalized JUCE/C++ functions can be called from Fluttter/Dart via dart:ffi NativeFunctions, since the dart isolate (thread) will execute it.
  • Some boilercode / wrapping is still needed. See fluttering/lib/juce_fluttering_interop.dart.

Getting Strings from JUCE/C++ into dart

  • For getting juce::Strings, JUCE has to return UTF-8 char* pointers
  • If the String is local it has to be copied to memory or it will get lost on return.
  • This can be done using toRawUTF8, malloc and strcpy, see the example in EXTERN_C const char *getAppName() in Source/JucyFlutteringInterop.h, using the helper function const char *copyStringToUTF8(String juceString) from the same file
  • The dart caller then can convert this to a dart String, using fromUtf8 and call free on the returned Pointer<Utf8>, utilizing import package:ffi/ffi.dart. See tthe example in fluttering/lib/juce_fluttering_interop.dart

Asynchronous Messages from JUCE/C++ to Flutter (instead of callbacks)

Problem:

  • Access to classes and values is only allowed from the same isolate!
  • JUCE Message Loop (e.g. juce::Timer) or AudioCallback Threads (e.g. juce::AudioProcessor) won't run in the same isolate as Flutter/Dart UI.
  • Therefore, just registering callback dart:ffi function pointers in your JUCE/C++ code will not be sufficient. (Except if the callback was called from some C++ function that was started from dart).

Solution:

  • Different isolates can communicate by sending values through ports (see ReceivePort, SendPort).
  • To access the dart native API from C++, files from GitHub: dart-lang/sdk/runtime/include where included in the JUCE project Source/DartApiDL (the folder was added to the header search paths for all Build/Debug targets). see https://github.com/mraleph/go_dart_ffi_example
  • Init by calling the NativeAPI from dart (that will be the receiver) and tell JUCE/C++ the port.
  • From then on JUCE/C++ may send messages containing objects with int, double or UTF-8 char* string pointers to the dart receiver port.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].