Skip to content

fdch/pddb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PDDB - Pure Data Data Base Specification

pddb is a JSON database that parses the Pure Data source code to get data about the internal objects. It is useful in the context of the pdpy project, with possible other uses like autocomplete, error check when typing, etc. In the following text there is a brief description of the JSON data structure.

Live querying

Simply run make start, start typing your queries. You should see a message like this on your Terminal:

Starting live database...
Type your queries, eg: osc~, and hit RETURN to get the result.
Type QUIT and hit RETURN to quit.
Starting server...
Starting client...
Listening on 127.0.0.1:9226
Connected by ('127.0.0.1', 61874)

For example, when typing osc~ and hitting return, this is the result:

osc~
Received: [True, namespace(inlets=2, outlets=1), 1]

Which means that osc~

  • is an object --> True
  • has 2 inlets and 1 outlet --> namespace(inlets=2, outlets=1))
  • takes 1 optional creation argument --> 1

Grab the database

Simply run wget https://raw.githubusercontent.com/fdch/pddb/main/pddb.json

Make the database

  1. Clone or download the Pure Data distribution
  2. Clone or download this repository.
  3. Run the following:
cd pddb
make PDDIR=/path/to/pure-data

Where /path/to/pure-data is the path to your Pure Data distribution. Mine looks like ~/Development/pure-data, which is the default.

Goals

The purpose of this database is to better understand the internal structure of the Pure Data source code, and to enable language checks for the pdpy project. PRs are welcome.

Loading PDDB with python

You can load pddb.json as a json object like this:

import json
with open('pddpy.json') as f:
  data = json.load(f)

print(data)

NOTE: the data variable will be used in the python examples that follow.

JSON data structure

This database is an Array of Objects, meaning that:

  1. A single Array encloses the entire database.
  2. Every element contains exactly one Entry Object.

Entry Object

Each entry Object has two keys named file and classes. The structure looks like this:

[
 {
   "file" : '',
   "classes" : []
 }, ...
]

file

>>> data[0]['file']
'/path/to/pure-data/extra/pique/pique.c'

This key contains exactly one String with the path to the Pure Data .c file from which the data of that specific entry was obtained.

In python, you can extract all file keys like this:

>>> [entry['file'] for entry in data]
['/path/to/pure-data/extra/pique/pique.c', ... ****]

classes

>>> data[0]['classes']
[{'className': 'pique', 'attributes': {'patchable': False, 'newmethod': 'pique_new', 'arguments': {'name': 'pique', 'args': ['A_DEFFLOAT']}, 'methods': ['list', {'name': 'errthresh', 'args': ['A_FLOAT']}], 'description': {'kind': 'data', 'subkind': 'array'}, 'iolets': {'outlets': 1}}}]

This key contains an Array of Class Objects that describe the Pure Data classes found in the file path to which file points. In this classes key you will find most of the data.

Class Object

Each class Object has two keys: className and attributes.

