Browse Source

implemented version of sfprops natively into soundthread and added a currently unused meta tag to nodes that flags if a process always outputs stereo

Jonathan Higgins 3 months ago
parent
commit
a25c29a3f1

+ 2 - 0
dev_tools/json_editor/json_editor.gd

@@ -86,6 +86,7 @@ func edit_node(key: String):
 		$HBoxContainer/VBoxContainer2/HBoxContainer5/shortdescription.text = info.get("short_description", "")
 		$HBoxContainer/VBoxContainer2/HBoxContainer5/shortdescription.text = info.get("short_description", "")
 		$HBoxContainer/VBoxContainer2/HBoxContainer7/longdescription.text = info.get("description", "")
 		$HBoxContainer/VBoxContainer2/HBoxContainer7/longdescription.text = info.get("description", "")
 		$HBoxContainer/VBoxContainer2/HBoxContainer6/stereo.button_pressed = bool(info.get("stereo"))
 		$HBoxContainer/VBoxContainer2/HBoxContainer6/stereo.button_pressed = bool(info.get("stereo"))
+		$HBoxContainer/VBoxContainer2/HBoxContainer8/outputisstereo.button_pressed = bool(info.get("outputisstereo"))
 		$HBoxContainer/VBoxContainer2/HBoxContainer9/inputtype.text = str(info.get("inputtype", ""))
 		$HBoxContainer/VBoxContainer2/HBoxContainer9/inputtype.text = str(info.get("inputtype", ""))
 		$HBoxContainer/VBoxContainer2/HBoxContainer11/outputtype.text = str(info.get("outputtype", ""))
 		$HBoxContainer/VBoxContainer2/HBoxContainer11/outputtype.text = str(info.get("outputtype", ""))
 		
 		
@@ -205,6 +206,7 @@ func save_node(is_new: bool) -> void:
 		"short_description": $HBoxContainer/VBoxContainer2/HBoxContainer5/shortdescription.text,
 		"short_description": $HBoxContainer/VBoxContainer2/HBoxContainer5/shortdescription.text,
 		"description": $HBoxContainer/VBoxContainer2/HBoxContainer7/longdescription.text,
 		"description": $HBoxContainer/VBoxContainer2/HBoxContainer7/longdescription.text,
 		"stereo": $HBoxContainer/VBoxContainer2/HBoxContainer6/stereo.button_pressed,
 		"stereo": $HBoxContainer/VBoxContainer2/HBoxContainer6/stereo.button_pressed,
+		"outputisstereo": $HBoxContainer/VBoxContainer2/HBoxContainer8/outputisstereo.button_pressed,
 		"inputtype": $HBoxContainer/VBoxContainer2/HBoxContainer9/inputtype.text,
 		"inputtype": $HBoxContainer/VBoxContainer2/HBoxContainer9/inputtype.text,
 		"outputtype": $HBoxContainer/VBoxContainer2/HBoxContainer11/outputtype.text,
 		"outputtype": $HBoxContainer/VBoxContainer2/HBoxContainer11/outputtype.text,
 		"parameters": {}
 		"parameters": {}

+ 11 - 0
dev_tools/json_editor/json_editor.tscn

@@ -180,6 +180,17 @@ text = "Stereo:"
 [node name="stereo" type="CheckBox" parent="HBoxContainer/VBoxContainer2/HBoxContainer6"]
 [node name="stereo" type="CheckBox" parent="HBoxContainer/VBoxContainer2/HBoxContainer6"]
 layout_mode = 2
 layout_mode = 2
 
 
+[node name="HBoxContainer8" type="HBoxContainer" parent="HBoxContainer/VBoxContainer2"]
+layout_mode = 2
+
+[node name="Label" type="Label" parent="HBoxContainer/VBoxContainer2/HBoxContainer8"]
+custom_minimum_size = Vector2(250, 0)
+layout_mode = 2
+text = "Output is always stereo:"
+
+[node name="outputisstereo" type="CheckBox" parent="HBoxContainer/VBoxContainer2/HBoxContainer8"]
+layout_mode = 2
+
 [node name="HBoxContainer9" type="HBoxContainer" parent="HBoxContainer/VBoxContainer2"]
 [node name="HBoxContainer9" type="HBoxContainer" parent="HBoxContainer/VBoxContainer2"]
 layout_mode = 2
 layout_mode = 2
 
 

File diff suppressed because it is too large
+ 4974 - 742
dev_tools/json_editor/process_help_backup.json


+ 116 - 2
scenes/main/process_help.json

@@ -3,6 +3,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Performs a mathematical averaging of the set number of cycle counts. The effect is more akin to a loss of resolution than the blurring which might be expected. Values below 10 retain some semblance of the original, while values of 100 create a kind of 'sample hold' effect.\n\n",
 	"description": "Performs a mathematical averaging of the set number of cycle counts. The effect is more akin to a loss of resolution than the blurring which might be expected. Values below 10 retain some semblance of the original, while values of 100 create a kind of 'sample hold' effect.\n\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -31,6 +32,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This effect intoduces distortion by reducing the sample rate or bit-depth of a sound. Reducing the sample rate will introduce inharmonic frequencies known as aliasing. Reducing the bit-depth will introduce both more noise and a crunchy rounding error distortion, particularly at lower rates.\n\n",
 	"description": "This effect intoduces distortion by reducing the sample rate or bit-depth of a sound. Reducing the sample rate will introduce inharmonic frequencies known as aliasing. Reducing the bit-depth will introduce both more noise and a crunchy rounding error distortion, particularly at lower rates.\n\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -75,6 +77,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process reads each wavecycle and replaces it with a short square pulse of a random length of the same amplitude. This produces a rough, rattle like timbre.\n",
 	"description": "This process reads each wavecycle and replaces it with a short square pulse of a random length of the same amplitude. This produces a rough, rattle like timbre.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Replaces wavecycles with short pulses",
 	"short_description": "Replaces wavecycles with short pulses",
@@ -86,6 +89,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Cuts the top and bottom off of a wavecycle. Unlike conventional clipping that only cuts off parts of the signal that exceeds a set threshold, Clip Fraction looks at each cycle of the sound and cuts off a set fraction of that wavecycle. This produces a clipping effect that is uniform across the entire signal and maintains the dynamic range of the original. The lower you set the value, the more distorted the sound will be.\n",
 	"description": "Cuts the top and bottom off of a wavecycle. Unlike conventional clipping that only cuts off parts of the signal that exceeds a set threshold, Clip Fraction looks at each cycle of the sound and cuts off a set fraction of that wavecycle. This produces a clipping effect that is uniform across the entire signal and maintains the dynamic range of the original. The lower you set the value, the more distorted the sound will be.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -114,6 +118,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process distorts and shrinks a sound by taking a group of wavecycles and deleting all but the loudest wavecycle in that group. This will shorten the sound without changing pitch while also adding grit and texture.",
 	"description": "This process distorts and shrinks a sound by taking a group of wavecycles and deleting all but the loudest wavecycle in that group. This will shorten the sound without changing pitch while also adding grit and texture.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -142,6 +147,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Takes a wavecycle and divides its frequency, pitch shifting it down and making it slower. This longer wavecycle replaces the next few wavecycles keeping the length of the file the same. This produces a rough pitch shift effect with added distortion artifacts. Works best with division values less than 4, at high division values the sound file may be too low to hear.\n\nThis process is the opposite of Distort: Multiply.\n",
 	"description": "Takes a wavecycle and divides its frequency, pitch shifting it down and making it slower. This longer wavecycle replaces the next few wavecycles keeping the length of the file the same. This produces a rough pitch shift effect with added distortion artifacts. Works best with division values less than 4, at high division values the sound file may be too low to hear.\n\nThis process is the opposite of Distort: Multiply.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -170,6 +176,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Takes a wavecycle and divides its length and makes shorter and higher copies that equal the divided length. It then takes these copies and superimposes them over the original wavecycle. The higher the scaling the shorter each copy will be and the more copies will be layered over the original. The loudness control works like a mix between the original and the copies of the wavecycle. Produces a sheen of distortion over the original sound.\n",
 	"description": "Takes a wavecycle and divides its length and makes shorter and higher copies that equal the divided length. It then takes these copies and superimposes them over the original wavecycle. The higher the scaling the shorter each copy will be and the more copies will be layered over the original. The loudness control works like a mix between the original and the copies of the wavecycle. Produces a sheen of distortion over the original sound.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -214,6 +221,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Takes all wave cycles from the first inlet and imposes the length (pseudo pitch) of them onto the audio in the second inlet.",
 	"description": "Takes all wave cycles from the first inlet and imposes the length (pseudo pitch) of them onto the audio in the second inlet.",
 	"inputtype": "[0, 0]",
 	"inputtype": "[0, 0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Impose wavecycle length from first file onto the second",
 	"short_description": "Impose wavecycle length from first file onto the second",
@@ -225,6 +233,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Takes all wave cycles from both files and interleaves them between each other, the length of each file relative to each other will have a significant impact on the overall effect.",
 	"description": "Takes all wave cycles from both files and interleaves them between each other, the length of each file relative to each other will have a significant impact on the overall effect.",
 	"inputtype": "[0, 0]",
 	"inputtype": "[0, 0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Interleave wavecycles from two files",
 	"short_description": "Interleave wavecycles from two files",
