Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CircleOfFifths/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".CircleOfFifths" android:label="@string/app_name"
android:screenOrientation="portrait" android:theme="@style/DisableSoundEffects"
Expand Down
2 changes: 1 addition & 1 deletion PdCore/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ allprojects {
// These are specific to PdCore, but nexusPublishing needs them here:
// https://github.com/gradle-nexus/publish-plugin/issues/84
group = 'io.github.libpd.android'
version = '1.3.0-SNAPSHOT'
version = '1.4.0-SNAPSHOT'

// Create a Sonatype user token for these environment variables:
// export ORG_GRADLE_PROJECT_sonatypeUsername="<tokenUsername>"
Expand Down
12 changes: 10 additions & 2 deletions PdCore/pd-core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ version = rootProject.version

dependencies {
implementation 'androidx.legacy:legacy-support-v4:' + rootProject.androidxLegacySupportVersion
implementation 'com.google.oboe:oboe:1.10.0'
}

android {
Expand All @@ -26,12 +27,19 @@ android {
}

buildFeatures {
prefabPublishing = true
// Export prefab, that will allow apps to compile externals
prefabPublishing = true

// Import prefab: extract native libs (mainly Oboe), to be able to access the headers and to link to the libs
prefab = true
}

prefab {
pd {
headers = 'src/main/jni/libpd/pure-data/src'
headers = 'src/main/jni/libpd/pure-data/src'
}
pdnativeoboe {
headers = 'src/main/jni/libpd/jni/oboe'
}
}

Expand Down
141 changes: 141 additions & 0 deletions PdCore/pd-core/src/main/java/org/puredata/android/io/AudioDevices.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/**
*
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
*
*/

package org.puredata.android.io;
import org.puredata.android.service.R;

import android.content.Context;
import android.app.Activity;
import android.media.AudioManager;
import android.media.AudioDeviceCallback;
import android.media.AudioDeviceInfo;
import android.util.Log;
import android.content.res.Resources;
import android.preference.ListPreference;
import android.preference.PreferenceFragment;

import java.util.ArrayList;
import java.util.List;

public class AudioDevices {

private static final String TAG = "AudioDevices";
private AudioManager mAudioManager;

private class AudioDeviceList {
private ListPreference mPref;
private List<String> mEntries = new ArrayList<>();
private List<String> mValues = new ArrayList<>();

private CharSequence[] listToArray(List<String> l) {
String[] array = new String[l.size()];
l.toArray(array);
return array;
}
AudioDeviceList(PreferenceFragment prefFragment, String key) {
mPref = (ListPreference) prefFragment.findPreference(key);
mEntries.add("Default");
mValues.add("-1");
}
public void add(AudioDeviceInfo device) {
String name = device.getProductName().toString() + " " + typeToString(device.getType());
mEntries.add(name);
mValues.add(Integer.toString(device.getId()));
mPref.setEntries(listToArray(mEntries));
mPref.setEntryValues(listToArray(mValues));
}
}

private AudioDeviceList mInputDevices = null;
private AudioDeviceList mOutputDevices = null;

/**
* @param context activity or service that calls this method
*/
public AudioDevices(Activity context) {
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
PreferenceFragment prefFragment = (PreferenceFragment) context.getFragmentManager().findFragmentByTag("prefFragment");
Resources res = context.getResources();
mInputDevices = new AudioDeviceList(prefFragment, res.getString(R.string.pref_key_indevice));
mOutputDevices = new AudioDeviceList(prefFragment, res.getString(R.string.pref_key_outdevice));
setupAudioDeviceCallback();
}

/**
* Converts the value from {@link AudioDeviceInfo#getType()} into a human
* readable string
* @param type One of the {@link AudioDeviceInfo}.TYPE_* values
* e.g. AudioDeviceInfo.TYPE_BUILT_IN_SPEAKER
* @return string which describes the type of audio device
*/
static String typeToString(int type){
switch (type) {
case AudioDeviceInfo.TYPE_AUX_LINE:
return "auxiliary line-level connectors";
case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
return "Bluetooth device supporting the A2DP profile";
case AudioDeviceInfo.TYPE_BLUETOOTH_SCO:
return "Bluetooth device typically used for telephony";
case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
return "built-in earphone speaker";
case AudioDeviceInfo.TYPE_BUILTIN_MIC:
return "built-in microphone";
case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
return "built-in speaker";
case AudioDeviceInfo.TYPE_BUS:
return "BUS";
case AudioDeviceInfo.TYPE_DOCK:
return "DOCK";
case AudioDeviceInfo.TYPE_FM:
return "FM";
case AudioDeviceInfo.TYPE_FM_TUNER:
return "FM tuner";
case AudioDeviceInfo.TYPE_HDMI:
return "HDMI";
case AudioDeviceInfo.TYPE_HDMI_ARC:
return "HDMI audio return channel";
case AudioDeviceInfo.TYPE_IP:
return "IP";
case AudioDeviceInfo.TYPE_LINE_ANALOG:
return "line analog";
case AudioDeviceInfo.TYPE_LINE_DIGITAL:
return "line digital";
case AudioDeviceInfo.TYPE_TELEPHONY:
return "telephony";
case AudioDeviceInfo.TYPE_TV_TUNER:
return "TV tuner";
case AudioDeviceInfo.TYPE_USB_ACCESSORY:
return "USB accessory";
case AudioDeviceInfo.TYPE_USB_DEVICE:
return "USB device";
case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
return "wired headphones";
case AudioDeviceInfo.TYPE_WIRED_HEADSET:
return "wired headset";
default:
case AudioDeviceInfo.TYPE_UNKNOWN:
return "unknown";
}
}

private void setupAudioDeviceCallback(){
// Note that we will immediately receive a call to onDevicesAdded with the list of
// devices which are currently connected.
mAudioManager.registerAudioDeviceCallback(new AudioDeviceCallback() {
@Override
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
for (AudioDeviceInfo device : addedDevices){
if (device.isSource()) mInputDevices.add(device);
else if (device.isSink()) mOutputDevices.add(device);
}
}

public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
}
}, null);
}
}
15 changes: 15 additions & 0 deletions PdCore/pd-core/src/main/java/org/puredata/android/io/PdAudio.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
public class PdAudio {

private static AudioWrapper audioWrapper = null;
private static int inputDeviceId = -1;
private static int outputDeviceId = -1;
private static final Handler handler = new Handler(Looper.getMainLooper());
private static final Runnable pollRunner = new Runnable() {
@Override
Expand Down Expand Up @@ -77,6 +79,17 @@ protected int process(short[] inBuffer, short[] outBuffer) {
}
}

/**
* Set the audio input and output devices Id. Call it before startAudio().
*
* @param inDeviceId id of the audio input device (-1 means the default device)
* @param outDeviceId id of the audio output device (-1 means the default device)
*/
public synchronized static void setDevicesId(int inDeviceId, int outDeviceId) {
inputDeviceId = inDeviceId;
outputDeviceId = outDeviceId;
}

/**
* Starts the audio components.
*
Expand All @@ -85,6 +98,8 @@ protected int process(short[] inBuffer, short[] outBuffer) {
public synchronized static void startAudio(Context context) {
PdBase.computeAudio(true);
if (PdBase.implementsAudio()) {
PdBase.setRecordingDeviceId(inputDeviceId);
PdBase.setPlaybackDeviceId(outputDeviceId);
handler.post(pollRunner);
PdBase.startAudio();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
package org.puredata.android.service;

import org.puredata.android.io.AudioParameters;
import org.puredata.android.io.AudioDevices;
import org.puredata.core.PdBase;

import android.content.Context;
Expand All @@ -16,6 +17,7 @@
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.preference.PreferenceFragment;

/**
*
Expand All @@ -27,20 +29,33 @@
*/
public class PdPreferences extends PreferenceActivity {

@SuppressWarnings("deprecation")
public AudioDevices audioDevices = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AudioParameters.init(this);
initPreferences(getApplicationContext());
addPreferencesFromResource(R.xml.preferences);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment(), "prefFragment").commit();
}

