This commit is contained in:
Stefano D'Angelo 2023-08-04 15:08:46 +02:00
parent 6d92e83b57
commit 0a586e9764
78 changed files with 1053 additions and 7 deletions

8
TODO
View File

@ -1,9 +1,3 @@
0.6.0
-----
code:
* android, ios
1.0.0 1.0.0
----- -----
@ -100,7 +94,7 @@ build system:
* VC, XCode, etc project files? * VC, XCode, etc project files?
* single header(s) * single header(s)
* cross compile (rpi etc.) * cross compile (rpi etc.)
* consider tuist (https://tuist.io/), bazel (https://bazel.build/), pants (https://www.pantsbuild.org/), buck (https://buck2.build/), please (https://please.build/index.html) for mobile apps * better use of xcodegen (see xcode warnings) and/or consider tuist (https://tuist.io/), bazel (https://bazel.build/), pants (https://www.pantsbuild.org/), buck (https://buck2.build/), please (https://please.build/index.html) for mobile apps
* homogenize android and ios common code (e.g., same index) * homogenize android and ios common code (e.g., same index)
-- --

View File

@ -0,0 +1,24 @@
/*
* Brickworks
*
* Copyright (C) 2023 Orastron Srl unipersonale
*
* Brickworks is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* Brickworks is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Brickworks. If not, see <http://www.gnu.org/licenses/>.
*
* File author: Stefano D'Angelo, Paolo Marrone
*/
char audioStart();
void audioStop();
void setParameter(int i, float v);
float getParameter(int i);

View File

@ -0,0 +1,102 @@
/*
* Brickworks
*
* Copyright (C) 2023 Orastron Srl unipersonale
*
* Brickworks is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* Brickworks is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Brickworks. If not, see <http://www.gnu.org/licenses/>.
*
* File author: Stefano D'Angelo, Paolo Marrone
*/
import SwiftUI
import WebKit
import AVFoundation
struct WebView: UIViewRepresentable {
class Coordinator: NSObject, WKScriptMessageHandlerWithReply {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage, replyHandler: @escaping (Any?, String?) -> Void) {
guard let body = message.body as? [String : Any] else { return }
guard let name = body["name"] as? String else { return }
switch (name) {
case "needAudioPermission":
replyHandler(AVCaptureDevice.authorizationStatus(for: .audio) != .authorized, nil)
break;
case "requestAudioPermission":
AVAudioSession.sharedInstance().requestRecordPermission { granted in }
replyHandler(nil, nil)
break;
case "audioStart":
replyHandler(audioStart() != 0, nil)
break;
case "audioStop":
audioStop()
replyHandler(nil, nil)
break;
case "setParameter":
guard let index = body["index"] as? Int32 else { return }
guard let value = body["value"] as? Double else { return }
setParameter(index, Float(value))
replyHandler(nil, nil)
break;
case "getParameter":
guard let index = body["index"] as? Int32 else { return }
let v = getParameter(index)
replyHandler(v, nil)
break;
default:
break;
}
}
}
func makeCoordinator() -> Coordinator {
return Coordinator()
}
let url: URL
func makeUIView(context: Context) -> WKWebView {
let configuration = WKWebViewConfiguration()
configuration.userContentController.addScriptMessageHandler(Coordinator(), contentWorld: .page, name: "listener")
let webView = WKWebView(frame: .zero, configuration: configuration)
webView.isInspectable = true
return webView
}
func updateUIView(_ webView: WKWebView, context: Context) {
let request = URLRequest(url: url)
webView.load(request)
}
}
struct ContentView: View {
var body: some View {
let url = Bundle.main.url(forResource: "index", withExtension: "html")
WebView(url: url!)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
@main
struct templateApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}

View File

@ -0,0 +1,175 @@
<!DOCTYPE html>
<!--
Brickworks
Copyright (C) 2023 Orastron Srl unipersonale
Brickworks is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, version 3 of the License.
Brickworks is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Brickworks. If not, see <http://www.gnu.org/licenses/>.
File author: Stefano D'Angelo, Paolo Marrone
-->
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<script type="text/javascript" src="config.js"></script>
<script type="text/javascript">
function request(data) {
return window.webkit.messageHandlers.listener.postMessage(data);
}
function needAudioPermission() {
return request({ name: "needAudioPermission" });
}
function requestAudioPermission() {
return request({ name: "requestAudioPermission" });
}
function audioStart() {
return request({ name: "audioStart" });
}
function audioStop() {
return request({ name: "audioStop" });
}
function setParameter(index, value) {
return request({ name: "setParameter", index: index, value: value });
}
function getParameter(index) {
return request({ name: "getParameter", index: index });
}
var hasAudioPermission = true;
var audioStarted = false;
var topButtonElem;
var outParamInterval;
function gotAudioPermission() {
hasAudioPermission = true;
topButtonElem.value = "START";
}
window.onload = async function () {
topButtonElem = document.getElementById("topButton");
var paramsElem = document.getElementById("params");
for (var i = 0; i < buses.length; i++)
if (!buses[i].output) {
hasAudioPermission = !await needAudioPermission();
break;
}
topButtonElem.value = hasAudioPermission ? "START" : "INIT";
topButtonElem.addEventListener("click", async function () {
if (hasAudioPermission) {
if (audioStarted) {
clearInterval(outParamInterval);
await audioStop();
paramsElem.innerHTML = "";
topButtonElem.value = "START";
audioStarted = false;
} else {
if (await audioStart()) {
for (var i = 0; i < parameters.length; i++) {
var div = document.createElement("div");
paramsElem.appendChild(div);
var label = document.createElement("label");
label.innerText = parameters[i].name;
div.appendChild(label);
div.appendChild(document.createElement("br"));
var range = document.createElement("input");
range.classList.add("range");
range.setAttribute("type", "range");
range.setAttribute("id", "p" + i);
range.setAttribute("min", 0);
range.setAttribute("max", 1);
range.setAttribute("step", parameters[i].step ? 1 / parameters[i].step : "any");
range.value = parameters[i].defaultValue;
if (parameters[i].output)
range.setAttribute("readonly", "readonly");
else {
let index = i;
range.addEventListener("input",
async function (ev) {
await setParameter(index, parseFloat(ev.target.value));
});
}
div.appendChild(range);
}
outParamInterval = setInterval(
async function () {
for (var i = 0; i < parameters.length; i++)
if (parameters[i].output)
document.getElementById("p" + i).value = await getParameter(i);
}, 50);
topButtonElem.value = "STOP";
audioStarted = true;
} else
alert("Could not start audio");
}
} else {
await requestAudioPermission();
var interval = setInterval(
async function () {
if (!await needAudioPermission()) {
gotAudioPermission();
clearInterval(interval);
}
}, 50);
}
});
};
</script>
<style>
* {
margin: 0;
padding: 0;
user-select: none;
}
body {
margin: 1em;
}
#topButton {
width: 100%;
border: 0;
background-color: #04aa6d;
color: white;
padding: 0.5em;
text-align: center;
margin-bottom: 1em;
padding: 1em;
}
.range {
width: 90%;
}
</style>
</head>
<body>
<input id="topButton" type="button">
<div id="params"></div>
</body>
</html>