@@ -236,6 +245,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Takes a wavecycle and repeats it based on the multiplier. On each repetition the wavecycle is morphed slightly in shape so that it morphs into the shape of the next wavecycle in the file. This adds a modulatory quality to the output, successive wavecycles glissando and bend as they flow into one another.\n",
 	"description": "Takes a wavecycle and repeats it based on the multiplier. On each repetition the wavecycle is morphed slightly in shape so that it morphs into the shape of the next wavecycle in the file. This adds a modulatory quality to the output, successive wavecycles glissando and bend as they flow into one another.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -264,6 +274,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Takes each wavecycle and multiplies its frequency making it higher and shorter. It then repeats this wavecycle to fill the length of the original keeping the output file the same length. This produces a distorted pitching up of the sound. \n\nThis process is the opposite of Distort: Divide.\n",
 	"description": "Takes each wavecycle and multiplies its frequency making it higher and shorter. It then repeats this wavecycle to fill the length of the original keeping the output file the same length. This produces a distorted pitching up of the sound. \n\nThis process is the opposite of Distort: Divide.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -292,6 +303,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process identifies groups of wavecycles and removes a set number of wavecycles from that group replacing them with silence. At small values this will add a granular texture onto the sound. With large values this will produce a hard edged sputtering like sound.\n",
 	"description": "This process identifies groups of wavecycles and removes a set number of wavecycles from that group replacing them with silence. At small values this will add a granular texture onto the sound. With large values this will produce a hard edged sputtering like sound.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -336,6 +348,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Introduces distortion into a signal by raising sample values to a power. Values less than 1 tend to flatten the tops of the waveform, while values greater than 1 narrow the waveform shape, creating a thinner, raspier sound.\n",
 	"description": "Introduces distortion into a signal by raising sample values to a power. Values less than 1 tend to flatten the tops of the waveform, while values greater than 1 narrow the waveform shape, creating a thinner, raspier sound.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -364,6 +377,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Takes a wavecycle and repeats it based on the multiplier. Unlike Distort: Interpolate this process does not modify the wavecycles in anyway other than repeating them, this results in pitches emerging at higher multiplication values.\n",
 	"description": "Takes a wavecycle and repeats it based on the multiplier. Unlike Distort: Interpolate this process does not modify the wavecycles in anyway other than repeating them, this results in pitches emerging at higher multiplication values.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -408,6 +422,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Looks at a set number of wavecycles and finds the loudest one and repeats it to replace all other wavecycles. The repeated wavecycle is repeated at its original frequency and amplitude. This produces a sample and hold like effect.\n",
 	"description": "Looks at a set number of wavecycles and finds the loudest one and repeats it to replace all other wavecycles. The repeated wavecycle is repeated at its original frequency and amplitude. This produces a sample and hold like effect.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -436,6 +451,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process reads each wavecycle and replaces it with a sine waveform of the same length and amplitude. This effect of this process is quite dependent on the input material but will usually produce a smoothing or filtering like effect. \n",
 	"description": "This process reads each wavecycle and replaces it with a sine waveform of the same length and amplitude. This effect of this process is quite dependent on the input material but will usually produce a smoothing or filtering like effect. \n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Replaces wavecycles with sine shaped wavecycles",
 	"short_description": "Replaces wavecycles with sine shaped wavecycles",
@@ -447,6 +463,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process reads each wavecycle and replaces it with a square waveform of the same length and amplitude. This produces a similar but considerably harsher effect to Distort: Clip Fraction.\n",
 	"description": "This process reads each wavecycle and replaces it with a square waveform of the same length and amplitude. This produces a similar but considerably harsher effect to Distort: Clip Fraction.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Replaces wavecycles with square shaped wavecycles",
 	"short_description": "Replaces wavecycles with square shaped wavecycles",
@@ -458,6 +475,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process reads each wavecycle and replaces it with a triangle waveform of the same length and amplitude. This effect of this process is quite dependent on the input material. If applied to noisy and distorted sounds this will producing a smoothing or filtering like effect. On sounds with few harmonics - e.g. sine waves - it will add additional harmonics producing a gentle distortion.\n",
 	"description": "This process reads each wavecycle and replaces it with a triangle waveform of the same length and amplitude. This effect of this process is quite dependent on the input material. If applied to noisy and distorted sounds this will producing a smoothing or filtering like effect. On sounds with few harmonics - e.g. sine waves - it will add additional harmonics producing a gentle distortion.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Replaces wavecycles with triangle shaped wavecycles",
 	"short_description": "Replaces wavecycles with triangle shaped wavecycles",
