PD-linking-tutorial

From YoungMusic

Jump to: navigation, search

First things first. Let's set some limits...

  • I'm only explaining how to make externals in a windows environment. I like Linux a lot, but my soundcard is not supported so I do not use PD with Linux.
  • I use the Dev-C++ programming environment. I tried the borland compiler first, but it does not work unless you start by compiling the entire PD package with the borland compiler. But Dev-C++ and the MinGW compiler are free, so there you go...

Contents

step one: getting the software

If you don't have PD yet, I think you'd better install it first, play with a for a few months and come back later. If you DO have PD and you want to write your own externals, check first if you have the source code somewhere. Otherwise you'll have to get it from the [PD website.

Dev-C++ can be downloaded from the bloodshed website. If you aren't using it yet, take your time to get to know it and come back later.

step two: make a new project

Choose a new project
Choose a new project
You are gonna make a dll, but for simplicity just start with an empty project. You won't need all the windows stuff anyway. Make sure you select 'C Project', not 'C++ Project'. And don't forget to give your project a name.

If you did this correct, you'll end up with an empty project. No files are added so you might want to do that. Select File->New->Source File, and add it to your project when asked.

step three: the code

Now we need some basic code for the external. I largely copied this from the tutorial by Johannes m Zmölnig.

#include "m_pd.h"

static t_class *helloworld_class;

typedef struct _helloworld {
        t_object object;
} t_helloworld;

void helloworld_bang(t_helloworld *x) {
     post("Hello world !!");
} 

void *helloworld_new(void) {
     t_helloworld *x = (t_helloworld *)pd_new(helloworld_class);
     return (void *)x;
} 

__declspec(dllexport) void helloworld_setup(void) {
     helloworld_class = class_new(gensym("helloworld"),
                        (t_newmethod)helloworld_new,
                        0, sizeof(t_helloworld),
                        CLASS_DEFAULT, 0);
     class_addbang(helloworld_class, helloworld_bang);
}

The only thing that's different in my version is the line:

__declspec(dllexport) void helloworld_setup(void) {
Select dll as type.
Select dll as type.
You have to add the export definition because otherwise PD won't be able to find the function in your dll.

Save your file now. You could call it helloworld.c, for example.

Project options

Add pd.lib
Add pd.lib
Hold on! Don't compile your project yet. It won't work. First, there are some project options to be set. Open the options window and set the following:
  • In the General tab, select Win32 DLL as the program type.
  • In the Parameters tab, add the library c:/pd/bin/pd.lib to the Linker section. (Of course the path may vary according to your PD installation.)
  • In the Directories tab, there is a 'library Directories' tab. It should contain the path to the PD libraries. In my case it's C:\pd\lib.
  • Next tab is the 'Include Directories' tab. Add the path to the PD source code there. (Something like C:\pd\src?)

That's all. Now you are ready to build your project. The generated dll should be placed in a directory where PD can find it. I generally place them in the same directory where I saved my PD-patch. Then try to make an object with the name 'helloworld'. It should work. (The name is case-sensitive, though.)

Yvan Vander Sanden 20:38, 6 January 2007 (CET)

Setup directories for the compiler.
Setup directories for the compiler.

Alternate version

Update: after working a few months with externals, i tend to use the same template again and again to start from. Basicly it's the same thing as the helloworld example above, but i've changed some naming conventions and find the code much more readable that way.

Behold my template:

static t_class *cName;

typedef struct _Name {
  t_object object;
} typeName;


void nameBang(typeName *name) {
  post("this is a template object. Don't use it.");
} 

void *newName(void) {
     typeName *name = (typeName *)pd_new(cName);
     return (void *)name;
} 

__declspec(dllexport) void Name_setup(void) {
     cName = class_new(gensym("name"),
                       (t_newmethod)newName,
                       0, sizeof(typeName),
                       CLASS_DEFAULT, 0);
     class_addbang(cName, nameBang);
}

When I make a new external, I just change 'name' by the name I want. But watch out! There is 'name' and 'Name'. You should replace them with 'yourExternal' and YourExternal' or you'll get in trouble.

Yvan Vander Sanden 23:25, 1 May 2007 (CEST)

Personal tools