View File

@ -0,0 +1,32 @@
COMMON_DIR := ${ROOT_DIR}/../../common/ios
COMMON_SOURCES := index.html app.swift native.mm app-Bridging-Header.h
COMMON_SOURCES_IN := $(addprefix ${COMMON_DIR}/, ${COMMON_SOURCES})
COMMON_SOURCES_OUT := $(addprefix build/gen/src/, ${COMMON_SOURCES})
SOURCES := ${SOURCE} config.js
SOURCES_IN := $(addprefix ${ROOT_DIR}/../src/, ${SOURCES})
SOURCES_OUT := $(addprefix build/gen/src/, ${SOURCES})
BUNDLE_NAME := $(shell echo ${NAME} | sed 's:_:-:g')
all: ${COMMON_SOURCES_OUT} ${SOURCES_OUT} build/gen/${NAME}.xcodeproj
${COMMON_SOURCES_OUT} ${SOURCES_OUT}: ${COMMON_SOURCES_IN} ${SOURCES_IN} | build/gen/src
cp $^ build/gen/src
build/gen/${NAME}.xcodeproj: build/gen/project.yml
xcodegen generate --spec $^
build/gen/project.yml: ${COMMON_DIR}/project.yml | build/gen
cat $^ | sed s:@NAME@:${NAME}:g | sed s:@BUNDLE_NAME@:${BUNDLE_NAME}:g > $@
build/gen build/gen/src:
mkdir -p $@
clean:
rm -fr build
install:
.PHONY: all clean install