@@ -469,6 +487,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes a sound, reverses it and then prepends the reversed sound onto the start of the original. This works best with sound with long decays where the reversed sound creates a swell into the forwards sound. ",
 	"description": "This process takes a sound, reverses it and then prepends the reversed sound onto the start of the original. This works best with sound with long decays where the reversed sound creates a swell into the forwards sound. ",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -513,6 +532,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Repeats the whole sound a set number of times with gaps in between each repetition. These gaps shrink on each repetition. With Decay set less than 1, on each repetition the sound will get quieter, replicating something similar to a bouncing ball. This effect works best with very short sounds.",
 	"description": "Repeats the whole sound a set number of times with gaps in between each repetition. These gaps shrink on each repetition. With Decay set less than 1, on each repetition the sound will get quieter, replicating something similar to a bouncing ball. This effect works best with very short sounds.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -621,6 +641,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Starting at the Location in the input file this process takes a segment and repeats it. When the next clock tick occurs, the process will step to another segment and start repeating that. The distance in the file that each step can be is set by the Maximum Step and the amount of the file that it is possible for the process to explore either side of the original Location is set by the Ambitus. In this process the walk has the chance to sober up on each step and if it does it will play normally for an amount clock ticks between sober minimum and maximum time.\n",
 	"description": "Starting at the Location in the input file this process takes a segment and repeats it. When the next clock tick occurs, the process will step to another segment and start repeating that. The distance in the file that each step can be is set by the Maximum Step and the amount of the file that it is possible for the process to explore either side of the original Location is set by the Ambitus. In this process the walk has the chance to sober up on each step and if it does it will play normally for an amount clock ticks between sober minimum and maximum time.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -745,6 +766,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process is intended to be used with speach but can be used with any sound. It uses an evelope follower to try and identify a syllable or prominent peak and cuts it out and repeats it a set number of times getting shorter on each repeat by cutting off the end of the segment.",
 	"description": "This process is intended to be used with speach but can be used with any sound. It uses an evelope follower to try and identify a syllable or prominent peak and cuts it out and repeats it a set number of times getting shorter on each repeat by cutting off the end of the segment.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -837,6 +859,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process is intended to be used with speach but can be used with any sound. It uses an evelope follower to try and itentify a syllable or prominent peak and cuts it out and repeats it a set number of times getting shorter on each repeat by cutting off the start of the segment.",
 	"description": "This process is intended to be used with speach but can be used with any sound. It uses an evelope follower to try and itentify a syllable or prominent peak and cuts it out and repeats it a set number of times getting shorter on each repeat by cutting off the start of the segment.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -929,6 +952,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process is intended to be used with speach but can be used with any sound. It uses an evelope follower to try and itentify a syllable or prominent peak and cuts it out and repeats it a set number of times.",
 	"description": "This process is intended to be used with speach but can be used with any sound. It uses an evelope follower to try and itentify a syllable or prominent peak and cuts it out and repeats it a set number of times.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1021,6 +1045,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process is intended to be used with speach but can be used with any sound. It uses an evelope follower to try and identify a syllable or prominent peak and cuts it out and repeats it in reverse.",
 	"description": "This process is intended to be used with speach but can be used with any sound. It uses an evelope follower to try and identify a syllable or prominent peak and cuts it out and repeats it in reverse.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1081,6 +1106,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Joins together, end-to-end, a series of segments taken from the file. This process will continue until the end of the file is reached. Note, with very long loop lengths and very short steps this may make [b]very[/b] long files.\n",
 	"description": "Joins together, end-to-end, a series of segments taken from the file. This process will continue until the end of the file is reached. Note, with very long loop lengths and very short steps this may make [b]very[/b] long files.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1141,6 +1167,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process cuts a sound into segments of a fixed length - that length can vary over time - and then repeats each segement a set number of times. With long segment lengths this will create a clear loops, with short segments this will create a sputtering glitchy repeating effect like a skipped cd or locked record groove.",
 	"description": "This process cuts a sound into segments of a fixed length - that length can vary over time - and then repeats each segement a set number of times. With long segment lengths this will create a clear loops, with short segments this will create a sputtering glitchy repeating effect like a skipped cd or locked record groove.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1185,6 +1212,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Cuts out segments at random from the full duration of the file and splices them end to end. Randomises the length of each chunk to be between the minimum and maximum. With small maximum chunks this will produce a granular synthesis like effect, with large chunks it will create new phrases in the material.\n",
 	"description": "Cuts out segments at random from the full duration of the file and splices them end to end. Randomises the length of each chunk to be between the minimum and maximum. With small maximum chunks this will produce a granular synthesis like effect, with large chunks it will create new phrases in the material.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1245,6 +1273,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process emulates the process of dragging tape manually backwards and forwards over a tape head. To do this it accelerates and decelerates moving through the sound forwards and backwards. Note: Start and End cut out this segment of audio before starting the scrub process and don't retain the audio outside of this range.",
 	"description": "This process emulates the process of dragging tape manually backwards and forwards over a tape head. To do this it accelerates and decelerates moving through the sound forwards and backwards. Note: Start and End cut out this segment of audio before starting the scrub process and don't retain the audio outside of this range.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1337,6 +1366,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Starting at the Location in the input file this process takes a segment and repeats it. When the next clock tick occurs, the process will step to another segment and start repeating that. The distance in the file that each step can be is set by the Maximum Step and the amount of the file that it is possible for the process to explore either side of the original Location is set by the Ambitus. \n",
 	"description": "Starting at the Location in the input file this process takes a segment and repeats it. When the next clock tick occurs, the process will step to another segment and start repeating that. The distance in the file that each step can be is set by the Maximum Step and the amount of the file that it is possible for the process to explore either side of the original Location is set by the Ambitus. \n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1429,6 +1459,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Unlike the other extend processes this process also plays segments of the sound file backwards. This results in a smoother transition between jumps creating an output that slips and slides through its length.\n",
 	"description": "Unlike the other extend processes this process also plays segments of the sound file backwards. This results in a smoother transition between jumps creating an output that slips and slides through its length.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1505,6 +1536,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes the frequency of the lowest band and create filters up to the value of the highest band tuned to the harmonic series. Scatter applies some randomisation of these values moving the sound from something very harmonic to something more bell like in tone. The makeup gain provides a way of adding a boost to the filtered signal, you may need to adjust this if clipping occurs. Note, Q can be automated although doing this does sometimes produce temperamental results.\n",
 	"description": "This process takes the frequency of the lowest band and create filters up to the value of the highest band tuned to the harmonic series. Scatter applies some randomisation of these values moving the sound from something very harmonic to something more bell like in tone. The makeup gain provides a way of adding a boost to the filtered signal, you may need to adjust this if clipping occurs. Note, Q can be automated although doing this does sometimes produce temperamental results.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1597,6 +1629,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes the number of filters and spaces them equally in Hz between the lowest and highest bands. Scatter applies some randomisation of these values. The makeup gain provides a way of adding a boost to the filtered signal, you may need to adjust this if clipping occurs. Note, Q can be automated although doing this does sometimes produce temperamental results. Unlike Filter Bank: Pitched Intervals this will produce a more discordant sound as the frequencies will not align to uniform harmonic intervals.\n",
 	"description": "This process takes the number of filters and spaces them equally in Hz between the lowest and highest bands. Scatter applies some randomisation of these values. The makeup gain provides a way of adding a boost to the filtered signal, you may need to adjust this if clipping occurs. Note, Q can be automated although doing this does sometimes produce temperamental results. Unlike Filter Bank: Pitched Intervals this will produce a more discordant sound as the frequencies will not align to uniform harmonic intervals.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1705,6 +1738,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "The low-pass filter lets through all of the sound below pass-band and attenuates the frequencies higher than pass-band, ending at stop-band.\n\nThe high-pass filter lets through all of the sound above pass-band and attenuates the frequencies lower than pass-band, ending at stop-band.\n\nSetting the Pass-band lower than the stop-band creates a low-pass filter. Setting the Pass-band higher than the stop-band creates a high-pass filter.\n",
 	"description": "The low-pass filter lets through all of the sound below pass-band and attenuates the frequencies higher than pass-band, ending at stop-band.\n\nThe high-pass filter lets through all of the sound above pass-band and attenuates the frequencies lower than pass-band, ending at stop-band.\n\nSetting the Pass-band lower than the stop-band creates a low-pass filter. Setting the Pass-band higher than the stop-band creates a high-pass filter.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1765,6 +1799,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes the frequency of the lowest band and create filters up to the value of the highest band tuned to odd harmonics of the harmonic series. Scatter applies some randomisation of these values moving the sound from something very harmonic to something more bell like in tone. The makeup gain provides a way of adding a boost to the filtered signal, you may need to adjust this if clipping occurs. Note, Q can be automated although doing this does sometimes produce temperamental results.\n",
 	"description": "This process takes the frequency of the lowest band and create filters up to the value of the highest band tuned to odd harmonics of the harmonic series. Scatter applies some randomisation of these values moving the sound from something very harmonic to something more bell like in tone. The makeup gain provides a way of adding a boost to the filtered signal, you may need to adjust this if clipping occurs. Note, Q can be automated although doing this does sometimes produce temperamental results.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1857,6 +1892,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes the number of filters and spaces them equally in semitones between the lowest and highest bands. Scatter applies some randomisation of these values moving the sound from something very harmonic to something more bell like in tone. The makeup gain provides a way of adding a boost to the filtered signal, you may need to adjust this if clipping occurs. Note, Q can be automated although doing this does sometimes produce temperamental results. Unlike Filter Bank: Linear this will produce a more consonant sound as the frequencies will align to uniform harmonic intervals.\n",
 	"description": "This process takes the number of filters and spaces them equally in semitones between the lowest and highest bands. Scatter applies some randomisation of these values moving the sound from something very harmonic to something more bell like in tone. The makeup gain provides a way of adding a boost to the filtered signal, you may need to adjust this if clipping occurs. Note, Q can be automated although doing this does sometimes produce temperamental results. Unlike Filter Bank: Linear this will produce a more consonant sound as the frequencies will align to uniform harmonic intervals.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -1965,6 +2001,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process moves through the file from start to end at the speed set by scan speed. How linearly it moves through the file is set by the Search Range and Jitter. \n\nAs it moves through the file it cuts out small chunks - called grains - of the file and plays those back. The length of those grains and how they fade in and out is set by the Grain Size, Attack and Decay. The pitch of the grains is set by Pitch Shift. \n\nHow many grains play back is set by the Density, densities less than 1 will create gaps between grains, densities higher than 1 will cause grains to overlap and merge. \n\nFinally the sound can be panned from left to right with Panning and the Overalll level of the sound can be adjusted with Amplitude. \n\nThis process works particularly well when automation is applied to many parameters to make it shift and change over time. \n",
 	"description": "This process moves through the file from start to end at the speed set by scan speed. How linearly it moves through the file is set by the Search Range and Jitter. \n\nAs it moves through the file it cuts out small chunks - called grains - of the file and plays those back. The length of those grains and how they fade in and out is set by the Grain Size, Attack and Decay. The pitch of the grains is set by Pitch Shift. \n\nHow many grains play back is set by the Density, densities less than 1 will create gaps between grains, densities higher than 1 will cause grains to overlap and merge. \n\nFinally the sound can be panned from left to right with Panning and the Overalll level of the sound can be adjusted with Amplitude. \n\nThis process works particularly well when automation is applied to many parameters to make it shift and change over time. \n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": true,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2137,6 +2174,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Moves through the sound from start to end and cuts it into grains. The density control sets how many of these grains are played back. A density of 1 will sound close to the original file, less than 1 will introduce gaps between grains, and values greater than one will smooth out the sound and introduce doubling.\n",
 	"description": "Moves through the sound from start to end and cuts it into grains. The density control sets how many of these grains are played back. A density of 1 will sound close to the original file, less than 1 will introduce gaps between grains, and values greater than one will smooth out the sound and introduce doubling.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2165,6 +2203,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Cuts the sound file into grains and speeds them up or slows them down to change their pitch. By repeating/omitting grains it retains the original speed. At high increases in pitch this will create a metallic sound, with high decreases in pitch the sound will lose detail.\n",
 	"description": "Cuts the sound file into grains and speeds them up or slows them down to change their pitch. By repeating/omitting grains it retains the original speed. At high increases in pitch this will create a metallic sound, with high decreases in pitch the sound will lose detail.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2193,6 +2232,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes a sound and splits it into grains. Unlike the other granulate processes the size of the grain not set by a time duration but instead by a number of wavecycles similar to the distort processes. Once the grains have been cut out the process reorders all grains based on how loud they are to create a fall in gain. This process works best with sounds that have a wide dynamic range. This process works excellently with Misc: Stack to add more layers to the new transient sound and with Extend: Back to Back to create a rise and fall from the sound.",
 	"description": "This process takes a sound and splits it into grains. Unlike the other granulate processes the size of the grain not set by a time duration but instead by a number of wavecycles similar to the distort processes. Once the grains have been cut out the process reorders all grains based on how loud they are to create a fall in gain. This process works best with sounds that have a wide dynamic range. This process works excellently with Misc: Stack to add more layers to the new transient sound and with Extend: Back to Back to create a rise and fall from the sound.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2269,6 +2309,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes a sound and splits it into grains. Unlike the other granulate processes the size of the grain not set by a time duration but instead by a number of wavecycles similar to the distort processes. Once the grains have been cut out the process reorders all grains based on how loud they are to create a rise in gain. This process works best with sounds that have a wide dynamic range.",
 	"description": "This process takes a sound and splits it into grains. Unlike the other granulate processes the size of the grain not set by a time duration but instead by a number of wavecycles similar to the distort processes. Once the grains have been cut out the process reorders all grains based on how loud they are to create a rise in gain. This process works best with sounds that have a wide dynamic range.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2345,6 +2386,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Moves through the file from start to end and reorders the grains within the set timeframe of range. Small range values will retain some of the original shape of the sound, large range values will result in a very jumbled sound.\n",
 	"description": "Moves through the file from start to end and reorders the grains within the set timeframe of range. Small range values will retain some of the original shape of the sound, large range values will result in a very jumbled sound.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2389,6 +2431,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Cuts the sound file into grains and repeats omits grains to adjust the speed of the sound. At high decreases in speed this will create a metallic sound, with high increases in speed the sound will lose detail.\n",
 	"description": "Cuts the sound file into grains and repeats omits grains to adjust the speed of the sound. At high decreases in speed this will create a metallic sound, with high increases in speed the sound will lose detail.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2417,6 +2460,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Creates a glissando effect by gradually speeding up or slowing down the file. Once the target time in the sound is reached it will continue sliding up or down to the end of the sound. 0.5 = half speed and 1 octave lower, 2 = double speed and 1 octave higher. Note: for more control over speed over time you can automate the Speed process instead. \n",
 	"description": "Creates a glissando effect by gradually speeding up or slowing down the file. Once the target time in the sound is reached it will continue sliding up or down to the end of the sound. 0.5 = half speed and 1 octave lower, 2 = double speed and 1 octave higher. Note: for more control over speed over time you can automate the Speed process instead. \n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2461,6 +2505,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Adds silence at the end of the sound, very useful  before processes which add long tails such as resonant filters and bluring. Can also be used with scramble processes to add silences into the scramble. \n",
 	"description": "Adds silence at the end of the sound, very useful  before processes which add long tails such as resonant filters and bluring. Can also be used with scramble processes to add silences into the scramble. \n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2489,6 +2534,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes two inputs and multiples them together using a four-quadrant multiplier. Unlike amplitude modulation this allows the bipoloar mulitplier to go negative, inverting the input sounds phase. In sound terms this will produce two sounds layered together, the sum of input and modulator frequencies and the difference between the input and modulator frequencies and the carrier will dissapear. ",
 	"description": "This process takes two inputs and multiples them together using a four-quadrant multiplier. Unlike amplitude modulation this allows the bipoloar mulitplier to go negative, inverting the input sounds phase. In sound terms this will produce two sounds layered together, the sum of input and modulator frequencies and the difference between the input and modulator frequencies and the carrier will dissapear. ",
 	"inputtype": "[0, 0]",
 	"inputtype": "[0, 0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Multiply two sounds together",
 	"short_description": "Multiply two sounds together",
