Purr Data rc1
Purr Data release candidate 1!
- fix for iemgui colors not getting properly updated
- allow opening a file at OSX startup
- fix weird behavior when dragging files onto a Pd patch
- remove more debugging statements
- fix slider display error
- fix "Select All" on OSX
- fix allowed characters in atom box dialog
- forward console key events to Pd
- change [draw group] to [draw g]
- add fit width/height/optimal zoom shortcuts
- fix consistency bug with [draw]
- put "Window" menu in the customary position next to "Help" menu
- fix clipboard operations for patch snippets
- some translation fixes
- some Pd-l2ork fixes backported
- improvements for opening files in the same instance
please report lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
PortMidi 'Invalid Device ID'
I have been having this issue (maybe non-issue) for some time.
Here is my set up:
Teensy 2.0 MIDI Device
Pd 0.46.7
Late 2013 Macbook Pro
I am using a Teensy MIDI device in Pd.
If I connect the Teensy device, then launch Pd, I get the following error message:
could not open midi input 0 (Teensy MIDI): PortMidi: 'Invalid device ID'
could not open midi output 1 (Teensy MIDI): PortMidi: 'Invalid device ID'
Under my MIDI settings I have "Teensy MIDI" selected both as my input and output.
If I re-select "Teensy MIDI" in both dialogs of the MIDI preferences menu, and hit OK the same error message will reappear in Pd's print window.
Though I get this error, it seems to not effect the use of the device in any way.
When I connect the device to a windows machine, I don't have this PortMidi error message.
I have also connected this device to my iPhone using MobMuPlat, no issues.
Any advice would be helpful.
GUI port of Pd-l2ork Alpha 0 release
Hi,
tried to install it, but my Jessie couldn't resolve dependencies, any clue?
nau@lapdell:~/Bureau$ sudo dpkg -i pd-l2ork-x86_64-jessie-a0.deb
(Reading database ... 166599 files and directories currently installed.)
Preparing to unpack pd-l2ork-x86_64-jessie-a0.deb ...
Unpacking pd-l2ork (20160406) over (20160406) ...
dpkg: dependency problems prevent configuration of pd-l2ork:
pd-l2ork depends on tcl; however:
Package tcl is not installed.
pd-l2ork depends on tk; however:
Package tk is not installed.
pd-l2ork depends on libglew-dev; however:
Package libglew-dev is not installed.
pd-l2ork depends on libmagick++-dev; however:
Package libmagick++-dev is not installed.
pd-l2ork depends on libftgl2; however:
Package libftgl2 is not installed.
pd-l2ork depends on libgmerlin0; however:
Package libgmerlin0 is not installed.
pd-l2ork depends on libgmerlin-avdec1; however:
Package libgmerlin-avdec1 is not installed.
pd-l2ork depends on libavifile-0.7c2; however:
Package libavifile-0.7c2 is not installed.
pd-l2ork depends on libmpeg3-1 | libmpeg3-2; however:
Package libmpeg3-1 is not installed.
Package libmpeg3-2 is not installed.
pd-l2ork depends on libquicktime2; however:
Package libquicktime2 is not installed.
pd-l2ork depends on libfftw3-3; however:
Package libfftw3-3 is not installed.
pd-l2ork dep
dpkg: error processing package pd-l2ork (--install):
dependency problems - leaving unconfigured
Processing triggers for hicolor-icon-theme (0.13-1) ...
Processing triggers for shared-mime-info (1.3-1) ...
Processing triggers for man-db (2.7.0.2-5) ...
Processing triggers for desktop-file-utils (0.22-1) ...
Processing triggers for gnome-menus (3.13.3-6) ...
Processing triggers for mime-support (3.58) ...
Processing triggers for systemd (215-17+deb8u4) ...
Errors were encountered while processing:
pd-l2ork
Thanks!
Nau
Automatically enabling audio and MIDI devices as they're plugged in
@lzr Hello,
I am using windows so the experience is maybe in some respects different.
However, what you have observed holds true.
But for windows none of it is specific only to Pd.
I had tried using asio4all which performs much like "aggregate device" in osx. However in windows a new instance of asio4all is run for each program when it is opened and so new devices do not show up.
Maybe that is not so for "aggregate device"? and you could select that...... as because the new devices will not show in Pd while it is running they will not change the position of "aggregate device" in the Pd device list? But will they appear always in the same order in the "aggregate device"? I doubt it.
Then I hoped to use a batch file to always select asio4all as my Pd asio driver, but if any device is plugged in before Pd runs that will change the position of the driver in the Pd list.
So in the end I have a batch file for every setup, and I am rigorous about the order in which I plug my devices. A set of batch files and a set of text files to remind me how to proceed....
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
Convert midi files to use with arduino
hey guys!
as the paragliding season is coming i want to build a variometer (flying instrument measuring ascent)
that plays some nice loops instead of annoying beeps. i got an old airpressure sensor out of a broken vario and a arduino. i found a sketch that plays simple melodies. now i need to find some data to feed it with.
arduino needs the following format:
int melody[] = {
NOTE_C4, NOTE_G3,NOTE_G3, NOTE_A3, NOTE_G3,0, NOTE_B3, NOTE_C4};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
4, 8, 8, 4,4,4,4,4 };
i never worked with midi files so i need your help here.
i want to load midi file in pd, and analyse it there, to output a list of NOTES, and one of DURATIONS, to feed the flash memory with kinky gamboy sounds.
any clues for me how to get NOTE + DURATION out of a midi stream?
thx
Sebastian
PD cuts off other sound on the computer
Hi,
Yes.
I have turned on the computer and freshly started jackd. I start it from qjackcti (http://en.wikipedia.org/wiki/Qjackctl).
Error messages:
1. first window:
Could not connect to JACK server as client.
- Overall operation failed.
- Unable to connect to server.
Please check the messages window for more info.
2. Message window:
13:55:36.236 Patchbay deactivated.
13:55:36.254 Statistics reset.
Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started
13:55:36.336 ALSA connection graph change.
13:55:36.559 ALSA connection change.
13:55:36.560 ALSA connection graph change.
13:55:38.356 Startup script...
13:55:38.357 artsshell -q terminate
Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started
sh: artsshell: not found
13:55:38.760 Startup script terminated with exit status=32512.
13:55:38.760 JACK is starting...
13:55:38.760 /usr/bin/jackd -dalsa -d/dev/dsp -r44100 -p256 -n2 -Xseq
13:55:38.798 JACK was started with PID=2106.
Cannot create thread 1 Operation not permitted
Cannot create thread 1 Operation not permitted
jackdmp 1.9.6
Copyright 2001-2005 Paul Davis and others.
Copyright 2004-2010 Grame.
jackdmp comes with ABSOLUTELY NO WARRANTY
This is free software, and you are welcome to redistribute it
under certain conditions; see the file COPYING for details
JACK server starting in realtime mode with priority 10
Cannot lock down memory area (Cannot allocate memory)
ALSA lib control.c:882:(snd_ctl_open_noupdate) Invalid CTL /dev/dsp
control open "/dev/dsp" (No such file or directory)
ALSA lib control.c:882:(snd_ctl_open_noupdate) Invalid CTL /dev/dsp
control open "/dev/dsp" (No such file or directory)
audio_reservation_init
Acquire audio card Audio-1
creating alsa driver ... /dev/dsp|/dev/dsp|256|2|44100|0|0|nomon|swmeter|-|32bit
ALSA lib control.c:882:(snd_ctl_open_noupdate) Invalid CTL /dev/dsp
control open "/dev/dsp" (No such file or directory)
Cannot initialize driver
JackServer::Open() failed with -1
Failed to start server
13:55:39.278 JACK was stopped with exit status=255.
13:55:39.279 Post-shutdown script...
13:55:39.279 killall jackd
jackd: no process found
13:55:39.700 Post-shutdown script terminated with exit status=256.
13:55:40.822 Could not connect to JACK server as client. - Overall operation failed. - Unable to connect to server. Please check the messages window for more info.
Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started
13:55:54.576 Could not connect to JACK server as client. - Overall operation failed. - Unable to connect to server. Please check the messages window for more info.
Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started
13:58:38.483 Could not connect to JACK server as client. - Overall operation failed. - Unable to connect to server. Please check the messages window for more info.
Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started
13:59:09.197 Could not connect to JACK server as client. - Overall operation failed. - Unable to connect to server. Please check the messages window for more info.
Cannot connect to server socket err = No such file or directory
Cannot connect to server socket
jack server is not running or cannot be started
As you can see the last paragraph (...jjack server is not running or cannot be started...) then repeats itself over and over again every 30 seconds.
Seems like Jack isn't working??
Thanks.
Help Building Midi Generative Patches
Hi everyone,
I'm not really a programmer and i need help creating some patches that i can keep and use to generate midi for my compositions. Nothing too complex. I can't afford Max, so will have to be in either PD or Bidule i guess?
Idea 1
I need a patch that generates a metronome rhythm, just a simple note on/note off metronome for one definable note, but with the ability to control the speed of the rhythm, from slow, to really fast, on the fly and with the note length set as a percentage of the interval between notes, again changeable on the fly. This then goes out to my DAW to trigger a sample.
Idea 2
Pretty much the same as Idea 1, but with a definable range of note outputs, so as to trigger different samples within a soft sampler in the DAW, choosing each sample randomly.
Idea 3
Same as Idea 2, but output to go to a synth. So would be cool to be able to output chords and for each note on trigger to also output random triggers for lfo/cut off/other cool parameters etc. too.
Idea 4
I'd also like a simple sequence tool which outputs a short repeating predefined sequence of midi note on and note off to send to the DAW, but where I can control and change the interval/time between each note on trigger on the fly to create varied and interesting patterns and again where the note length is changeable on the fly and set as a percentage of the interval between notes.
I want to record the midi output into a DAW where i can then edit it down into the most interesting bits and build compositions.
None of the ideas need a GUI. I just want these useful tools to keep and produce works with and that I can maybe add to and develop in the future when I've learned how to program!
Any ideas, help building or tips would be really appreciated!
Thanks,
Henry
The Infinity Series!
Domien,
it's rather difficult to me to "understand" your sound example, but I'm interrested in trying to "examine" your patch and take an impulse on it !
I love this "back-and-forth" creative suggestions scheme between forum's users. So here is another input, received from a friend of mine two or three month ago.
When you wrote about "related notes values", it reminded me this "Hexagonal toroïd representation" theory you can learn about at
http://www.musimediane.com/numero1/Chouvel-analyse/torehexa.html
Sorry, this is in french :-[
It says (among many other more complicated implications) that if you take a sheet of paper and that you draw on it a "honeycomb" structure with hexagonal tiles, when you place a note value in a given tile and then decide to place two other notes (fifth and major 3rd) next to it in a particuliar fashion, you can name (i.e. 'give a note value to') every other tile of the 'sheet', following a simple rule. At a certain point you see that the 'sheet' can be folded to become a cylinder, wich can again fold itself to become a torus.
Then, anywhere on this "hexagonal torus", any tile is directly 'surrounded' by an 'orbit' made of 3rd and 5ths intervals, made of 'rather consonant' notes (all these notes form all existing triad chords that include the central note), and this orbit is itself surrounded by a second (thus wider) orbit formed by kinda 'contrapuntal' notes.
I made a patch that allows you to individually trig these notes in orbital disposition with a midi kebd, either changing 'central note' whenever a new note is played, or keeping it fixed.
A previous simplier "banged" version can be seen in the image posted.
Anyone interrested tell me.
Nau
How to specify the MIDI channel?
hi maelstorm,
first of all i am really happy that you replied to this post. i got many useful hints and aha's from reading your posts.
also the use of the flag "-mididevout" which i used (found here the info in this post http://puredata.hurleur.com/sujet-3187-more-midi-output-device-options-needed).
since i set the flag, the devices are always listed and the settings do not get lost.
so device A is always input device 1 and output device 2, and device B always output device 1.
anyway, maybe i do not fully understand the use of the flag, the channel the devices are sending seems to be not always the same.