@Override
protected void onDestroy() {
super.onDestroy();
}

public static class MyPreferenceFragment extends PreferenceFragment
{
@Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Resources res = getResources();
addPreferencesFromResource(R.xml.preferences);
((PdPreferences)getActivity()).audioDevices = new AudioDevices(getActivity());
}
}

/**
* If no preferences are available, initialize preferences with defaults suggested by {@link PdBase} or {@link AudioParameters}, in that order.
*
Expand All @@ -53,8 +68,10 @@ public static void initPreferences(Context context) {
SharedPreferences.Editor editor = prefs.edit();
int srate = PdBase.suggestSampleRate();
editor.putString(res.getString(R.string.pref_key_srate), "" + ((srate > 0) ? srate : AudioParameters.suggestSampleRate()));
editor.putString(res.getString(R.string.pref_key_indevice), res.getStringArray(R.array.indevice_values)[0]);
int nic = PdBase.suggestInputChannels();
editor.putString(res.getString(R.string.pref_key_inchannels), "" + ((nic > 0) ? nic : AudioParameters.suggestInputChannels()));
editor.putString(res.getString(R.string.pref_key_outdevice), res.getStringArray(R.array.outdevice_values)[0]);
int noc = PdBase.suggestOutputChannels();
editor.putString(res.getString(R.string.pref_key_outchannels), "" + ((noc > 0) ? noc : AudioParameters.suggestOutputChannels()));
editor.commit();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,18 @@ public synchronized void initAudio(int srate, int nic, int noc, float millis) th
stopForeground();
Resources res = getResources();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
int in_id = -1;
int out_id = -1;
{
String s = prefs.getString(res.getString(R.string.pref_key_indevice), null);
if (s != null) {
in_id = Integer.parseInt(s);
}
s = prefs.getString(res.getString(R.string.pref_key_outdevice), null);
if (s != null) {
out_id = Integer.parseInt(s);
}
}
if (srate < 0) {
String s = prefs.getString(res.getString(R.string.pref_key_srate), null);
if (s != null) {
Expand Down Expand Up @@ -137,6 +149,7 @@ public synchronized void initAudio(int srate, int nic, int noc, float millis) th
millis = 50.0f; // conservative choice
}
int tpb = (int) (0.001f * millis * srate / PdBase.blockSize()) + 1;
PdAudio.setDevicesId(in_id, out_id);
PdAudio.initAudio(srate, nic, noc, tpb, true);
sampleRate = srate;
inputChannels = nic;
Expand Down Expand Up @@ -213,6 +226,7 @@ public boolean onUnbind(Intent intent) {
@Override
public void onCreate() {
super.onCreate();

AudioParameters.init(this);
if (!abstractionsInstalled) {
try {
Expand Down
1 change: 1 addition & 0 deletions PdCore/pd-core/src/main/jni/Application.mk
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
APP_PLATFORM := android-28
APP_OPTIM := release
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
APP_STL := c++_shared
2 changes: 1 addition & 1 deletion PdCore/pd-core/src/main/jni/libpd
Submodule libpd updated 46 files
+14 −0 Android.mk
+9 −2 CHANGES.txt
+26 −6 README.md
+17 −6 cpp/PdBase.hpp
+101 −137 csharp/LibPDBinding.csproj
+0 −31 csharp/LibPDBinding.nuspec
+23 −0 csharp/LibPDBinding.targets
+0 −2 csharp/Managed/Data/Bang.cs
+0 −2 csharp/Managed/Data/Float.cs
+0 −2 csharp/Managed/Data/IAtom.cs
+0 −2 csharp/Managed/Data/Symbol.cs
+1 −1 csharp/Managed/Events/AftertouchEventArgs.cs
+1 −1 csharp/Managed/Events/ControlChangeEventArgs.cs
+1 −1 csharp/Managed/Events/MidiByteEventArgs.cs
+1 −1 csharp/Managed/Events/PitchbendEventArgs.cs
+1 −1 csharp/Managed/Events/PolyAftertouchEventArgs.cs
+1 −1 csharp/Managed/Events/ProgramChangeEventArgs.cs
+2 −5 csharp/Managed/Pd.cs
+0 −1 csharp/Managed/Utils/MessageInvocation.cs
+35 −35 csharp/Native/Audio.cs
+7 −7 csharp/Native/Defines.cs
+19 −19 csharp/Native/General.cs
+0 −3 csharp/Native/MultiInstance.cs
+0 −32 csharp/Properties/AssemblyInfo.cs
+19 −0 csharp/README.md
+0 −32 csharp/README.txt
+4 −4 csharp/app.config
+ csharp/libwinpthread-1.dll
+21 −0 java/org/puredata/core/PdBase.java
+2 −2 java/org/puredata/core/PdBaseLoader.java
+281 −0 jni/oboe/OboeEngine.cpp
+85 −0 jni/oboe/OboeEngine.h
+175 −0 jni/oboe/PdStreams.h
+46 −0 jni/oboe/logging_macros.h
+154 −0 jni/oboe/z_jni_oboe.cpp
+13 −0 jni/oboe/z_jni_oboe.h
+7 −0 jni/oboe/z_jni_oboe_shared.c
+24 −0 jni/z_jni.h
+10 −0 jni/z_jni_opensl.c
+10 −0 jni/z_jni_pa.c
+9 −0 jni/z_jni_plain.c
+2 −2 libpd.podspec
+ libs/mingw64/libwinpthread-1.dll
+5 −5 samples/csharp/naudio/App.config
+5 −1 samples/csharp/naudio/LibPdBindingNaudio.csproj
+12 −2 samples/csharp/pdtest/LibPDBindingTest.csproj
12 changes: 12 additions & 0 deletions PdCore/pd-core/src/main/res/values/audio.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
<item>44100</item>
<item>48000</item>
</string-array>
<string-array name="indevice_labels">
<item>Default</item>
</string-array>
<string-array name="indevice_values">
<item>-1</item>
</string-array>
<string-array name="inchannels_labels">
<item>None</item>
<item>Mono</item>
Expand All @@ -28,6 +34,12 @@
<item>1</item>
<item>2</item>
</string-array>
<string-array name="outdevice_labels">
<item>Default</item>
</string-array>
<string-array name="outdevice_values">
<item>-1</item>
</string-array>
<string-array name="outchannels_labels">
<item>None</item>
<item>Mono</item>
Expand Down
6 changes: 6 additions & 0 deletions PdCore/pd-core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
<string name="pref_key_srate">SAMPLE_RATE</string>
<string name="pref_title_srate">Sample rate</string>
<string name="pref_sum_srate">Sample rate for Pure Data</string>
<string name="pref_key_indevice">INPUT_DEVICE</string>
<string name="pref_title_indevice">Input device</string>
<string name="pref_sum_indevice">Name of the input device</string>
<string name="pref_key_inchannels">INPUT_CHANNELS</string>
<string name="pref_title_inchannels">Input channels</string>
<string name="pref_sum_inchannels">Number of input channels</string>
<string name="pref_key_outdevice">OUTPUT_DEVICE</string>
<string name="pref_title_outdevice">Output device</string>
<string name="pref_sum_outdevice">Name of the output device</string>
<string name="pref_key_outchannels">OUTPUT_CHANNELS</string>
<string name="pref_title_outchannels">Output channels</string>
<string name="pref_sum_outchannels">Number of output channels</string>
Expand Down
6 changes: 6 additions & 0 deletions PdCore/pd-core/src/main/res/xml/preferences.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
android:entries="@array/srate_labels" android:key="@string/pref_key_srate"
android:title="@string/pref_title_srate" android:summary="@string/pref_sum_srate">
</ListPreference>
<ListPreference android:key="@string/pref_key_indevice"
android:entryValues="@array/indevice_values" android:entries="@array/indevice_labels"
android:title="@string/pref_title_indevice" android:summary="@string/pref_sum_indevice"></ListPreference>
<ListPreference android:key="@string/pref_key_inchannels"
android:entryValues="@array/inchannels_values" android:entries="@array/inchannels_labels"
android:title="@string/pref_title_inchannels" android:summary="@string/pref_sum_inchannels"></ListPreference>
<ListPreference android:key="@string/pref_key_outdevice"
android:entryValues="@array/outdevice_values" android:entries="@array/outdevice_labels"
android:title="@string/pref_title_outdevice" android:summary="@string/pref_sum_outdevice"></ListPreference>
<ListPreference android:key="@string/pref_key_outchannels"
android:entryValues="@array/outchannels_values" android:entries="@array/outchannels_labels"
android:title="@string/pref_title_outchannels" android:summary="@string/pref_sum_outchannels"></ListPreference>
Expand Down
3 changes: 2 additions & 1 deletion PdTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
</manifest>
Loading