@@ -2500,6 +2546,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process is intended for removing DC offset from a soundfile. You can specify how much the signal should be moved away from the 0 crossing line. It can also be used to deliberately add a DC offset into the sound file before further processing. For processes in the Distort catagory this will allow for an asymetrical application of their processing providing different timbres. Note, working this way is not how the processes are intended to be used and may produce errors on runtime and unpredictable results. Playing signals with significant DC bias in them is not good for the longterm health of your loudspeakers. If you do deliberately add a DC offset, you should run the process in the opposite direction after you are done processing to remove the DC bias. ",
 	"description": "This process is intended for removing DC offset from a soundfile. You can specify how much the signal should be moved away from the 0 crossing line. It can also be used to deliberately add a DC offset into the sound file before further processing. For processes in the Distort catagory this will allow for an asymetrical application of their processing providing different timbres. Note, working this way is not how the processes are intended to be used and may produce errors on runtime and unpredictable results. Playing signals with significant DC bias in them is not good for the longterm health of your loudspeakers. If you do deliberately add a DC offset, you should run the process in the opposite direction after you are done processing to remove the DC bias. ",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2528,6 +2575,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Adjusts the gain of a sound making it louder and quieter. Less than 1 is quieter, more than 1 is louder. Useful for adjusting the level of a sound before a process to avoid clipping and for blending parallel processing in your thread (see Help > Tips > Wet/Dry Mix for more). \n",
 	"description": "Adjusts the gain of a sound making it louder and quieter. Less than 1 is quieter, more than 1 is louder. Useful for adjusting the level of a sound before a process to avoid clipping and for blending parallel processing in your thread (see Help > Tips > Wet/Dry Mix for more). \n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2556,6 +2604,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process inverts the polarity of a signal, swapping the positive and negative portions of the waveform. When mixed with the original input sound this will create silence. This can be combined with other processes to effectively remove the input signal leaving only the result of the process. E.g. running a sound into Distort: Fractal and into this process and combining the result will leave only the fractal component of the waveform. ",
 	"description": "This process inverts the polarity of a signal, swapping the positive and negative portions of the waveform. When mixed with the original input sound this will create silence. This can be combined with other processes to effectively remove the input signal leaving only the result of the process. E.g. running a sound into Distort: Fractal and into this process and combining the result will leave only the fractal component of the waveform. ",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Invert the polarity (phase) of a signal",
 	"short_description": "Invert the polarity (phase) of a signal",
@@ -2567,6 +2616,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Unlike the trim function, this process removes the selected segment of audio out of the audio file keeping only the audio that is outside of the start and end points. Once it has removed the segment of audio it puts the start and end of the file together to close the gap. ",
 	"description": "Unlike the trim function, this process removes the selected segment of audio out of the audio file keeping only the audio that is outside of the start and end points. Once it has removed the segment of audio it puts the start and end of the file together to close the gap. ",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2611,6 +2661,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process analyses the sound on the second inlet to identify its dynamic envelope. It then take the sound on the first inlet and adjusts its gain so that it follows the dynamic contour of the second inlet turning the sound up and down as needed so that it follows the original.",
 	"description": "This process analyses the sound on the second inlet to identify its dynamic envelope. It then take the sound on the first inlet and adjusts its gain so that it follows the dynamic contour of the second inlet turning the sound up and down as needed so that it follows the original.",
 	"inputtype": "[0, 0]",
 	"inputtype": "[0, 0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2639,6 +2690,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Makes the sound play backwards. Particularly useful before processes like Stack to create interesting attack and decays.\n",
 	"description": "Makes the sound play backwards. Particularly useful before processes like Stack to create interesting attack and decays.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Reverses a sound",
 	"short_description": "Reverses a sound",
@@ -2650,6 +2702,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes the input sound and multiplies it by a set frequency using a four-quadrant multiplier. Unlike amplitude modulation this allows the bipoloar mulitplier to go negative, inverting the input sounds phase. In sound terms this will produce two sounds layered together, the sum of input and modulator frequencies and the difference between the input and modulator frequencies and the carrier will dissapear. ",
 	"description": "This process takes the input sound and multiplies it by a set frequency using a four-quadrant multiplier. Unlike amplitude modulation this allows the bipoloar mulitplier to go negative, inverting the input sounds phase. In sound terms this will produce two sounds layered together, the sum of input and modulator frequencies and the difference between the input and modulator frequencies and the carrier will dissapear. ",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2678,6 +2731,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "Plays the sound faster or slower to adjust its speed and pitch. -12 semitones is half speed; +12 semitones is double speed. \n",
 	"description": "Plays the sound faster or slower to adjust its speed and pitch. -12 semitones is half speed; +12 semitones is double speed. \n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2706,6 +2760,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes the sound and makes numerous copies of it, set by the number of layers. Each copy is sped up or slowed down by the transposition amount multiplied  by its layer number - -12 semitones = half speed, +12 semitones = double speed. These layers are then stacks on top of each other to create a denser sound. The attack offset is used to line up the layers so that their attacks all line up, adjust this to the point in the input where you want all the sounds to line up. The output duration allows you to trim off the end of the sound as with negative transposition and many layers the output can get very long. \n",
 	"description": "This process takes the sound and makes numerous copies of it, set by the number of layers. Each copy is sped up or slowed down by the transposition amount multiplied  by its layer number - -12 semitones = half speed, +12 semitones = double speed. These layers are then stacks on top of each other to create a denser sound. The attack offset is used to line up the layers so that their attacks all line up, adjust this to the point in the input where you want all the sounds to line up. The output duration allows you to trim off the end of the sound as with negative transposition and many layers the output can get very long. \n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2814,6 +2869,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process can trim off the start/end of a file to cut to a precise length. This is particularly helpful for trimming chunks out of long files that have been created with extend of granulation processes mid way through a thread for further processing to speed up the processing time. Time is given as a percentage.\n",
 	"description": "This process can trim off the start/end of a file to cut to a precise length. This is particularly helpful for trimming chunks out of long files that have been created with extend of granulation processes mid way through a thread for further processing to speed up the processing time. Time is given as a percentage.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2858,6 +2914,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process plays the audio through a delay line which can be fed back onto itself to create multiple repetitions of the sound. The delay time of the process can be modulated to change over time. With short delay times and small amounts of modulation depth and slow modulation speed this will create chorus and flanger like effects. With longer delay times and higher modulation depth and slow modulation speed this will create audible pitch bends in the sound. With fast modulation speeds this will create an FM like effect producing new higher harmonics in the sound. If modulation frequency is set positive the modulation will be a repeating sine waveform, when set negative the modulation will be random values.",
 	"description": "This process plays the audio through a delay line which can be fed back onto itself to create multiple repetitions of the sound. The delay time of the process can be modulated to change over time. With short delay times and small amounts of modulation depth and slow modulation speed this will create chorus and flanger like effects. With longer delay times and higher modulation depth and slow modulation speed this will create audible pitch bends in the sound. With fast modulation speeds this will create an FM like effect producing new higher harmonics in the sound. If modulation frequency is set positive the modulation will be a repeating sine waveform, when set negative the modulation will be random values.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -2998,6 +3055,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process takes a midi note number and uses the frequency of that note as the time for a delay, this creates ringing pitched sounds similar to karplus strong synthesis.",
 	"description": "This process takes a midi note number and uses the frequency of that note as the time for a delay, this creates ringing pitched sounds similar to karplus strong synthesis.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3058,6 +3116,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process produces a reverb effect, emulating the way sound bounces around an acoustic space. It has three modes, Small, Medium and Large that aim to emulate three different acoustic spaces.",
 	"description": "This process produces a reverb effect, emulating the way sound bounces around an acoustic space. It has three modes, Small, Medium and Large that aim to emulate three different acoustic spaces.",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": true,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3182,6 +3241,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This synth node contains four oscillators. Oscillator 1 is the carrier - the oscillator we listen to - and oscillators 2, 3, and 4 are modulators. The modulators modulate the frequency of the previous oscillator. Frequency modulation adds new overtones to the sound. Simple ratios i.e. frequencies that are integer multiplications of the carriers frequency, will generally produce overtones that align to the harmonic series. More complex ratios will produce inharmonic overtones. This is an effective way of quickly making a very complex tone.",
 	"description": "This synth node contains four oscillators. Oscillator 1 is the carrier - the oscillator we listen to - and oscillators 2, 3, and 4 are modulators. The modulators modulate the frequency of the previous oscillator. Frequency modulation adds new overtones to the sound. Simple ratios i.e. frequencies that are integer multiplications of the carriers frequency, will generally produce overtones that align to the harmonic series. More complex ratios will produce inharmonic overtones. This is an effective way of quickly making a very complex tone.",
 	"inputtype": "[]",
 	"inputtype": "[]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3354,6 +3414,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process generates a constant ramp tone. The pitch of the ramp tone as well as its amplitude can be set to vary over time.",
 	"description": "This process generates a constant ramp tone. The pitch of the ramp tone as well as its amplitude can be set to vary over time.",
 	"inputtype": "[]",
 	"inputtype": "[]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3446,6 +3507,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process generates random points called splines and interpolates between them to create waveforms. The morph speed parameter sets how quickly the waveform will vary overtime creating shifting over tones as it changes shape. ",
 	"description": "This process generates random points called splines and interpolates between them to create waveforms. The morph speed parameter sets how quickly the waveform will vary overtime creating shifting over tones as it changes shape. ",
 	"inputtype": "[]",
 	"inputtype": "[]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3554,6 +3616,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process generates a constant sine tone. The pitch of the sine tone as well as its amplitude can be set to vary over time. This synth node is particularly useful for testing the various Distort processes to get a feel for how they change a sound.",
 	"description": "This process generates a constant sine tone. The pitch of the sine tone as well as its amplitude can be set to vary over time. This synth node is particularly useful for testing the various Distort processes to get a feel for how they change a sound.",
 	"inputtype": "[]",
 	"inputtype": "[]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3646,6 +3709,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process generates a constant square tone. The pitch of the square tone as well as its amplitude can be set to vary over time.",
 	"description": "This process generates a constant square tone. The pitch of the square tone as well as its amplitude can be set to vary over time.",
 	"inputtype": "[]",
 	"inputtype": "[]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3738,6 +3802,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process generates a constant triangle tone. The pitch of the triangle tone as well as its amplitude can be set to vary over time.",
 	"description": "This process generates a constant triangle tone. The pitch of the triangle tone as well as its amplitude can be set to vary over time.",
 	"inputtype": "[]",
 	"inputtype": "[]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3830,6 +3895,7 @@
 	"category": "time",
 	"category": "time",
 	"description": "This process generates white noise. The amplitude of the noise can vary over time.",
 	"description": "This process generates white noise. The amplitude of the noise can vary over time.",
 	"inputtype": "[]",
 	"inputtype": "[]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3906,6 +3972,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process is very similar to the time domain Gain process, it adjusts how loud the signal is, however this process operates on signals that are in the frequency domain. This is useful for adjusting signals that may clip when converted back to the time domain.\n",
 	"description": "This process is very similar to the time domain Gain process, it adjusts how loud the signal is, however this process operates on signals that are in the frequency domain. This is useful for adjusting signals that may clip when converted back to the time domain.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -3934,6 +4001,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This is process is used to analyse a sound and convert it from the time domain to the frequency domain. This allows for processes in the PVOC processes menu to be used to manipulate the sound. Once you are done processing in the frequency domain you can convert it back to audio again using Resynthesise. See Help > Tutorials > PVOC for more.\n",
 	"description": "This is process is used to analyse a sound and convert it from the time domain to the frequency domain. This allows for processes in the PVOC processes menu to be used to manipulate the sound. Once you are done processing in the frequency domain you can convert it back to audio again using Resynthesise. See Help > Tutorials > PVOC for more.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Convert a sound from the time domain to the frequency domain",
 	"short_description": "Convert a sound from the time domain to the frequency domain",