[
 {
   "file": "",
   "classes": [
       {
           "className": "",
           "attributes": {} | []
       }, ...
 }, ...
]

className

>>> data[0]['classes'][0]['className']
'pique'

This key has exactly one String with the name by which this specific class is refered to internally in the source code.

attributes

>>> data[0]['classes'][0]['attributes']
{'patchable': False, 'newmethod': 'pique_new', 'arguments': {'name': 'pique', 'args': ['A_DEFFLOAT']}, 'methods': ['list', {'name': 'errthresh', 'args': ['A_FLOAT']}], 'description': {'kind': 'data', 'subkind': 'array'}, 'iolets': {'outlets': 1}}

This key can hold either one or multiple Attribute Objects. Therefore, it can be either an Object or an Array of Objects and needs to be parsed accordingly.

Attribute Object

This Object contains variable keys depending on the Pure Data class it describes. The possible keys are:

Key Type Description
patchable bool Describes if object has inlets or not.
newmethod String The method by which the class is instantiated as a new object.
arguments `Object String`
methods `String Object
description Object Describes the object with kind and a subkind keys. See Description Object.
iolets Object Describes the objects inlets and outlets. See iolet Object.
signal bool Describes if object processes audio or not.
alias String This contains an alias string that can be used to create the object when patching.
help String This contains the help file identifier when multiple objects are grouped into the same help file.

arguments

>>> data[0]['classes'][0]['attributes']['arguments']
{'name': 'pique', 'args': ['A_DEFFLOAT']}

This key can either be a String or an argument Object (See Argument Object)

arguments Sring

>>> data[3]['classes'][0]['attributes']['arguments']
'loop~'

If arguments is a String, this means that the Pure Data object does not take any arguments except the creation argument. So, the String represents the argument needed to create the object when patching.

argument Object

>>> data[23]['classes'][0]['attributes']['arguments']
{'name': 'delay', 'args': ['A_DEFFLOAT', 'A_DEFFLOAT', 'A_DEFSYM']}

If arguments is an Object, then the Pure Data object takes arguments besides its creation argument.

The argument Object contains a name and an args keys, for example:

"arguments": {
    "name": "moses",
    "args": [
        "A_DEFFLOAT"
    ]
}

argument["name"]

If the argument Object is within the arguments key, then the name key points to the creation argument (e.g., "moses" or "array define").

>>> data[0]['classes'][0]['attributes']['arguments']['name']
'pique'

However, it it is within the methods key, then the name key points to the "message" header.

For example, in the case of the netreceive object, the message header to set the internal port is "listen", and it takes a list as argument. This looks like this:

"name": "listen",
"args": [
    "A_GIMME"
]

argument["args"]

The args key contains an Array of argument types as defined in the Pure Data source code (e.g., "A_DEFFLOAT"). The list of possible argument types is:

Type Description
A_DEFFLOAT A float type argument that can either be present or the Pure Data object falls back to the argument's default value.
A_GIMME A list of arguments.
A_DEFSYM A symbol type argument that can either be present or the Pure Data object falls back to the argument's default value.
A_DEFSYMBOL Same as "A_DEFSYM"
A_FLOAT A float type argument that must be present.
A_SYMBOL A symbol type argument that must be present.

methods

This key describes the way to interface with the object via Pure Data "messages". The methods key can be either a String or an argument Object or an Array combining both.

If there is no methods key present, then the object takes no messages.

methods Array

This Array can hold a combination of String and argument Objects. This needs to be taken into account when parsing. Continue reading for each specification.

methods Sring

>>> data[26]['classes'][0]['attributes']['methods']
'list'

If methods is a String, this means that the Pure Data object takes only one message. So, the String represents the message that takes exactly one symbol, for example, the "bang" message. The above example is from the midiin object.

methods Object

>>> data[23]['classes'][0]['attributes']['methods']
['bang', 'stop', {'name': 'float', 'args': ['A_FLOAT']}, {'name': 'tempo', 'args': ['A_FLOAT', 'A_SYMBOL']}]

This Object describes the way to construct the message to interface with the Pure Data object. It is exactly like the arguments object. See Argument Object. The above example is from the delay object.

description Object

>>> data[26]['classes'][0]['attributes']['description']
{'kind': 'interface', 'subkind': 'midi'}

The description Object contains two keys, kind and subkind, each holding a String that attempts to classify the Pure Data object in the following way:

description["kind"]

These are the different kinds of Pure Data objects that this description performs:

data, signal, interface, parsing, control, operators
Kind Description
signal The object processes audio in DSP blocks
interface Objects that handle user interface actions
operators Control operators
data Handle various data structures
parsing Parsing functions
control Control flow
nonobj Non public objects
obsolete Objects marked as obsolete
extra None of the above kind

description["subkind"]

These are the different sub-kinds of Pure Data objects that this description performs:

array, analysis, midi, generators, block, list, system, time, gui, math, stream, other, text, struct, fourier, filters, canvas, format, network, control_to_sig, flow, delays, comparison, binary, keyboard, route, types

signal

signal Description
math Performs mathematical functions on the audio block.
fourier Performs the Fast Fourier Transform on the audio block.
filters Filters the audio signal block.
flow Signal object inlets and outlets.
delays Delays a signal block.
route Signal routing.
generators Signal generators.
system Input/Output to disk or to audio interface.
control_to_sig Converts control to signal.
array Interface signals with tables and arrays.
block Interface to change the DSP block.
analysis Analyze the signal block.

interface

interface Description
midi Handle MIDI input and output
keyboard Handle Keyboard events
system Handle System events
gui Graphical User Interface objects

operators

operators Description
math Mathematical operators
binary Binary operators
comparison Comparison perators

data

data Description
array Tables and Arrays
struct Data Structures
text Text objects
canvas Subpatches
other None of the above

parsing

parsing Description
list Parse list elements
stream Parse an incoming stream
forma Format parsing

control

control Description
flow Inlets and Outlets
network Network objects
math Mathematical operations
time Delay and time operations
generators Control flow Generators
types Type casting

iolets Object

>>> data[35]['classes'][0]['attributes']['iolets']
{'inlets': 2, 'outlets': 1}

The iolets Object contains two keys, inlets and outlets, each holding a Number that describes how many inlet and outlet the Pure Data object box has. The above example is from the hip~ object.

Example

This is an example of the x_misc.c entry. The only class that is shown is the random class, the rest are omitted:

[
 {
   "file": "/Users/fd/Development/pure-data/src/x_misc.c",
        "classes": [
            {
                "className": "random",
                "attributes": {
                    "patchable": true,
                    "newmethod": "random_new",
                    "arguments": {
                        "name": "random",
                        "args": [
                            "A_DEFFLOAT"
                        ]
                    },
                    "methods": "bang",
                    "description": {
                        "kind": "control",
                        "subkind": "generators"
                    },
                    "iolets": {
                        "inlets": 2,
                        "outlets": 1
                    }
                }
            }, ...
 }, ...
]

Limitations

The "random" className is located in the x_misc.c file. The Pure Data object is created with the "random" symbol and an optional float (A_DEFFLOAT). It has a single method that is represented by the "bang" string, and it is described as a control object of the generators subkind. It has 2 inlets and 1 outlet.

While this is true, it is incomplete. From this description alone, we are missing information about the functionality of the object. For example, we cannot know what the object does. Other limitations come from the fact that the .c files are not loaded but parsed, and some object attributes may depend on creation arguments and other circumstances during instantiation. Accounting for these is still in the todo list.

You are of course welcome to help in any way. Please file an issue or make a PR!

Credits

Fede Camara Halac (fdch)

Pure Data by Miller Puckette.