View File

@ -0,0 +1,278 @@
/*
* Brickworks
*
* Copyright (C) 2023 Orastron Srl unipersonale
*
* Brickworks is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3 of the License.
*
* Brickworks is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Brickworks. If not, see <http://www.gnu.org/licenses/>.
*
* File author: Stefano D'Angelo, Paolo Marrone
*/
#include <algorithm>
#include <mutex>
#include <vector>
#define MINIAUDIO_IMPLEMENTATION
#define MA_NO_RUNTIME_LINKING
#include <miniaudio.h>
#include "config.h"
#define BLOCK_SIZE 32
#define NUM_BUFS (NUM_CHANNELS_IN > NUM_CHANNELS_OUT ? NUM_CHANNELS_IN : NUM_CHANNELS_OUT)
ma_device device;
#ifdef P_NOTE_ON
CFStringRef midiClientName = NULL;
MIDIClientRef midiClient = NULL;
CFStringRef midiInputName = NULL;
MIDIPortRef midiPort = NULL;
#endif
P_TYPE instance;
float paramValues[NUM_PARAMETERS];
float bufs[NUM_BUFS][BLOCK_SIZE];
#if NUM_CHANNELS_IN != 0
const float *inBufs[NUM_CHANNELS_IN];
#endif
float *outBufs[NUM_CHANNELS_OUT];
std::mutex mutex;
#ifdef P_MEM_REQ
void *mem;
#endif
static void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount) {
(void)pDevice;
#if NUM_CHANNELS_IN == 0
(void)pInput;
#else
const float *x = reinterpret_cast<const float *>(pInput);
#endif
float *y = reinterpret_cast<float *>(pOutput);
if (mutex.try_lock()) {
for (int i = 0; i < NUM_PARAMETERS; i++)
if (config_parameters[i].out)
paramValues[i] = P_GET_PARAMETER(&instance, i);
else
P_SET_PARAMETER(&instance, i, paramValues[i]);
mutex.unlock();
}
ma_uint32 i = 0;
while (i < frameCount) {
ma_uint32 n = std::min(frameCount - i, static_cast<ma_uint32>(BLOCK_SIZE));
int l;
#if NUM_CHANNELS_IN != 0
l = NUM_CHANNELS_IN * i;
for (ma_uint32 j = 0; j < n; j++)
for (int k = 0; k < NUM_CHANNELS_IN; k++, l++)
bufs[k][j] = x[l];
#endif
#if NUM_CHANNELS_IN != 0
P_PROCESS(&instance, inBufs, outBufs, n);
#else
P_PROCESS(&instance, NULL, outBufs, n);
#endif
l = NUM_CHANNELS_OUT * i;
for (ma_uint32 j = 0; j < n; j++)
for (int k = 0; k < NUM_CHANNELS_OUT; k++, l++)
y[l] = bufs[k][j];
i += n;
}
}
#ifdef P_NOTE_ON
void (^midiNotifyBlock)(const MIDINotification *message) = ^(const MIDINotification *message) {
if (message->messageID != kMIDIMsgObjectAdded)
return;
const MIDIObjectAddRemoveNotification *n = reinterpret_cast<const MIDIObjectAddRemoveNotification *>(message);
MIDIEndpointRef endPoint = n->child;
MIDIPortConnectSource(midiPort, endPoint, NULL);
};
void (^midiReceiveBlock)(const MIDIEventList *evtlist, void *srcConnRefCon) = ^(const MIDIEventList *evtlist, void *srcConnRefCon) {
const MIDIEventPacket *p = evtlist->packet;
for (UInt32 i = 0; i < evtlist->numPackets; i++) {
for (UInt32 j = 0; j < p->wordCount; j++) {
UInt32 w = p->words[j];
if ((w & 0xf0000000) != 0x20000000)
continue;
switch (w & 0x00f00000) {
case 0x00900000:
mutex.lock();
P_NOTE_ON(&instance, (w & 0x0000ff00) >> 8, w & 0x000000ff);
mutex.unlock();
break;
case 0x00800000:
mutex.lock();
P_NOTE_OFF(&instance, (w & 0x0000ff00) >> 8);
mutex.unlock();
break;
#ifdef P_PITCH_BEND
case 0x00e00000:
mutex.lock();
P_PITCH_BEND(&instance, ((w & 0x0000007f) << 7) | ((w & 0x00007f00) >> 8));
mutex.unlock();
break;
#endif
#ifdef P_MOD_WHEEL
case 0x00b00000:
if ((w & 0x0000ff00) == 0x00000100) {
mutex.lock();
P_MOD_WHEEL(&instance, w & 0x000000ff);
mutex.unlock();
}
break;
#endif
}
}
p = MIDIEventPacketNext(p);
}
};
#endif
extern "C"
char audioStart() {
#if NUM_CHANNELS_IN == 0
ma_device_config deviceConfig = ma_device_config_init(ma_device_type_playback);
#else
ma_device_config deviceConfig = ma_device_config_init(ma_device_type_duplex);
#endif
deviceConfig.periodSizeInFrames = BLOCK_SIZE;
deviceConfig.periods = 1;
deviceConfig.performanceProfile = ma_performance_profile_low_latency;
deviceConfig.noPreSilencedOutputBuffer = 1;
deviceConfig.noClip = 0;
deviceConfig.noDisableDenormals = 0;
deviceConfig.noFixedSizedCallback = 1;
deviceConfig.dataCallback = data_callback;
deviceConfig.capture.pDeviceID = NULL;
deviceConfig.capture.format = ma_format_f32;
deviceConfig.capture.channels = NUM_CHANNELS_IN;
deviceConfig.capture.shareMode = ma_share_mode_shared;
deviceConfig.playback.pDeviceID = NULL;
deviceConfig.playback.format = ma_format_f32;
deviceConfig.playback.channels = NUM_CHANNELS_OUT;
deviceConfig.playback.shareMode = ma_share_mode_shared;
if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS)
goto err_device_init;
#ifdef P_NOTE_ON
if (midiClientName == NULL) {
midiClientName = CFSTR("template");
if (midiClientName == NULL)
goto err_midiClientName;
}
if (midiClient == (MIDIClientRef)NULL) {
if (MIDIClientCreateWithBlock(midiClientName, &midiClient, midiNotifyBlock) != 0)
goto err_midiClientCreate;
}
if (midiInputName == NULL) {
midiInputName = CFSTR("Input");
if (midiInputName == NULL)
goto err_midiInputName;
}
if (midiPort == (MIDIPortRef)NULL) {
if (MIDIInputPortCreateWithProtocol(midiClient, midiInputName, kMIDIProtocol_1_0, &midiPort, midiReceiveBlock) != 0)
goto err_midiInputPort;
ItemCount n = MIDIGetNumberOfSources();
for (ItemCount i = 0; i < n; i++) {
MIDIEndpointRef endPoint = MIDIGetSource(i);
MIDIPortConnectSource(midiPort, endPoint, NULL);
}
}
#endif
P_INIT(&instance);
P_SET_SAMPLE_RATE(&instance, (float)device.sampleRate);
#ifdef P_MEM_REQ
size_t req = P_MEM_REQ(&instance);
if (req) {
mem = malloc(req);
if (mem == NULL)
goto err_mem_req;
P_MEM_SET(&instance, mem);
} else
mem = NULL;
#endif
for (int i = 0; i < NUM_PARAMETERS; i++) {
paramValues[i] = config_parameters[i].defaultValueUnmapped;
if (!config_parameters[i].out)
P_SET_PARAMETER(&instance, i, paramValues[i]);
}
P_RESET(&instance);
#if NUM_CHANNELS_IN != 0
for (int i = 0; i < NUM_CHANNELS_IN; i++)
inBufs[i] = bufs[i];
#endif
for (int i = 0; i < NUM_CHANNELS_OUT; i++)
outBufs[i] = bufs[i];
if (ma_device_start(&device) != MA_SUCCESS)
goto err_device_start;
return 1;
err_device_start:
#ifdef P_MEM_REQ
free(mem);
err_mem_req:
#endif
#ifdef P_FINI
P_FINI(&instance);
#endif
#ifdef P_NOTE_ON
err_midiInputPort:
err_midiInputName:
err_midiClientCreate:
err_midiClientName:
#endif
ma_device_uninit(&device);
err_device_init:
return 0;
}
extern "C"
void audioStop() {
#ifdef P_MEM_REQ
free(mem);
#endif
#ifdef P_FINI
P_FINI(&instance);
#endif
ma_device_stop(&device);
ma_device_uninit(&device);
}
extern "C"
void setParameter(int i, float v) {
mutex.lock();
paramValues[i] = v;
mutex.unlock();
}
extern "C"
float getParameter(int i) {
mutex.lock();
float v = paramValues[i];
mutex.unlock();
return v;
}

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,20 @@
name: @NAME@
targets:
@NAME@:
platform: iOS
type: application
sources:
- path: src
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: com.orastron.@BUNDLE_NAME@
SWIFT_OBJC_BRIDGING_HEADER: src/app-Bridging-Header.h
HEADER_SEARCH_PATHS:
- ../../../src
- ../../../../common/ios
- ../../../../../include
- ../../../../../../miniaudio
info:
path: Info.plist
properties:
NSMicrophoneUsageDescription: Audio input access needed to run the example

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_ap1
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_ap2
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_balance
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_bitcrush
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_chorus
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_clip
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_comb
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_comp
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_delay
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_dist
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_drive
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_eq_3band
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_flanger
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_fuzz
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_hp1
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_hs1
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_lp1
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_ls1
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_mm1
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_mm2
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_noise_gate
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_notch
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_one_pole
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_pan
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_phaser
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_reverb
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_satur
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_slew_lim
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_svf
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_trem
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_vibrato
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fx_wah
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_ap1
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_ap2
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_balance
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_bitcrush
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_chorus
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_clip
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_comb
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_comp
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_delay
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_dist
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_drive
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_eq_3band
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_flanger
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_fuzz
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_hp1
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_hs1
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_lp1
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_ls1
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_mm1
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_mm2
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_noise_gate
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_notch
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_one_pole
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_pan
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_phaser
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_reverb
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_satur
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_slew_lim
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_svf
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_trem
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_vibrato
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_fxpp_wah
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_synth_mono
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_synth_poly
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_synth_simple
SOURCE := ${NAME}.c
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_synthpp_mono
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_synthpp_poly
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk

View File

@ -0,0 +1,6 @@
ROOT_DIR := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
NAME := bw_example_synthpp_simple
SOURCE := ${NAME}.cpp
include ${ROOT_DIR}/../../common/ios/ios.mk