@@ -3945,6 +4013,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This is process is used to take the analysis of a sound file and resynthesise it back into the time domain. This should be used after you are done processing in the frequency domain to convert back to audio. See Help > Tutorials > PVOC for more. \n",
 	"description": "This is process is used to take the analysis of a sound file and resynthesise it back into the time domain. This should be used after you are done processing in the frequency domain to convert back to audio. See Help > Tutorials > PVOC for more. \n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Convert a sound from the frequency domain to the time domain",
 	"short_description": "Convert a sound from the frequency domain to the time domain",
@@ -3956,6 +4025,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process takes the spectral envelope of the second inlet and imposes it over the sound in the first inlet. This allows you to create a blend of the two sounds where the timbre of the first inlet will take on the shape and emphasis of the second.",
 	"description": "This process takes the spectral envelope of the second inlet and imposes it over the sound in the first inlet. This allows you to create a blend of the two sounds where the timbre of the first inlet will take on the shape and emphasis of the second.",
 	"inputtype": "[1, 1]",
 	"inputtype": "[1, 1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4016,6 +4086,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Extracts the spectral contour of the sound retaining any spectral articulation, such as patterns of speech, but replaces the signal by rising (positive values for Glissando Rate) or falling (negative values for Glissando Rate) inharmonic glissandos.",
 	"description": "Extracts the spectral contour of the sound retaining any spectral articulation, such as patterns of speech, but replaces the signal by rising (positive values for Glissando Rate) or falling (negative values for Glissando Rate) inharmonic glissandos.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4076,6 +4147,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "A spectral peak is an area of higher amplitude among the frequencies of the spectrum. A trough is an area of low amplitude between spectral peaks. The INVERT mode swaps these, so that the peaks become troughs and vice versa. This should make the sound noisier, with buzzy high frequencies. Vibrate allow you to oscillate between the original and inverted states this works particularly well when set to a very low value e.g. 0.01.",
 	"description": "A spectral peak is an area of higher amplitude among the frequencies of the spectrum. A trough is an area of low amplitude between spectral peaks. The INVERT mode swaps these, so that the peaks become troughs and vice versa. This should make the sound noisier, with buzzy high frequencies. Vibrate allow you to oscillate between the original and inverted states this works particularly well when set to a very low value e.g. 0.01.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4152,6 +4224,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process allows you to move the first four formants in a sound to a specific frequency set in Hz. Each of the formant peaks can be moved independently.",
 	"description": "This process allows you to move the first four formants in a sound to a specific frequency set in Hz. Each of the formant peaks can be moved independently.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4276,6 +4349,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Narrow steepen skirts of formant peaks by power factor. This focuses energy on the spectral peaks and therefore acts like an increasingly tight filter. As Narrowing is increased the material between the peaks is diminished and eventually disappears.",
 	"description": "Narrow steepen skirts of formant peaks by power factor. This focuses energy on the spectral peaks and therefore acts like an increasingly tight filter. As Narrowing is increased the material between the peaks is diminished and eventually disappears.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4352,6 +4426,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Rotates formants using an LFO, moving their peaks and frequencies up or down the spectrum. When a formant reaches the edge of the formant area they wrap around appearing at the bottom or top of the area.",
 	"description": "Rotates formants using an LFO, moving their peaks and frequencies up or down the spectrum. When a formant reaches the edge of the formant area they wrap around appearing at the bottom or top of the area.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4428,6 +4503,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Extracts the spectral contour of the sound retaining any spectral articulation, such as patterns of speech, but replaces the signal by an endlessly rising (positive values for Glissando Rate) or falling (negative values for Glissando Rate) shepard tone.",
 	"description": "Extracts the spectral contour of the sound retaining any spectral articulation, such as patterns of speech, but replaces the signal by an endlessly rising (positive values for Glissando Rate) or falling (negative values for Glissando Rate) shepard tone.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4472,6 +4548,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process allows you to shift the first four formants in a sound by a set value in Hz. Each of the formant peaks can be moved independently. Note that formants moving below zero or above nyquist will disappear. ",
 	"description": "This process allows you to shift the first four formants in a sound by a set value in Hz. Each of the formant peaks can be moved independently. Note that formants moving below zero or above nyquist will disappear. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4596,6 +4673,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This mode inverts the spectral values for each channel, usually producing a highly distorted output.",
 	"description": "This mode inverts the spectral values for each channel, usually producing a highly distorted output.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4640,6 +4718,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process shifts all formants in the sound towards the specified formants, this will usually result in a lowering of the overal timbre of the sound e.g. high voices become deep voices.",
 	"description": "This process shifts all formants in the sound towards the specified formants, this will usually result in a lowering of the overal timbre of the sound e.g. high voices become deep voices.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4748,6 +4827,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process attempts to achieve a chorusing effect by randomising the amplitude and frequency values of the partials. If very large amplitude values are used, the sound will turn to noise. The chorusing effect itself is achieved by values just a little above 1. Values of 2 or 3 begin to create a granular effect, and values of 10, 100 and 1000 create more and more noise.\n",
 	"description": "This process attempts to achieve a chorusing effect by randomising the amplitude and frequency values of the partials. If very large amplitude values are used, the sound will turn to noise. The chorusing effect itself is achieved by values just a little above 1. Values of 2 or 3 begin to create a granular effect, and values of 10, 100 and 1000 create more and more noise.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4792,6 +4872,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process takes a minimum and maximum frequency range and moves all frequencies outside of this into that range. It does this by transposing the frequencies in octaves, attempting to retain the harmonic relationships within the frequency spectrum. This generally works best with fairly narrow ranges between lowest and highest frequencies.",
 	"description": "This process takes a minimum and maximum frequency range and moves all frequencies outside of this into that range. It does this by transposing the frequencies in octaves, attempting to retain the harmonic relationships within the frequency spectrum. This generally works best with fairly narrow ranges between lowest and highest frequencies.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4836,6 +4917,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Applies a linear frequency shift to the sound between the minimum and maximum frequencies. Unlike pitch shifting, frequency shifting offsets all frequencies by the same number of Hz which decorrolates the harmonic relationship between frequencies in the sound. ",
 	"description": "Applies a linear frequency shift to the sound between the minimum and maximum frequencies. Unlike pitch shifting, frequency shifting offsets all frequencies by the same number of Hz which decorrolates the harmonic relationship between frequencies in the sound. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4896,6 +4978,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Extracts the spectral contour of the sound retaining any spectral articulation, such as patterns of speech, but replaces the signal by rising (positive values for Glissando Rate) or falling (negative values for Glissando Rate) versions of the original input sound.",
 	"description": "Extracts the spectral contour of the sound retaining any spectral articulation, such as patterns of speech, but replaces the signal by rising (positive values for Glissando Rate) or falling (negative values for Glissando Rate) versions of the original input sound.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4940,6 +5023,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This shifts the entire pitch and envelope of the file up or down by a set number of semitones while keeping the duration of the file the same. This produces a different overal tone than shifting pitch with granular processes. ",
 	"description": "This shifts the entire pitch and envelope of the file up or down by a set number of semitones while keeping the duration of the file the same. This produces a different overal tone than shifting pitch with granular processes. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -4968,6 +5052,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This shifts the entire pitch of the file up or down by a set number of semitones while keeping spectral envelope and the duration of the file the same. This will produce a pitch shift while retaining some of the original timbre of the sound.",
 	"description": "This shifts the entire pitch of the file up or down by a set number of semitones while keeping spectral envelope and the duration of the file the same. This will produce a pitch shift while retaining some of the original timbre of the sound.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5012,6 +5097,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process identifies all the harmonic partials in the sound and randomises their pitches. It keeps the original formants the same.",
 	"description": "This process identifies all the harmonic partials in the sound and randomises their pitches. It keeps the original formants the same.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5072,6 +5158,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process takes a set frequency and tunes all partials in the input sound to that frequency or harmonics of that frequency. The final sound is a very natural sounding resonance based on the specified frequency. carrying the spectral articulation of the original sound. The process works best on unpitched, pitch-unspecific, or noisy materials, but can be applied to any sound. ",
 	"description": "This process takes a set frequency and tunes all partials in the input sound to that frequency or harmonics of that frequency. The final sound is a very natural sounding resonance based on the specified frequency. carrying the spectral articulation of the original sound. The process works best on unpitched, pitch-unspecific, or noisy materials, but can be applied to any sound. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5100,6 +5187,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Introduces an oscillation towards and away from inharmonicness in the spectrum of a sound. The program moves towards inharmonicness by means of the stretch factor. \n",
 	"description": "Introduces an oscillation towards and away from inharmonicness in the spectrum of a sound. The program moves towards inharmonicness by means of the stretch factor. \n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5160,6 +5248,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This function take the energy (loudness) information of a frequency channel and averages it between adjacent frequency channels. This resuls in high energy points being spread vertically across the frequency spectrum introducing noise and roughening the sound.",
 	"description": "This function take the energy (loudness) information of a frequency channel and averages it between adjacent frequency channels. This resuls in high energy points being spread vertically across the frequency spectrum introducing noise and roughening the sound.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5188,6 +5277,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process introduces noise into the spectrum in a way which is coherent with the spectral envelope. The formants in each window are retained, and the level in every channel is made to approximate this average spectral contour to a greater or lesser extent, depending on spread. This process tends to exaggerate the less prominent noise constituents of the spectrum.",
 	"description": "This process introduces noise into the spectrum in a way which is coherent with the spectral envelope. The formants in each window are retained, and the level in every channel is made to approximate this average spectral contour to a greater or lesser extent, depending on spread. This process tends to exaggerate the less prominent noise constituents of the spectrum.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5232,6 +5322,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process looks for peaks or troughs in the dynamic range of the sound and then exaggerates the spectral content of those to shift the overall timbre of the sound. Values less than 1 will emphasise the frequencies in the troughs often bringing out pitched resonances, values greater than 1 will bring out the frequencies in the transient peaks often adding a bright buzzy timbre. ",
 	"description": "This process looks for peaks or troughs in the dynamic range of the sound and then exaggerates the spectral content of those to shift the overall timbre of the sound. Values less than 1 will emphasise the frequencies in the troughs often bringing out pitched resonances, values greater than 1 will bring out the frequencies in the transient peaks often adding a bright buzzy timbre. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5260,6 +5351,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Focus identifies a number of peaks in the sound and analyses the prominent frequencies in those peaks. It then filters the entire sound through those frequencies imposing the spectral content of the peaks onto the entire sound. ",
 	"description": "Focus identifies a number of peaks in the sound and analyses the prominent frequencies in those peaks. It then filters the entire sound through those frequencies imposing the spectral content of the peaks onto the entire sound. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5320,6 +5412,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Inverts the spectral envelope, relative to the overall spectral envelope. This means that the energy associated with the highest frequency bands is transferred to the lowest ones and vice versa. As the lowest partials in many sounds have the greatest amplitude and the highest ones the least, the result is typically a much brighter timbre.\n",
 	"description": "Inverts the spectral envelope, relative to the overall spectral envelope. This means that the energy associated with the highest frequency bands is transferred to the lowest ones and vice versa. As the lowest partials in many sounds have the greatest amplitude and the highest ones the least, the result is typically a much brighter timbre.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "Invert the spectral envelope",
 	"short_description": "Invert the spectral envelope",
