libpd on mac: clarification requested on expected behavior of cpp sample
Thanks for those links Monetus. I'm pretty close with my existing setup and will first try to work with that when I have some more time. Some of the output from the samples/cpp/pdtest appears to be as expected.
However, from main.cpp
cout << endl << "BEGIN Patch Test" << endl;
// open patch
Patch patch = pd.openPatch("pd/test.pd", ".");
cout << patch << endl;
// close patch
pd.closePatch(patch);
cout << patch << endl;
// open patch again
patch = pd.openPatch(patch);
cout << patch << endl;
// process any received messages
//
// in a normal case (not a test like this), you would call this in
// your application main loop
pd.processFloat(1, inbuf, outbuf);
pd.receiveMessages();
cout << "FINISH Patch Test" << endl;
the response
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
seems right but no patch was opened and if I already opened that patch before running the executable, none of the print messages (called later in the code) showed up in the console of pd. I'll focus on this and try to repost to the forum when I have a better idea of what is going on.
Purr Data alpha6
This is the alpha 6 release of Purr Data (the GUI port of Pd-l2ork)
Change log:
- bump jmmmp to 0.47
- fix extraneous colon in [print -n]
- add missing dll dependencies for various externals for Windows
- fix bug with zombie window sometimes getting created for subpatches
- fix nbox label color not updating
- fix "New Array" dialog buttons to keep from creating multiple arrays
- Windows build simplification-- you can now build a Windows installer
using msys2 in only 7 steps! Works on both win32 and win64 machines - clean up help patches
This is the last alpha, so please report lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
Purr Data alpha5
This is the alpha 5 release of Purr Data (the GUI port of Pd-l2ork)
Change log:
- added rjlib for Windows and OSX (already available in GNU/Linux)
- more fixes for OSX (thanks to Matt Barber)
- bump fftease, pmpd, lyonpotpourri version (already available in GNU/Linux)
- added fluid~ external
- fix regression with filenames on Windows
- improved Windows installer
- added disis externals for OSX and Windows
- simplified Windows build instructions
- added rpi deb package for Raspbian
- fix regression that kept standard libs from loading on Windows
Please report lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
Purr Data alpha4
This is the alpha 4 release of Purr Data (the GUI port of Pd-l2ork)
Change log:
- added installer for Windows
- added lyonpotpourri, fftease, and autotune on OSX and Windows builds
- added PDP on OSX (thanks to Matt Barber)
- fixed MIDI dialog
- aesthetic improvements to preferences dialog
- fixed a crasher when using Jack
- fixed bugs with drawnumber and drawsymbol not displaying
- fixed stray js errors
- fixed a GOP display bug
- fixed regression when deleting the last argument in a comment or object box
- fixed bug with the "quick find" bar
- updated jmmmp to 0.46
- fixed red gop rectangle drag anchor
- fixed "double-undo" bug (Thanks to Matt Barber)
Please report lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
Purr Data alpha3
This is the alpha 2 release of Purr Data (the GUI port of Pd-l2ork)
Change log:
- visual improvements to the dialogs (thanks to Albert Gräf)
- fix error with "couldn't unbind" error with "Put" menu array
- fix resize anchor for [cnv]
- fix problem with starting up on Windows if there's a space in the path
- ported Scope~ from cyclone
- fix bug with disappearing text in object and message boxes
- fix resizing bug with atom box
- fix problem with iemguis in subpatches causing errors in the GUI
- fix message box border
Lots of changes in this one, so expect-- and please report-- lots of bugs to
https://git.purrdata.net/jwilkes/purr-data/issues
Binaries:
Purr Data alpha2
This is the alpha 2 release of Purr Data (the GUI port of Pd-l2ork)
Change log:
- OSX build included (Thanks to Matt Barber)
- Gem works on Windows now
- fixed bug that broke infinite undo in some cases
- build improvements for deb packages (Thanks to Albert Gräf)
- shorter console messages for legacy tk gui commands (Thanks to Albert Gräf)
- determistic build of deb packages with l2ork_addons/tar_em_up.sh
- you can now use the build instructions to build a binary on Windows with
msys2 - updated moocow and some iem libraries
- fixed bug where the window menus weren't inheriting the OS theme correctly
on GNU/Linux distros
Lots of changes in this one, so expect-- and please report-- lots of bugs to
git.purrdata.net
Binaries:
Finally:
Albert Gräf added an AUR package here
"This always builds from the latest git sources and can be used as a drop-in replacement for the pd-l2ork or pd-l2ork-git package. Just run yaourt -S purr-data-git
and you should be set (be patient, this package takes quite a while to build)."
how does [list drip] actually work?
@rjp9 yup, basically you put items into a stack and take them out of the stack the reverse order, so it is used to remember what needs to be done next.
an example, the "call stack" is the term used for an area of RAM that stores which function a program is in, so if you have a "main" function:
main(int argc, char ** argv) {
somefunction()
someotherfunction()
}
and the functions look like:
somefunction() {
int cat
cat = somethirdfunction()
}
someotherfunction() {
float dog
somefunction()
}
somethirdfunction() {
char lettera
-- do nothing
}
then when the program runs the call stack will look like this at various times:
when it starts main:
main -- has space for function info and argc, argv
when somefunction is called:
main (bottom of stack)
somefunction - top of stack - has space for function info and an integer (cat)
then somethirdfunction is called and cat's value is set, while in somethirdfunction the stack looks like this:
main (bottom of stack)
somefunction - middle of stack
somethirdfunction - top of stack, has space for lettera
since somethirdfunction doesn't do anything, it returns:
main (bottom of stack)
somefunction - middle of stack
some function exits:
main (bottom of stack)
and someotherfunction is called:
main (bottom of stack)
someotherfunction - middle of stack
since someotherfunction calls somefunction which calls somethirdfunction, the call stack will eventually look like this when in somethirdfunction here:
main (bottom of stack)
someotherfunction - second member of stack
somefunction - third member
somethirdfunction -top of stack
and this whole time the "automatic variables" and their values are remembered in the function info. This includes arguments to the function (like in trigger_anything) and other variables declared at the top of each function. and you can have a function call itself too, and have itself in it's own call stack eventually, as in recursive cases like this.
in this case, the stack would be more like, if you have 8 elements:
trigger_anything
split off first 4 elements
trigger_anything
split off first 2 elements
trigger_anything
split off first element
output first element
split off second element
output second element
split off 3rd and 4th elements together (in 2nd trigger_anything)
trigger anything
split off 3rd argument
output 3rd argument
split off 4th
output 4th
split off last 4 elements (from 1st trigger_anything)
and repeat the exact same thing with the last 4
wikipedia has a good page on it https://en.wikipedia.org/wiki/Stack_(abstract_data_type)
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
0.41.4 doesn't load all of its extensions?
Hi,
i'm having several problems with the externals i'm trying to use.
First of all, I'm trying to add an external to print "hello world" on the screen. I copied the source from the "my first external tutorial" and everything compiled correctly. I added the ~.pd_linux and the ~.o on the /usr/lib/pd-extended/extra/helloworld directory.
In file->path... I put the /usr/lib/pd-extended/extra/helloworld. And in Startup... added external. My files are named external.pd_linux and external.o.
Once I have changed the path and startup settings the startup text box started showng the following messages:
[import] $Revision: 1.2 $
[import] is still in development, the interface could change!
compiled against Pd version 0.42.5
tried but couldn't sync A/D/A
libdir: can't load library
Gem: can't load library
cyclone: can't load library
zexy: can't load library
creb: can't load library
cxc: can't load library
iemlib: can't load library
list-abs: can't load library
mapping: can't load library
markex: can't load library
maxlib: can't load library
memento: can't load library
mjlib: can't load library
motex: can't load library
oscx: can't load library
pddp: can't load library
pdogg: can't load library
pixeltango: can't load library
pmpd: can't load library
rradical: can't load library
sigpack: can't load library
smlib: can't load library
toxy: can't load library
unauthorized: can't load library
pan: can't load library
hcs: can't load library
jmmmp: can't load library
ext13: can't load library
ggee: can't load library
flib: can't load library
ekext: can't load library
flatspace: can't load library
pdp: can't load library
pidip: can't load library
load_object: Symbol "external_setup" not found
external: can't load library
Does anyone know what I did wrong?
A last question. Once I got the library installed correctly, could I simply cal the method "helloworld_setup", on an pd object to print my message?
Thanks for helping!
Upgrade tangle
hello
I upgraded to Ubuntu 10.10 a couple of months ago and had some issues I need help in finding the best way to resolve.
I was using Pd 0.41-4extended and upgraded to Pd 0.42.5-extended when I upgraded Ubuntu
I noticed that the Pd .deb installed a '/usr/lib/pd-extended' directory instead of the old '/usr/lib/pd'
of course the Ubuntu upgrade wiped the '/' partition (I have '/' and '/home' on separate partitions) but everything was left intact on my '/home' partition so all my patches and work files were left untouched in '/home/user/pd-externals' dir
I made sure to backup of my old '/usr/lib/pd/' directory with all my externals and docs
but now when I launch Pd it throws errors saying it can't find my libraries:
cyclone: can't load library
zexy: can't load library
creb: can't load library
cxc: can't load library
list-abs: can't load library
mapping: can't load library
markex: can't load library
maxlib: can't load library
memento: can't load library
mjlib: can't load library
motex: can't load library
oscx: can't load library
pddp: can't load library
pdogg: can't load library
pixeltango: can't load library
pmpd: can't load library
rradical: can't load library
sigpack: can't load library
smlib: can't load library
toxy: can't load library
iemlib: can't load library
unauthorized: can't load library
pan: can't load library
hcs: can't load library
jmmmp: can't load library
ext13: can't load library
ggee: can't load library
flib: can't load library
ekext: can't load library
flatspace: can't load library
so my question is:
what is the best way to migrate all my old libraries, externals and docs?
has anyone else encountered this problem?
and if so, what is the easiest way to deal with this *other* than going in and copying everything over to '/usr/lib'pd-externals/docs/' and '/usr/lib'pd-externals/extras/' dirs?
is it as easy as just changing the paths to a new location?
thanks in advance,
kim