Updated LibPdInstance.cs.

This commit is contained in:
Niall Moody 2021-10-03 13:51:04 +01:00
parent 4c17055789
commit 1b3c08893a

View file

@ -261,7 +261,7 @@ public class LibPdInstance : MonoBehaviour
#region libpd delegate/callback declarations #region libpd delegate/callback declarations
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
//-Print hook--------------------------------------------------------------- //-Print hook---------------------------------------------------------------
// We don't make the print hook publicly available (for now), so it's just a //We don't make the print hook publicly available (for now), so it's just a
//single static delegate. //single static delegate.
/// Delegate/function pointer type. /// Delegate/function pointer type.
@ -437,12 +437,15 @@ public class LibPdInstance : MonoBehaviour
/// We use this to ensure libpd -> Unity events get sent to all LibPdInstances. /// We use this to ensure libpd -> Unity events get sent to all LibPdInstances.
/*! /*!
It's also used to ensure libpd_queued_release() only gets called once IMPORTANT: Bear in mind that C#'s List is not thread-safe. That's not a
all LibPdInstances have been destroyed. problem for the way we're using it at the time of writing, because
activeInstances only gets accessed from the main thread in OnEnable,
OnDisable and the various BangOutput, FloatOutput, etc. delegates that
themselves get called from Update.
activeInstances should *NEVER* be accessed from the audio thread though.
*/ */
private static List<LibPdInstance> activeInstances = new List<LibPdInstance>(); private static List<LibPdInstance> activeInstances = new List<LibPdInstance>();
/// The WeakReference pointing to ourselves in activeInstances.
//private WeakReference instanceReference;
/// True if we were unable to intialise Pd's audio processing. /// True if we were unable to intialise Pd's audio processing.
private bool pdFail = false; private bool pdFail = false;
@ -451,8 +454,10 @@ public class LibPdInstance : MonoBehaviour
/// True if we have successfully loaded our patch. /// True if we have successfully loaded our patch.
private bool loaded = false; private bool loaded = false;
/// Global variable used to ensure we don't initialise LibPd more than once. /// Global variable used to ensure we don't initialise libpd more than once.
private static bool pdInitialised = false; private static bool pdInitialised = false;
/// Global reference count used to determine when to un-initialise libpd.
private static int numInstances = 0;
#endregion #endregion
#region events #region events
@ -502,10 +507,10 @@ public class LibPdInstance : MonoBehaviour
/// Initialise LibPd. /// Initialise LibPd.
void Awake() void Awake()
{ {
// Initialise libpd, if it's not already. //Initialise libpd, if it's not already.
if (!pdInitialised) if(!pdInitialised)
{ {
// Setup hooks. //Setup hooks.
printHook = new LibPdPrintHook(PrintOutput); printHook = new LibPdPrintHook(PrintOutput);
libpd_set_queued_printhook(printHook); libpd_set_queued_printhook(printHook);
@ -545,7 +550,7 @@ public class LibPdInstance : MonoBehaviour
midiByteHook = new LibPdMidiByteHook(MidiByteOutput); midiByteHook = new LibPdMidiByteHook(MidiByteOutput);
libpd_set_queued_midibytehook(midiByteHook); libpd_set_queued_midibytehook(midiByteHook);
// Initialise libpd if possible, report any errors. //Initialise libpd if possible, report any errors.
int initErr = libpd_queued_init(); int initErr = libpd_queued_init();
if(initErr != 0) if(initErr != 0)
{ {
@ -554,33 +559,33 @@ public class LibPdInstance : MonoBehaviour
} }
pdInitialised = true; pdInitialised = true;
// Try and add the patch directory to libpd's search path for //Try and add the patch directory to libpd's search path for
// loading externals (still can't seem to load externals when //loading externals (still can't seem to load externals when
// running in Unity though). //running in Unity though).
if(patchDir != String.Empty) if(patchDir != String.Empty)
libpd_add_to_search_path(Application.streamingAssetsPath + patchDir); libpd_add_to_search_path(Application.streamingAssetsPath + patchDir);
// Make sure our static pipePrintToConsole variable is set //Make sure our static pipePrintToConsole variable is set
// correctly. //correctly.
pipePrintToConsoleStatic = pipePrintToConsole; pipePrintToConsoleStatic = pipePrintToConsole;
} }
else else
pipePrintToConsole = pipePrintToConsoleStatic; pipePrintToConsole = pipePrintToConsoleStatic;
// Calc numTicks. //Calc numTicks.
int bufferSize; int bufferSize;
int noOfBuffers; int noOfBuffers;
AudioSettings.GetDSPBufferSize (out bufferSize, out noOfBuffers); AudioSettings.GetDSPBufferSize (out bufferSize, out noOfBuffers);
numTicks = bufferSize/libpd_blocksize(); numTicks = bufferSize/libpd_blocksize();
// Create our instance. //Create our instance.
instance = libpd_new_instance(); instance = libpd_new_instance();
// Set our instance. //Set our instance.
libpd_set_instance(instance); libpd_set_instance(instance);
// Initialise audio. //Initialise audio.
int err = libpd_init_audio(2, 2, AudioSettings.outputSampleRate); int err = libpd_init_audio(2, 2, AudioSettings.outputSampleRate);
if(err != 0) if(err != 0)
{ {
@ -599,7 +604,7 @@ public class LibPdInstance : MonoBehaviour
//Create our bindings dictionary. //Create our bindings dictionary.
bindings = new Dictionary<string, IntPtr>(); bindings = new Dictionary<string, IntPtr>();
// Open our patch. //Open our patch.
patchPointer = libpd_openfile(patchName + ".pd", patchPointer = libpd_openfile(patchName + ".pd",
Application.streamingAssetsPath + patchDir); Application.streamingAssetsPath + patchDir);
if(patchPointer == IntPtr.Zero) if(patchPointer == IntPtr.Zero)
@ -611,13 +616,16 @@ public class LibPdInstance : MonoBehaviour
patchFail = true; patchFail = true;
} }
// Turn on audio processing. //Turn on audio processing.
libpd_start_message(1); libpd_start_message(1);
libpd_add_float(1.0f); libpd_add_float(1.0f);
libpd_finish_message("pd", "dsp"); libpd_finish_message("pd", "dsp");
if(!patchFail) if(!patchFail)
{
loaded = true; loaded = true;
++numInstances;
}
} }
} }
} }
@ -658,8 +666,10 @@ public class LibPdInstance : MonoBehaviour
libpd_free_instance(instance); libpd_free_instance(instance);
} }
--numInstances;
//If we're the last instance left, release libpd's ringbuffer. //If we're the last instance left, release libpd's ringbuffer.
if(pdInitialised && (activeInstances.Count < 1)) if(pdInitialised && (numInstances < 1))
{ {
if(printHook != null) if(printHook != null)
{ {
@ -946,7 +956,7 @@ public class LibPdInstance : MonoBehaviour
{ {
libpd_set_instance(instance); libpd_set_instance(instance);
if (libpd_sysrealtime(port, value) != 0) if(libpd_sysrealtime(port, value) != 0)
Debug.LogWarning(gameObject.name + "::SendMidiSysRealtime(): input parameter(s) out of range. port = " + port + " value = " + value); Debug.LogWarning(gameObject.name + "::SendMidiSysRealtime(): input parameter(s) out of range. port = " + port + " value = " + value);
} }