@@ -5329,8 +5422,9 @@
   },
   },
   "blur_noise": {
   "blur_noise": {
 	"category": "pvoc",
 	"category": "pvoc",
-	"description": "This process enables one to move a sound source towards pure noise, by making the data in every channel – most of which is actually low level noise – equally loud. Setting noise amount to 1 will reduce all sounds to a very similar noise signal that follows the dynamic envelope of the original sound.",
+	"description": "This process enables one to move a sound source towards pure noise, by making the data in every channel – most of which is actually low level noise – equally loud. Setting noise amount to 1 will reduce all sounds to a very similar noise signal that follows the dynamic envelope of the original sound.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5359,6 +5453,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process randomises the spectrum of a sound within a set range. This will result in the harmonic relationship between partials being removed and in pitched material this will move it towards a bell like tone. With the lowest channel set higher than 0 some of the original sounds fundamental frequencies will remain allowing you to only randomise the overtones in the sound.\n",
 	"description": "This process randomises the spectrum of a sound within a set range. This will result in the harmonic relationship between partials being removed and in pitched material this will move it towards a bell like tone. With the lowest channel set higher than 0 some of the original sounds fundamental frequencies will remain allowing you to only randomise the overtones in the sound.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5419,6 +5514,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process takes all frequencies above the threshold and stretches them upwards. In harmonic sounds this will break the relationship between the harmonics moving it into an inharmonic sound. ",
 	"description": "This process takes all frequencies above the threshold and stretches them upwards. In harmonic sounds this will break the relationship between the harmonics moving it into an inharmonic sound. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5495,6 +5591,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process takes all frequencies below the threshold and stretches them downwards. In harmonic sounds this will break the relationship between the harmonics moving it into an inharmonic sound. ",
 	"description": "This process takes all frequencies below the threshold and stretches them downwards. In harmonic sounds this will break the relationship between the harmonics moving it into an inharmonic sound. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5571,6 +5668,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process is the opposite of Trace, it removes the loudest frequencies from the sound leaving only quieter partials and potentially noise. This will thin a sound highlighting its timbre.",
 	"description": "This process is the opposite of Trace, it removes the loudest frequencies from the sound leaving only quieter partials and potentially noise. This will thin a sound highlighting its timbre.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5599,6 +5697,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This function throws away a specified proportion of the analysis data in each window at random. This produces a result similar to the Trace process however, unlike Trace the material kept by Thin Randomly may or may not include prominent parts of the sound.\n",
 	"description": "This function throws away a specified proportion of the analysis data in each window at random. This produces a result similar to the Trace process however, unlike Trace the material kept by Thin Randomly may or may not include prominent parts of the sound.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5627,6 +5726,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Looks for and retains only the N loudest partials in the analysis data on a window-by-window basis. This reduces the data in the spectral dimension and produces an aural 'trace' of the original sound.\n\nWith non-'noisy' sources it is necessary to reduce the number of channels quite considerably to make any appreciable aural change to the source sound. Even the 10 loudest channels will retain a surprising amount of the original sound. The flip side of this is that Trace can be used to 'clean' a sound, if a certain amount of data loss is not a problem. \n\nThis works well with Blur after it to create a smeared simplified version of the sound.\n",
 	"description": "Looks for and retains only the N loudest partials in the analysis data on a window-by-window basis. This reduces the data in the spectral dimension and produces an aural 'trace' of the original sound.\n\nWith non-'noisy' sources it is necessary to reduce the number of channels quite considerably to make any appreciable aural change to the source sound. Even the 10 loudest channels will retain a surprising amount of the original sound. The flip side of this is that Trace can be used to 'clean' a sound, if a certain amount of data loss is not a problem. \n\nThis works well with Blur after it to create a smeared simplified version of the sound.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5655,6 +5755,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Frequencies are sustained into subsequent windows. The Overalll effect is one of sustaining, but one which also makes the spectrum more complex.\n\nThe Glissandos parameter produces glissandos within the spectrum of the sound. Very effective slow glissandos are produced when Glissandos is near 0, e.g., -0.9 or 0.1. At 0.5, there are several glissandos, at 1, they are fairly fast, and at 10 it becomes a wash.\n",
 	"description": "Frequencies are sustained into subsequent windows. The Overalll effect is one of sustaining, but one which also makes the spectrum more complex.\n\nThe Glissandos parameter produces glissandos within the spectrum of the sound. Very effective slow glissandos are produced when Glissandos is near 0, e.g., -0.9 or 0.1. At 0.5, there are several glissandos, at 1, they are fairly fast, and at 10 it becomes a wash.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5699,6 +5800,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process 'blurs' detail in the time dimension by interpolating between the spectral envelope values of the start and end windows blurring windows. Note that it is not interpolating continuously over all the windows in between, just between the data in the start and end windows. The Overalll result is somewhat affected by just how different the data is in these two windows. The interpolation process produces a 'straight line' (linear) scale of values between the start and end points.\n",
 	"description": "This process 'blurs' detail in the time dimension by interpolating between the spectral envelope values of the start and end windows blurring windows. Note that it is not interpolating continuously over all the windows in between, just between the data in the start and end windows. The Overalll result is somewhat affected by just how different the data is in these two windows. The interpolation process produces a 'straight line' (linear) scale of values between the start and end points.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5727,6 +5829,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process is similar to the Extend: Drunk functions however, unlike the extend processes this process moves through analysis windows. This can result in a much smoother extension of the sound as windows are overlapped. The process moves from the start point jumping forwards and backwards randomly between windows. The amount it can move by is limited by the range setting. If range is small, the output will tend to linger around the start-point in the file, progressing very slowly away from it in an arbitrary direction. This results in a mix of time-stretching and slow wandering through the source. If range is large, the drunken walk tends to leap about wildly in the file, scrambling the source sound. ",
 	"description": "This process is similar to the Extend: Drunk functions however, unlike the extend processes this process moves through analysis windows. This can result in a much smoother extension of the sound as windows are overlapped. The process moves from the start point jumping forwards and backwards randomly between windows. The amount it can move by is limited by the range setting. If range is small, the output will tend to linger around the start-point in the file, progressing very slowly away from it in an arbitrary direction. This results in a mix of time-stretching and slow wandering through the source. If range is large, the drunken walk tends to leap about wildly in the file, scrambling the source sound. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5787,6 +5890,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process allows you to pick a single point in time in the sound and output only that moment, drawn out for the amount of time that you specifiy.",
 	"description": "This process allows you to pick a single point in time in the sound and output only that moment, drawn out for the amount of time that you specifiy.",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5831,6 +5935,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Moves through the sound from start to end and freezes the spectrum of the sound at a regular interval. With fast clock speeds this produces a granular like effect, with slow clock speeds this freezes the sound in place creating an audible step from freeze to freeze. This process works well with Blur to to smooth out the boundaries between steps. ",
 	"description": "Moves through the sound from start to end and freezes the spectrum of the sound at a regular interval. With fast clock speeds this produces a granular like effect, with slow clock speeds this freezes the sound in place creating an audible step from freeze to freeze. This process works well with Blur to to smooth out the boundaries between steps. ",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5859,6 +5964,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "Stretches or shrinks the sound over time, without changing frequency. It creates extra time-windows to expand the Overalll time-base of the sound, without a change of frequency. When using large stretch values you will make very long sound files, and this process may take some time to run.\n\nD-Ratio and D-Random allow you to randomise some of the channels in the sound to create internal variation and different timbres. Small amounts of this will blur the sound slightly and on long stretches help the sound feel less static. With large amounts of randomisation, the texture of the sound starts to feel granular.\n",
 	"description": "Stretches or shrinks the sound over time, without changing frequency. It creates extra time-windows to expand the Overalll time-base of the sound, without a change of frequency. When using large stretch values you will make very long sound files, and this process may take some time to run.\n\nD-Ratio and D-Random allow you to randomise some of the channels in the sound to create internal variation and different timbres. Small amounts of this will blur the sound slightly and on long stretches help the sound feel less static. With large amounts of randomisation, the texture of the sound starts to feel granular.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5919,6 +6025,7 @@
 	"category": "pvoc",
 	"category": "pvoc",
 	"description": "This process can trim off the start/end of a file to cut to a precise length in the frequency domain. This is particularly helpful for trimming chunks out of long files that have been created with time strech processes mid way through a thread for further processing to speed up the processing time. Time is given as a percentage.\n",
 	"description": "This process can trim off the start/end of a file to cut to a precise length in the frequency domain. This is particularly helpful for trimming chunks out of long files that have been created with time strech processes mid way through a thread for further processing to speed up the processing time. Time is given as a percentage.\n",
 	"inputtype": "[1]",
 	"inputtype": "[1]",
+	"outputisstereo": false,
 	"outputtype": "[1]",
 	"outputtype": "[1]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -5963,6 +6070,7 @@
 	"category": "utility",
 	"category": "utility",
 	"description": "SoundThread only supports mono and stereo .wav files.\n\nClicking and dragging on the sound file viewer will let you select a section of audio to play.\n\nIf audio is selected in Input File when you run the thread, SoundThread will automatically cut out that section and process only that.\n\nClicking on the sound file viewer while audio is playing will allow you to jump around the file to listen to different sections.\n",
 	"description": "SoundThread only supports mono and stereo .wav files.\n\nClicking and dragging on the sound file viewer will let you select a section of audio to play.\n\nIf audio is selected in Input File when you run the thread, SoundThread will automatically cut out that section and process only that.\n\nClicking on the sound file viewer while audio is playing will allow you to jump around the file to listen to different sections.\n",
 	"inputtype": "",
 	"inputtype": "",
+	"outputisstereo": false,
 	"outputtype": "[0]",
 	"outputtype": "[0]",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -6005,6 +6113,7 @@
 	"category": "utility",
 	"category": "utility",
 	"description": "The name inputted in File Name will be appended with the current date and time so that you don't need to input a new file name each time.\n\nSoundThread can create a lot of files as each node in the thread can create multiple files. Turning on Delete Intermediate Files will delete everything but the main output file. \n\nClicking and dragging on the sound file viewer will let you select a section of audio to play. Clicking on the sound file viewer while audio is playing will allow you to jump around the file to listen to different sections.\n",
 	"description": "The name inputted in File Name will be appended with the current date and time so that you don't need to input a new file name each time.\n\nSoundThread can create a lot of files as each node in the thread can create multiple files. Turning on Delete Intermediate Files will delete everything but the main output file. \n\nClicking and dragging on the sound file viewer will let you select a section of audio to play. Clicking on the sound file viewer while audio is playing will allow you to jump around the file to listen to different sections.\n",
 	"inputtype": "[0]",
 	"inputtype": "[0]",
+	"outputisstereo": false,
 	"outputtype": "",
 	"outputtype": "",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -6058,6 +6167,7 @@
 	"category": "utility",
 	"category": "utility",
 	"description": "This is a basic calculator for quick maths, it can be used in conjunction with other convert nodes to quickly work out parameter values.\n",
 	"description": "This is a basic calculator for quick maths, it can be used in conjunction with other convert nodes to quickly work out parameter values.\n",
 	"inputtype": "",
 	"inputtype": "",
+	"outputisstereo": false,
 	"outputtype": "",
 	"outputtype": "",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "A simple calculator for quick maths",
 	"short_description": "A simple calculator for quick maths",
@@ -6069,6 +6179,7 @@
 	"category": "utility",
 	"category": "utility",
 	"description": "Utility for quickly getting frequencies, values are truncated to two decimal places so are not entirely accurate. Particularly useful for tuning filters and filterbanks. Note, you can highlight and copy a frequency and then paste that into the value for the slider.\n",
 	"description": "Utility for quickly getting frequencies, values are truncated to two decimal places so are not entirely accurate. Particularly useful for tuning filters and filterbanks. Note, you can highlight and copy a frequency and then paste that into the value for the slider.\n",
 	"inputtype": "",
 	"inputtype": "",
+	"outputisstereo": false,
 	"outputtype": "",
 	"outputtype": "",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -6113,6 +6224,7 @@
 	"category": "utility",
 	"category": "utility",
 	"description": "Utility for quickly getting various units of time from another unit of time.",
 	"description": "Utility for quickly getting various units of time from another unit of time.",
 	"inputtype": "",
 	"inputtype": "",
+	"outputisstereo": false,
 	"outputtype": "",
 	"outputtype": "",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {
@@ -6235,8 +6347,9 @@
   },
   },
   "notes": {
   "notes": {
 	"category": "utility",
 	"category": "utility",
-	"description": "Doesn't do anything other than giving you a space to take notes. You can right click in the text box to copy and paste and use special characters like emojis 😊.\n",
+	"description": "Doesn't do anything other than giving you a space to take notes. You can right click in the text box to copy and paste and use special characters like emojis 😊.\n",
 	"inputtype": "",
 	"inputtype": "",
+	"outputisstereo": false,
 	"outputtype": "",
 	"outputtype": "",
 	"parameters": {},
 	"parameters": {},
 	"short_description": "A box for taking notes",
 	"short_description": "A box for taking notes",
@@ -6248,6 +6361,7 @@
 	"category": "utility",
 	"category": "utility",
 	"description": "Connect this node to a point in your thread to preview the output file at that point. This will stop this sound file from being deleted by Delete Intermediate Files. Note: many of these in a thread may cause lag with long input files.\n",
 	"description": "Connect this node to a point in your thread to preview the output file at that point. This will stop this sound file from being deleted by Delete Intermediate Files. Note: many of these in a thread may cause lag with long input files.\n",
 	"inputtype": "",
 	"inputtype": "",
+	"outputisstereo": false,
 	"outputtype": "",
 	"outputtype": "",
 	"parameters": {
 	"parameters": {
 	  "param1": {
 	  "param1": {

+ 2 - 0
scenes/main/scripts/graph_edit.gd

@@ -71,6 +71,7 @@ func _make_node(command: String, skip_undo_redo := false) -> GraphNode:
 			
 			
 			#get node properties
 			#get node properties
 			var stereo = node_info.get("stereo", false)
 			var stereo = node_info.get("stereo", false)
+			var outputisstereo = node_info.get("outputisstereo", false) #used to identify the few processes that always output in stereo making the thread need to be stereo
 			var inputs = JSON.parse_string(node_info.get("inputtype", ""))
 			var inputs = JSON.parse_string(node_info.get("inputtype", ""))
 			var outputs = JSON.parse_string(node_info.get("outputtype", ""))
 			var outputs = JSON.parse_string(node_info.get("outputtype", ""))
 			var portcount = max(inputs.size(), outputs.size())
 			var portcount = max(inputs.size(), outputs.size())
@@ -110,6 +111,7 @@ func _make_node(command: String, skip_undo_redo := false) -> GraphNode:
 			#set meta data for the process
 			#set meta data for the process
 			graphnode.set_meta("command", command)
 			graphnode.set_meta("command", command)
 			graphnode.set_meta("stereo_input", stereo)
 			graphnode.set_meta("stereo_input", stereo)
+			graphnode.set_meta("output_is_stereo", outputisstereo)
 			if inputs.size() == 0 and outputs.size() > 0:
 			if inputs.size() == 0 and outputs.size() > 0:
 				graphnode.set_meta("input", true)
 				graphnode.set_meta("input", true)
 			else:
 			else:

+ 81 - 55
scenes/main/scripts/run_thread.gd

@@ -125,13 +125,13 @@ func run_thread_with_branches():
 					if child.get_node("AudioPlayer").get_meta("trimfile"):
 					if child.get_node("AudioPlayer").get_meta("trimfile"):
 						inputcount += 1
 						inputcount += 1
 				#check if node has internal sample rate, e.g. synthesis nodes and add to array for checking if this is set correctly
 				#check if node has internal sample rate, e.g. synthesis nodes and add to array for checking if this is set correctly
-				if child.has_meta("node_sets_sample_rate"):
+				if child.has_meta("node_sets_sample_rate") and child.get_meta("node_sets_sample_rate") == true:
 					nodes_with_sample_rates.append(child)
 					nodes_with_sample_rates.append(child)
 	#do calculations for progress bar
 	#do calculations for progress bar
 	var progress_step
 	var progress_step
 	progress_step = 100 / (graph.size() + 3 + inputcount)
 	progress_step = 100 / (graph.size() + 3 + inputcount)
 
 
-	#check if input file sample rates and channel count match
+	#check if input file sample rates match
 	if input_nodes.size() > 1:
 	if input_nodes.size() > 1:
 		var match_sample_rates = await match_input_file_sample_rates(input_nodes)
 		var match_sample_rates = await match_input_file_sample_rates(input_nodes)
 		var stereo = []
 		var stereo = []
@@ -142,6 +142,7 @@ func run_thread_with_branches():
 	elif input_nodes.size() == 1:
 	elif input_nodes.size() == 1:
 		processing_sample_rate = input_nodes[0].get_node("AudioPlayer").get_meta("sample_rate")
 		processing_sample_rate = input_nodes[0].get_node("AudioPlayer").get_meta("sample_rate")
 		
 		
+		
 	#check if the sample rate of synthesis nodes match and if they match any files in the input file nodes
 	#check if the sample rate of synthesis nodes match and if they match any files in the input file nodes
 	if (nodes_with_sample_rates.size() > 0 and input_nodes.size() > 0) or nodes_with_sample_rates.size() > 1:
 	if (nodes_with_sample_rates.size() > 0 and input_nodes.size() > 0) or nodes_with_sample_rates.size() > 1:
 		var sythesis_sample_rates = []
 		var sythesis_sample_rates = []
@@ -277,14 +278,11 @@ func run_thread_with_branches():
 			#check all files in dictionary have the same sample rate and channel count and fix if not
 			#check all files in dictionary have the same sample rate and channel count and fix if not
 			var all_files = current_infiles.values()
 			var all_files = current_infiles.values()
 			
 			
-			var match_sample_rate = await match_file_sample_rates(0, process_count, all_files)
-			var match_channels = await match_file_channels(0, process_count, match_sample_rate[0])
+			var match_channels = await match_file_channels(0, process_count, all_files)
 			var matched_files = match_channels[0]
 			var matched_files = match_channels[0]
 			
 			
 			#add intermediate files
 			#add intermediate files
 			if control_script.delete_intermediate_outputs:
 			if control_script.delete_intermediate_outputs:
-				for f in match_sample_rate[1]:
-					intermediate_files.append(f)
 				for f in match_channels[1]:
 				for f in match_channels[1]:
 					intermediate_files.append(f)
 					intermediate_files.append(f)
 			
 			
@@ -658,19 +656,53 @@ func stereo_split_and_process(files: Array, node: Node, process_count: int, slid
 	return [dual_mono_output, intermediate_files, left, right]
 	return [dual_mono_output, intermediate_files, left, right]
 	
 	
 func is_stereo(file: String) -> bool:
 func is_stereo(file: String) -> bool:
-	if file != "none":
-		var output = await run_command(control_script.cdpprogs_location + "/sfprops", ["-c", file])
-		output = int(output.strip_edges()) #convert output from cmd to clean int
-		if output == 1:
-			return false
-		elif output == 2:
-			return true
-		elif output == 1026: #ignore pvoc .ana files
-			return false
-		else:
-			log_console("[color=#9c2828]Error: Only mono and stereo files are supported[/color]", true)
-			return false
-	return true
+	var soundfile_properties = get_soundfile_properties(file)
+	if soundfile_properties[1] == 2:
+		return true
+	else:
+		return false
+
+func get_soundfile_properties(file: String) -> Array:
+	var format
+	var channels
+	var samplerate
+	var bitdepth
+	
+	#open the audio file
+	var f = FileAccess.open(file, FileAccess.READ)
+	
+	#Skip the RIFF header (12 bytes: "RIFF", file size, "WAVE")
+	f.seek(12)
+	
+	#read through file until end of file if needed
+	while not f.eof_reached():
+		#read the 4 byte chunk id to identify what this chunk is
+		var chunk_id = f.get_buffer(4).get_string_from_ascii() 
+		#read how big this chunk is so it can be skipped if not the fmt chunk
+		var chunk_size = f.get_32()
+		
+		if chunk_id == "fmt ":
+			#found the format chunk
+			#fmt chunk layout:
+			#  - 2 bytes: Audio format (1 = PCM, 3 = IEEE float, etc.)
+			#  - 2 bytes: Number of channels (1 = mono, 2 = stereo, ...)
+			#  - 4 bytes: Sample rate
+			#  - 4 bytes: Byte rate
+			#  - 2 bytes: Block align
+			#  - 2 bytes: Bits per sample
+			format = f.get_16() #format 2 bytes: 1 = int PCM, 3 = float
+			channels = f.get_16() #num of channels 2 bytes
+			samplerate = f.get_32() #sample rate 4 bytes
+			f.seek(f.get_position() + 6)
+			bitdepth = f.get_16() #bitdepth 2 bytes
+			f.close()
+			
+			return [format, channels, samplerate, bitdepth]
+		# otherwise skip this chunk and continue
+		f.seek(f.get_position() + chunk_size)
+	
+	f.close()
+	return [-1] #no fmt chunk found, invalid wav file
 		
 		
 func get_samplerate(file: String) -> int:
 func get_samplerate(file: String) -> int:
 	var output = await run_command(control_script.cdpprogs_location + "/sfprops", ["-r", file])
 	var output = await run_command(control_script.cdpprogs_location + "/sfprops", ["-r", file])
@@ -680,12 +712,6 @@ func get_samplerate(file: String) -> int:
 func merge_many_files(inlet_id: int, process_count: int, input_files: Array) -> Array:
 func merge_many_files(inlet_id: int, process_count: int, input_files: Array) -> Array:
 	var merge_output = "%s_merge_%d_%d.wav" % [Global.outfile.get_basename(), inlet_id, process_count]
 	var merge_output = "%s_merge_%d_%d.wav" % [Global.outfile.get_basename(), inlet_id, process_count]
 	var converted_files := []  # Track any mono->stereo converted files or upsampled files
 	var converted_files := []  # Track any mono->stereo converted files or upsampled files
-
-	
-	#check if sample rates of files to be mixed differ and upsample as required
-	var match_sample_rates = await match_file_sample_rates(inlet_id, process_count, input_files)
-	input_files = match_sample_rates[0]
-	converted_files = match_sample_rates[1]
 	
 	
 	#check if there are a mix of mono and stereo files and interleave mono files if required
 	#check if there are a mix of mono and stereo files and interleave mono files if required
 	var match_channels = await match_file_channels(inlet_id, process_count, input_files)
 	var match_channels = await match_file_channels(inlet_id, process_count, input_files)
@@ -744,36 +770,36 @@ func match_input_file_sample_rates(input_nodes: Array) -> Array:
 
 
 
 
 #need to remove this function as not needed
 #need to remove this function as not needed
-func match_file_sample_rates(inlet_id: int, process_count: int, input_files: Array) -> Array:
-	var sample_rates := []
-	var converted_files := []
-	
-	#Get all sample rates
-	for f in input_files:
-		var samplerate = await get_samplerate(f)
-		sample_rates.append(samplerate)
-	
-	#Check if all sample rates are the same
-	if sample_rates.all(func(v): return v == sample_rates[0]):
-		pass
-	else:
-		log_console("Different sample rates found, upsampling files to match highest current sample rate before processing.", true)
-		#if not find the highest sample rate
-		var highest_sample_rate = sample_rates.max()
-		var index = 0
-		#move through all input files and compare match their index to the sample_rate array
-		for f in input_files:
-			#check if sample rate of current file is less than the highest sample rate
-			if sample_rates[index] < highest_sample_rate:
-				#up sample it to the highest sample rate if so
-				var upsample_output = Global.outfile + "_" + str(inlet_id) + "_" + str(process_count) + f.get_file().get_slice(".wav", 0) + "_" + str(highest_sample_rate) + ".wav"
-				await run_command(control_script.cdpprogs_location + "/housekeep", ["respec", "1", f, upsample_output, str(highest_sample_rate)])
-				#replace the file in the input_file index with the new upsampled file
-				input_files[index] = upsample_output
-				converted_files.append(upsample_output)
-				
-			index += 1
-	return [input_files, converted_files]
+#func match_file_sample_rates(inlet_id: int, process_count: int, input_files: Array) -> Array:
+	#var sample_rates := []
+	#var converted_files := []
+	#
+	##Get all sample rates
+	#for f in input_files:
+		#var samplerate = await get_samplerate(f)
+		#sample_rates.append(samplerate)
+	#
+	##Check if all sample rates are the same
+	#if sample_rates.all(func(v): return v == sample_rates[0]):
+		#pass
+	#else:
+		#log_console("Different sample rates found, upsampling files to match highest current sample rate before processing.", true)
+		##if not find the highest sample rate
+		#var highest_sample_rate = sample_rates.max()
+		#var index = 0
+		##move through all input files and compare match their index to the sample_rate array
+		#for f in input_files:
+			##check if sample rate of current file is less than the highest sample rate
+			#if sample_rates[index] < highest_sample_rate:
+				##up sample it to the highest sample rate if so
+				#var upsample_output = Global.outfile + "_" + str(inlet_id) + "_" + str(process_count) + f.get_file().get_slice(".wav", 0) + "_" + str(highest_sample_rate) + ".wav"
+				#await run_command(control_script.cdpprogs_location + "/housekeep", ["respec", "1", f, upsample_output, str(highest_sample_rate)])
+				##replace the file in the input_file index with the new upsampled file
+				#input_files[index] = upsample_output
+				#converted_files.append(upsample_output)
+				#
+			#index += 1
+	#return [input_files, converted_files]
 	
 	
 func match_file_channels(inlet_id: int, process_count: int, input_files: Array) -> Array:
 func match_file_channels(inlet_id: int, process_count: int, input_files: Array) -> Array:
 	var converted_files := []
 	var converted_files := []

Some files were not shown because too many files changed in this diff