Pd quits when opening Midi settings
Which version of Pd and on which operating system?
Can't say for sure what's up, one long-standing issue with Mac and Windows PD is that PD has never had a proper software midi interface between the app and the system. What it does have is a hack-in that will connect PD midi to - at maximum - the first nine ports on the system's midi port list and nowhere else. ATM only ALSA MIDI on linux has anything close to a fully interfaced PD midi to system buss.
To get full access to the max available midi porting on Mac/Win you have to start with all midi ports on the system deactivated. You then have to use 3d party midi patching software such as Midi Patchbay on Mac (don't use IAC leave it deactivated) or an equivalent Windows program to create nine virtual midi ports to occupy those first eight slots on the system list. Start PD and connect it to the nine virtual ports. Activate all the other midi ports/devices that you need on the system, then use the patching software to do the actually midi routing to external software and devices.
If the above sounds ridiculous -- it is! Supposedly this is actually being worked on (finally) but it requires a major rewrite of badly botched coding. Most of the Pd coders don't really "get" midi and the few that do haven't been very active since they contributed the ALSA code. Take it from someone who has written multiple midi synth editors with Pd-- there's a reason I prefer PureData on linux.
libpd on mac: clarification requested on expected behavior of cpp sample
Hi! I am running Pd-0.47-1-64bit on Mac OS 10.11.6 and libpd 0.9.2. I am trying to work with the samples/cpp/pdtest. Here's the github repo. I currently have an app that takes video and spits out a 2D array of color values for regions of interest to file. I have a pd patch that then loads those into a table and plays the corresponding pitch. I need the two (patch, c++ app) to coordinate the IPC.
I compiled the cpp code in the samples directory however, when running pdtest executable there is no patch opened. Is this by design? I was not able to find a pd-vanilla to build from source so took the most recent (pd-0.47-1-64bit.mac.tar.gz). Does libpd need to have the pd built after libpd? If so, can anyone please point me to a src file?
Here is a truncated output from running the compiled pdtest. Could someone tell me if this is what is expected?
Thank you for your help.
BEGIN Patch Test
Patch: "pd/test.pd" $0: 1003 valid: 1
Patch: "pd/test.pd" $0: 0 valid: 0
Patch: "pd/test.pd" $0: 1005 valid: 1
PD: PATCH OPENED: 1003
print: 0
PD: PATCH OPENED: 1005
print: 0
FINISH Patch Test
BEGIN Message Test
FINISH Message Test
BEGIN MIDI Test
FINISH MIDI Test
BEGIN Array Test
array1 len: 10
array1 0.0857145 0.328572 0.500001 0.57143 0.514287 0.47143 0.357144 0.285715 0.057143 0
array1 0 1 2 3 4 5 6 7 8 9
array1 10 10 10 10 10 10 10 10 10 10
FINISH Array Test
BEGIN PD Test
FINISH PD Test
Processing PD
PD: bang
PD: 100
PD: symbol test string
PD: bang
PD: 100
PD: symbol test string
PD: 1.23 a symbol
PD dollar zero: 1.23 a symbol
PD: 1.23 sent from a List object
PD: msg 1.23 sent from a List object
PD: 1.23 sent from a streamed list
PD MIDI: notein 2 60 64
PD MIDI: ctlin 2 0 64
PD MIDI: pgm 2 101
PD MIDI: midiin 1 239
PD: symbol test
PD: START MSG TEST
CPP: bang toCPP
CPP: float toCPP: 100
CPP: symbol toCPP: kaaa
CPP: list toCPP: 100 2.3 test 1 2 3 ffsfff
CPP: message toCPP: kaa 1 2.3 test ffs
PD: MSG TEST FINISH
PD: START MIDI TEST
PD: MIDI TEST FINISHED
PD: START ARRAY TEST
PD array1: 10
PD array1: 10
PD array1: 10
PD array1: 10
PD array1: 10
PD array1: 10
PD array1: 10
PD array1: 10
PD array1: 10
PD array1: 10
PD: FINISH ARRAY TEST
PD: test_abs: Hello World!
CPP MIDI: note on: 0 0 127
CPP MIDI: note on: 0 0 127
CPP MIDI: note on: 0 60 64
CPP MIDI: control change: 0 64 100
CPP MIDI: program change: 0 99
CPP MIDI: pitch bend: 0 2000
CPP MIDI: aftertouch: 0 100
CPP MIDI: poly aftertouch: 0 64 100
CPP MIDI: midi byte: 0 239
CPP: float env: 75.5457
CPP: float env: 87.9506
CPP: float env: 93.5842
...
CPP: float env: 88.5503
CPP: float env: 87.7612
print: 1
CPP MIDI: note on: 0 0 0
CPP MIDI: note on: 0 1 127
CPP: float env: 86.8932
...
CPP: float env: 41.2584
CPP: float env: 0
print: 2
CPP MIDI: note on: 0 1 0
CPP MIDI: note on: 0 2 127
...
print: 20
CPP MIDI: note on: 0 19 0
CPP MIDI: note on: 0 20 127
Need help to slightly modify a PD project (Rythmboy)
Hello everyone!
I recently stumbled upon a PuraData based step sequencer for my QuNeo MIDI controller, the so called Rythmboy:
http://subtersonic.weebly.com/blog/rhythmboy-a-step-sequencer-for-kmi-quneo
I want to use it as a step sequencer to use with the remix decks in Traktor, so I can add drums to the tracks I play.
Unfortunately, the Rythmboy has an internal MIDI clock, so I can't sync it with an external clock. I already tried to replace the BPM rotary in the patch with "MIDIrealtimein" and the stuff that's also needed, but I can't get it to work.
I managed to do all the other stuff that is needed to work with Traktor (changing the note output, optically mirroring the rotaries, limiting the notes ranges etc.), so I tried, but I don't know how to work with an external midi clock. Another problem that may occur is that the Rhythmboy then needs two MIDI inputs, #1 is the QuNeo and #2 is the external clock (Traktor or my Xone4D mixer).
This is the part of the Rhythmboy that controls the MIDI clock:
The blue box is a tap button to tap in the tempo. This is not needed.
The red box converts a rotary MIDI input between 0 and 127 into a BPM value between 60 and 240 bpm and gives out that value. This is where the changes need to happen I think. I need something that changes the MIDI clock in into a numerical BPM value.
The green box gives output to the rotary LEDs to show the current BPM. This is also not needed.
The other stuff lets a LED blink a metronome, I think.
So, would one of you please tell me what to put in instead of the red box, to make the magic happen?
Best regards,
Spatz
Loading a folder of audio files
@RonHerrema Hello again Ron......
Are you planning to have a main folder, with sub-folders all containing tracks, or are you expecting to just pick folders at random from anywhere on your computer.
If you want to pick from absolutely anywhere then you have three problems....
Most folders will have no wav files.........
Some folders will have wav files at the wrong sample rate....
Most folders containing wav files will contain other files as well... album art, etc.
Anyway..... in "cart" the playlist window is cleared and re-populated as each folder is opened.
If you want to bang a message box you need to give each one a [receive] object and then build a patch to send bangs to those objects. That patch is easy using [random]. The track name will always display in "cart" already. The number of tracks can be known (already the tracklist populator stops when it has created the messages in tracklist).
So you need to add (using the populator) a receive object for each message, place it into "tracklist" and attach (connect) each one to its message.
Either you should do this.........
The populator creates the message, connects it to the [s trackplay] object, creates the [receive 1] object and connects it to the message........ and moves on.
Or this....... the populator runs as in cart, but you add a counter, and when it has finished (how do you know, do you just put a delay and hope) it builds the [receive objects and connects them.
I reckon the first is easier. [s trackplay is object 0 on the page and each message is 1-n for the connect message. You need to change the numbers for the connect messages.......
the populator will build..
[s trackplay] (this is object 0)
[message 1] (this is object 1)
connect object 1 to object 0
[receive 1] (this is object 2)
connect object 2 to object 1
[message 2] (this is object 3....... in "cart" it was object 2 but [receive 1 has been created first)
connect object 3 to object 0
[receive 2] (this is object 4)
connect object 4 to object 3
etc. and it will stop when no more names arrive.
You will need a counter though (don't forget to reset it when the next folder is loaded) so that random can have the right argument. [random x].
You can use the right outlet of [readsf~] to bang out the next number from [random] and start the next track..............another counter and a calculation (when tracks played == track count +1) load the next folder.......... etc.......
Have Fun!
David.
use of threads for i²c I/O external : looking for a good strategy
@nau Hi, same boat (I don't know much about Pd internal functions & pthread), but maybe you can try to see if this external (really similar to my template, but this time to fetch real data for my HiCu project).
Look for m_clock / m_interval and clock_delay.
// ==============================================================================
// gac.c
//
// pd-Interface to [ 11h11 | gac ]
// Adapted by: Patrick Sebastien Coulombe
// Website: http://www.workinprogress.ca/guitare-a-crayon
//
// Original Author: Michael Egger
// Copyright: 2007 [ a n y m a ]
// Website: http://gnusb.sourceforge.net/
//
// License: GNU GPL 2.0 www.gnu.org
// Version: 2009-04-11
// ==============================================================================
// ==============================================================================
#include "m_pd.h"
#include <usb.h> //http://libusb-win32.sourceforge.net
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pthread.h"
#include "../common/gac_cmds.h"
// ==============================================================================
// Constants
// ------------------------------------------------------------------------------
#define USBDEV_SHARED_VENDOR 0x16c0 /* VOTI */
#define USBDEV_SHARED_PRODUCT 0x05dc /* Obdev's free shared PID */
#define DEFAULT_CLOCK_INTERVAL 34 /* ms */
#define OUTLETS 11
#define USBREPLYBUFFER 14
unsigned char buffer[USBREPLYBUFFER]; //accessible everywhere
// ==============================================================================
// Our External's Memory structure
// ------------------------------------------------------------------------------
typedef struct _gac // defines our object's internal variables for each instance in a patch
{
t_object p_ob; // object header - ALL pd external MUST begin with this...
usb_dev_handle *dev_handle; // handle to the gac usb device
void *m_clock; // handle to our clock
double m_interval; // clock interval for polling edubeat
double m_interval_bak; // backup clock interval for polling edubeat
int is_running; // is our clock ticking?
void *outlets[OUTLETS]; // handle to the objects outlets
int x_verbose;
pthread_attr_t gac_thread_attr;
pthread_t x_threadid;
} t_gac;
void *gac_class; // global pointer to the object class - so pd can reference the object
// ==============================================================================
// Function Prototypes
// ------------------------------------------------------------------------------
void *gac_new(t_symbol *s);
void gac_assist(t_gac *x, void *b, long m, long a, char *s);
void gac_bang(t_gac *x);
void gac_bootloader(t_gac *x);
static int usbGetStringAscii(usb_dev_handle *dev, int ndex, int langid, char *buf, int buflen);
void find_device(t_gac *x);
// =============================================================================
// Threading
// ------------------------------------------------------------------------------
static void *usb_thread_read(void *w)
{
t_gac *x = (t_gac*) w;
int nBytes;
while(1) {
pthread_testcancel();
if (!(x->dev_handle)) find_device(x);
else {
nBytes = usb_control_msg(x->dev_handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
EDUBEAT_CMD_POLL, 0, 0, (char *)buffer, sizeof(buffer), DEFAULT_CLOCK_INTERVAL);
if(x->x_verbose)post("thread read %i bytes", nBytes);
//post("%i b", nBytes);
}
}
return 0;
}
static void usb_thread_start(t_gac *x) {
// create the worker thread
if(pthread_attr_init(&x->gac_thread_attr) < 0)
{
error("gac: could not launch receive thread");
return;
}
if(pthread_attr_setdetachstate(&x->gac_thread_attr, PTHREAD_CREATE_DETACHED) < 0)
{
error("gac: could not launch receive thread");
return;
}
if(pthread_create(&x->x_threadid, &x->gac_thread_attr, usb_thread_read, x) < 0)
{
error("gac: could not launch receive thread");
return;
}
else
{
if(x->x_verbose)post("gac: thread %d launched", (int)x->x_threadid );
}
}
//--------------------------------------------------------------------------
// - Message: bootloader
//--------------------------------------------------------------------------
void gac_bootloader(t_gac *x)
{
int cmd;
int nBytes;
unsigned char bootloaderbuffer[8];
cmd = 0;
cmd = EDUBEAT_CMD_START_BOOTLOADER;
if (!(x->dev_handle)) find_device(x);
else {
nBytes = usb_control_msg(x->dev_handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
cmd, 0, 0, (char *)bootloaderbuffer, sizeof(bootloaderbuffer), DEFAULT_CLOCK_INTERVAL);
}
}
//--------------------------------------------------------------------------
// - Message: bang -> poll gac
//--------------------------------------------------------------------------
void gac_bang(t_gac *x) {
int i,n;
int replymask,replyshift,replybyte;
int temp;
for (i = 0; i < OUTLETS; i++) {
temp = buffer[i];
switch(i) {
case 0:
replybyte = buffer[8];
replyshift = ((0 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
case 1:
replybyte = buffer[8];
replyshift = ((1 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
case 2:
replybyte = buffer[8];
replyshift = ((2 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
case 3:
replybyte = buffer[8];
replyshift = ((3 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
case 4:
replybyte = buffer[9];
replyshift = ((0 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
case 5:
replybyte = buffer[9];
replyshift = ((1 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
case 6:
replybyte = buffer[9];
replyshift = ((2 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
case 8:
temp = buffer[10];
replybyte = buffer[13];
replyshift = ((0 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
case 9:
temp = buffer[11];
replybyte = buffer[13];
replyshift = ((1 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
case 10:
temp = buffer[12];
replybyte = buffer[13];
replyshift = ((2 % 4) * 2);
replymask = (3 << replyshift);
temp = temp * 4 + ((replybyte & replymask) >> replyshift);
break;
}
outlet_float(x->outlets[i], temp);
}
}
//--------------------------------------------------------------------------
// - The clock is ticking, tic, tac...
//--------------------------------------------------------------------------
void gac_tick(t_gac *x) {
clock_delay(x->m_clock, x->m_interval); // schedule another tick
gac_bang(x); // poll the edubeat
}
//--------------------------------------------------------------------------
// - Object creation and setup
//--------------------------------------------------------------------------
int gac_setup(void)
{
gac_class = class_new ( gensym("gac"),(t_newmethod)gac_new, 0, sizeof(t_gac), CLASS_DEFAULT,0);
// Add message handlers
class_addbang(gac_class, (t_method)gac_bang);
class_addmethod(gac_class, (t_method)gac_bootloader, gensym("bootloader"), A_DEFSYM,0);
post("bald-approved gac version 0.1",0);
return 1;
}
//--------------------------------------------------------------------------
void *gac_new(t_symbol *s) // s = optional argument typed into object box (A_SYM) -- defaults to 0 if no args are typed
{
t_gac *x; // local variable (pointer to a t_gac data structure)
x = (t_gac *)pd_new(gac_class); // create a new instance of this object
x->m_clock = clock_new(x,(t_method)gac_tick);
x->x_verbose = 0;
x->m_interval = DEFAULT_CLOCK_INTERVAL;
x->m_interval_bak = DEFAULT_CLOCK_INTERVAL;
x->dev_handle = NULL;
int i;
// create outlets and assign it to our outlet variable in the instance's data structure
for (i=0; i < OUTLETS; i++) {
x->outlets[i] = outlet_new(&x->p_ob, &s_float);
}
usb_thread_start(x); //start polling the device
clock_delay(x->m_clock,0.); //start reading the buffer
return x; // return a reference to the object instance
}
//--------------------------------------------------------------------------
// - Object destruction
//--------------------------------------------------------------------------
void gac_free(t_gac *x)
{
if (x->dev_handle) usb_close(x->dev_handle);
freebytes((t_object *)x->m_clock, sizeof(x->m_clock));
while(pthread_cancel(x->x_threadid) < 0)
if(x->x_verbose)post("gac: killing thread\n");
if(x->x_verbose)post("gac: thread canceled\n");
}
//--------------------------------------------------------------------------
// - USB Utility Functions
//--------------------------------------------------------------------------
static int usbGetStringAscii(usb_dev_handle *dev, int ndex, int langid, char *buf, int buflen)
{
char asciibuffer[256];
int rval, i;
if((rval = usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) + ndex, langid, asciibuffer, sizeof(asciibuffer), 1000)) < 0)
return rval;
if(asciibuffer[1] != USB_DT_STRING)
return 0;
if((unsigned char)asciibuffer[0] < rval)
rval = (unsigned char)asciibuffer[0];
rval /= 2;
/* lossy conversion to ISO Latin1 */
for(i=1;i<rval;i++){
if(i > buflen) /* destination buffer overflow */
break;
buf[i-1] = asciibuffer[2 * i];
if(asciibuffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
buf[i-1] = '?';
}
buf[i-1] = 0;
return i-1;
}
//--------------------------------------------------------------------------
void find_device(t_gac *x) {
usb_dev_handle *handle = NULL;
struct usb_bus *bus;
struct usb_device *dev;
usb_init();
usb_find_busses();
usb_find_devices();
for(bus=usb_busses; bus; bus=bus->next){
for(dev=bus->devices; dev; dev=dev->next){
if(dev->descriptor.idVendor == USBDEV_SHARED_VENDOR && dev->descriptor.idProduct == USBDEV_SHARED_PRODUCT){
char string[256];
int len;
handle = usb_open(dev); /* we need to open the device in order to query strings */
if(!handle){
error ("Warning: cannot open USB device: %s", usb_strerror());
continue;
}
/* now find out whether the device actually is gac */
len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 0x0409, string, sizeof(string));
if(len < 0){
post("gac: warning: cannot query manufacturer for device: %s", usb_strerror());
goto skipDevice;
}
post("::::::%s", string);
if(strcmp(string, "11h11") != 0)
goto skipDevice;
len = usbGetStringAscii(handle, dev->descriptor.iProduct, 0x0409, string, sizeof(string));
if(len < 0){
post("gac: warning: cannot query product for device: %s", usb_strerror());
goto skipDevice;
}
if(strcmp(string, "Gac") == 0)
break;
skipDevice:
usb_close(handle);
handle = NULL;
}
}
if(handle)
break;
}
if(!handle){
post("Could not find USB device 11h11/gac");
x->dev_handle = NULL;
} else {
x->dev_handle = handle;
post("Found USB device 11h11/gac");
}
}
Cheers
How to install externals, libraries, gui plug-ins, etc.
Edit: This post was originally written with Pd-extended 0.43 in mind. These days there is a nice little plugin called Deken that you can use to easily download and install most of the popular libraries in Pd. It comes bundled with recent versions of Pd-vanilla. You can still use namespaces to load up the objects for most libraries, but for some libraries like zexy that have all the objects bundled into a single file, you will still need to use [declare] to load it up.
Installing libraries and plug-ins isn't so obvious. This guide will hopefully clear up the process, and may even explain more than you need to know.
Recent changes
This first section is mainly for those upgrading to Pd-0.43 from previous versions. If you're new to Pd and are starting on 0.43, you can just skip this section and get on with loading libraries.
It use to be that installing a library was done by putting it wherever you wanted on your system and adding its path to the preferences. While this wasn't particularly difficult, it did have some problems. Recent efforts have been made to standardize this a bit so those problems can be avoided.
In Pd-extended 0.43, you can't add paths from within Pd any more like you used to. You can open the preferences and add a path, but it won't save it. This means that non-default libraries won't load on start-up any more; you have to load them from within the patch. While this sounds like a hassle, it does have the advantage that patches are much easier to share. You don't have to worry about others having different start-up settings than you. It also forces the patch to document what libraries are being used, so if an object isn't loading, you don't have to go on some crazy hunt to find out where it came from or what it's supposed to do.
Putting them in the right folder
To make sure Pd can easily find the library, you need to put them in the right folder. This is OS dependent. The following folders are your options (taken from here). I personally recommend putting them in the user-specific folders since they are likely easier to migrate when updating your OS.
Linux:
User-specific:
~/pd-externals
Global:
/usr/local/lib/pd-externals
Mac OSX
User-specific:
~/Library/Pd
Global:
/Library/Pd
Windows
User-specific:
%AppData%/Pd
Global:
%CommonProgramFiles%/Pd
Linux and OSX are pretty straight-forward. "~" means your home folder.
Windows is a bit trickier. %AppData% and %CommonProgramFiles% are environment variables that contain specific directories. What the exact directory is depends on which version of Windows you are on. You can find out what it is by opening up the command line and typing this:
echo %AppData%
You might end up with something like C:\Users\username\AppData\Roaming or C:\Documentes and Settings\username\Application Data. Also, to see it in the file browser, you might need to show hidden files. At any rate, once you find the directory, create a Pd folder if there isn't one, and put your library, objects, or plug-ins there.
Loading whole libraries
To load a library you have a few options. The one that works on both vanilla and extended is to use [declare -stdpath libraryname]. The libraryname is the name of the folder that all the objects/abstractions are in.
[declare] doesn't always work as expected in abstractions, though. In Pd-extended, you can also use [import], which works well in abstractions. I have found that sometimes it doesn't work with libraries of abstractions that don't have a meta file, though. But that can be fixed by just making one. Simply create an empty Pd patch and save it as libraryname-meta.pd in the library's folder. That's all the meta patch is.
A third option (also Pd-extended only) is to use [path]. This is new to Pd-extended 0.43 and works similarly to [declare]. I haven't needed it, yet. But it's there.
Once the library is loaded, you should be able to load an object or abstraction just by creating it by name.
Loading objects or abstractions using namespaces
While this method means a little more typing, it is also the safest, and it makes it easier to find out what objects are from which library. The way you do it is add the library name (i.e. the namespace) to the beginning of the object when you call it, like this:
[zexy/multiplex~] <-- load the [multiplex~] object from zexy
[cyclone/comb~] <-- load [comb~] from cyclone
You don't have to load the library with [import] or [declare] for this to work. You just call the object that way.
Why is this safest? Because it's possible for different libraries to have objects with the same name. For example, both cyclone and zexy have an object called [mean]. But they don't work exactly the same. zexy's takes a list, while cyclone's takes in a continuous stream. If you have both libraries loaded (and in Pd-extended, these two libraries happen to be loaded by default), you can't be sure which one you're getting if you just type [mean]. However, if you type [cyclone/mean], you know exactly which one you are getting.
Beatmaker Abstract
http://www.2shared.com/photo/mA24_LPF/820_am_July_26th_13_window_con.html
I conceptualized this the other day. The main reason I wanted to make this is because I'm a little tired of complicated ableton live. I wanted to just be able to right click parameters and tell them to follow midi tracks.
The big feature in this abstract is a "Midi CC Module Window" That contains an unlimited (or potentially very large)number of Midi CC Envelope Modules. In each Midi CC Envelope Module are Midi CC Envelope Clips. These clips hold a waveform that is plotted on a tempo divided graph. The waveform is played in a loop and synced to the tempo according to how long the loop is. Only one clip can be playing per module. If a parameter is right clicked, you can choose "Follow Midi CC Envelope Module 1" and the parameter will then be following the envelope that is looping in "Midi CC Envelope Module 1".
Midi note clips function in the same way. Every instrument will be able to select one Midi Notes Module. If you right clicked "Instrument Module 2" in the "Instrument Module Window" and selected "Midi input from Midi Notes Module 1", then the notes coming out of "Midi Notes Module 1" would be playing through the single virtual instrument you placed in "Instrument Module 2".
If you want the sound to come out of your speakers, then navigate to the "Bus" window. Select "Instrument Module 2" with a drop-down check off menu by right-clicking "Inputs". While still in the "Bus" window look at the "Output" window and check the box that says "Audio Output". Now the sound is coming through your speakers. Check off more Instrument Modules or Audio Track Modules to get more sound coming through the same bus.
Turn the "Aux" on to put all audio through effects.
Work in "Bounce" by selecting inputs like "Input Module 3" by right clicking and checking off Input Modules. Then press record and stop. Copy and paste your clip to an Audio Track Module, the "Sampler" or a Side Chain Audio Track Module.
Work in "Master Bounce" to produce audio clips by recording whatever is coming through the system for everyone to hear.
Chop and screw your audio in the sampler with highlight and right click processing effects. Glue your sample together and put it in an Audio Track Module or a Side Chain Audio Track Module.
Use the "Threshold Setter" to perform long linear modulation. Right click any parameter and select "Adjust to Threshold". The parameter will then adjust its minimum and maximum values over the length of time described in the "Threshold Setter".
The "Execution Engine" is used to make sure all changes happen in sync with the music.
IE>If you selected a subdivision of 2, and a length of 2, then it would take four quarter beats(starting from the next quarter beat) for the change to take place. So if you're somewhere in the a (1e+a) then you will have to wait for 2, 3, 4, 5, to pass and your change would happen on 6.
IE>If you selected a subdivision of 1 and a length of 3, you would have to wait 12 beats starting on the next quater beat.
IE>If you selected a subdivision of 8 and a length of 3, you would have to wait one and a half quarter beats starting on the next 8th note.
http://www.pdpatchrepo.info/hurleur/820_am,_July_26th_13_window_conception.png
Conditional gate
@mod said:
But time and time again we see the same sort of posts. People who just want to turn an audio signal on and off use something like [spigot~], people use [counter] instead of basic pd objects. They post these patches and run into trouble that could easily be avoided by only using vanilla objects unless necessary.
What's wrong with [counter]? Objects like those remedy the trouble of trying to figure out how to make one using only vanilla objects. Not that it's particularly difficult to do, but it may just be more intuitive or time saving to someone to use [counter].
Of course most people are using extended, but it's such a vast ocean that no-one knows how EVERY object in extended works. The object in question here, [gate], i can only hazard a guess, but i'm thinking that a maximum of 50% of users know the cyclone library and in particular the [gate] object well enough to debug a patch.
Well, that's where the basic advice that you and others have posted comes in: Right click -> Help.
Besides, I don't really think that because less people know or use an object should deter one from trying it. It may just make more sense or fit with their particular programming preferences. I know I like to build from low-level objects and work up, but not everyone is so interested. For example, I've built my own compressor abstraction. But plenty of other people would rather just load a compressor object and be done with it. Nothing wrong with either approach.
Also, I've been using Pd long enough that I feel comfortable saying I'm in "expert" territory. I don't know what every extended object does, but I don't know what EVERY vanilla object does, either.
(I'm speaking from my own bad experiences here too, because my old patches had some extended objects in them, and i answered countless emails from people having trouble with those externals not loading. I could have saved myself a lot of time by just using the correct vanilla constructs in the first place)
Now, this is a different issue, and I'm more inclined to agree here. You can definitely ensure higher compatibility by sticking to vanilla objects, as some externals don't work correctly on all OS's and vanilla users may not have some of the more popular libraries installed, but it does come with the potential costs of flexibility or computational load. And, this is only an issue if you want to share your patches or use them on other OS's.
When I'm writing a patch that's for personal use only, and I don't expect to be sharing it, I tend to use whatever I want. But if I'm making an abstraction I might share, I usually follow an order of precedence:
1. Use vanilla objects where possible/practical for best compatibility.
2. Use extended objects if needed, since it's used widely and newbie-friendly.
3. If absolutely necessary, use a popular lib not included in Pd-extended, like GridFlow or RjLib (I've never had to do this, yet).
But that's entirely for compatibility reasons only.
@Shakasin said:
But is there something in vanilla that could replace my [gate] just curious ?
. [== 1] [== 2] [== 3]
| | |
[spigot] [spigot] [spigot] etc....
Connect the gate number to the left inlet of the [== ] objects, and the value you want to pass to the left inlet of the [spigot]s.
MIDI YOKE beginner
Hello, i stumbled on Pure Data today and loved the idea of controlling Ableton via an ipod touch. So now i've been sitting here for two hours trying to get this to work.
I've downloaded Pure data and the app for the ipod. So far so good.
When i press buttons on the ipod, it recognises that in Pure Data. Going great.
Now, and i should point out i'm on a windows computer, i have to connect it to ableton. No IAC bus midi stuffs since windows don't have those, so Midi Yoke it is.
I have installed Midi Ox (couldn't find Midi Yoke so... is this the same program?)
and i think... i understand it. I set midi out on DP to midi yoke 1. Set Midi yoke 1 in to midi Yoke 1 out in Midi Ox. In ableton i then highlight everything (track, sync and remote) on both Midi yoke 1 out and in (because i dont know what to highlight so...)
now... nothing. I think the problem is that Midi Ox don't recognise the Midi out from DP but i'm not sure. I don't see any changes at all when i press the buttons on the Ipod in Midi ox.
I'm sorry for all this rambling, and i have googled as much as i can but i haven't found any solution. I did find a tutorial named how to setup as i described http://www.gadgetcracker.com/2009/06/how-to-iphone-touchosc-pure-data-ableton-live/ but link just 404
Please help me
Traktor (will work with others)Coge Midi clock Sync with OSC
This is a cross platform alternative for synchronizing two(or more) different computers to one Midi Clock.
Since one will have coge this will be between a Mac OSX and windows running traktor that produces midi clock.
For windows Midi Yoke (tested in XP) to wrap Midi clock to Pure Data extended (tested with v 0.41.4) from there the clock will be sent has an OSC message to one or all network computer(s). On the listening side there will be one other Pure Data patch converting a specific OSC message to Midi clock. Then coge can catch this midi clock just by clicking "Midi clk".
This is nothing special but it took me almost 3 weeks to accomplish it. Given that i knew nothing about pure data at the time, this site was very helpful. All examples were gathered from here.
Also note that this is not the best way.
There are Midi cables for this.
There are usb to midi converters, for those who don't have midi ports. Also external sound boards quite good with several inputs and outputs.
I have experienced a +/- 3 Beats float of BPM count on coge but always around the correct number, over time this seems to float less.
This still lacks testing.
Anyway.
You'll need Pure data extended on every machine.
You'll need Midi Yoke on Windows.
You can use Yac Driver on Mac OSX for midi wrap.
Don't know for linux, sorry. (read somewhere something about jack)
On pure data you'll need to define the midi device input or output which ever is the case.
On windows it's easy on any pure data windows you can set midi devices, choose midi Yoke (the channel number should be the same in the receiver input and sender output).
On OSX it's on the main window, under preferences.
If using this with quartz composer one can skip the pure data on the OSC server side (which is the one that listens). If adding more functions to this keep in mind that quartz composer does not understands 0 arguments messages. (I think this should be a bug)
You are advised to change the IP on the pure data patch to which ever is your destination. You can use 0.0.0.0 to broadcast. Don't use wireless, it's a 0 security communication protocol.
Hope to save someone's time. GL