GithubHelp home page GithubHelp logo

cycling74 / min-api Goto Github PK

View Code? Open in Web Editor NEW
52.0 34.0 20.0 1.5 MB

High-level C++-language application programming interface for Max

License: MIT License

C++ 98.89% CMake 0.77% Ruby 0.19% C 0.07% Python 0.07%

min-api's People

Contributors

benbrackenc74 avatar benediktadams avatar hiddedejong avatar isabelgk avatar jonasohland avatar nwolek avatar omarcostahamido avatar robtherich avatar tap avatar timblechmann avatar x37v avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

min-api's Issues

Attributes call their setter methods before object is fully constructed

My test case for this involves the attribute disable function, but this is indicative of a wider problem when accessing any class member, which could cause a lot of pain for users.

    attribute<bool> disable_simple_integer { this, "disable_simple_integer", true,
        setter { MIN_FUNCTION {
            simple_integer.disable(args[0]);
            return { args[0] };
        }}
    };

    attribute<long> simple_integer { this, "simple_integer", 100};

The above code-block causes an error on object construction, because 'simple_integer' is not yet constructed when the setter function is called to set the default value of 'disable_simple_integer'. Obviously it's possible to put checks for this in, but this could end up with a lot of extra boilerplate in setter methods.

Additionally, these kind of errors can be quite hard to spot for inexperienced developers, and also can be introduced from working code merely by re-ordering members in the class definition.

Is it possible to delay the initialisation of attributes with their default value (via their setters) until after object construction?

refactor / review / rework wrapper functions

Currently it is cumbersome and overwhelming, and highly-repetitive and error-prone, to add/manage new method bindings/signatures to the magic robot code that wraps a Min class for Max.

Additionally the naming of the template classes is not descriptive and thus also the subject of occasional confusion or misunderstanding.

attribute readonly property has no effect

Setting the readonly property on an attribute has no effect, which makes sense as I can't find any implementation for it. I would add it myself but the 'object_attr_setdisabled' function is missing from the c74::max namespace.

Being able to add a block() method

It would be useful if, in addition to the one sample processing method, it was also possible to add an optional block method serving as a vector preprocessor, called just before the processing of a vector starts.

One example where this would be useful would be audio gain and matrix objects. If updated gain values are set as control messages rather than at audio rate, this would make it possible to smooth the transition to the new value over one vector in order to avoid audible clicks.

The JSFX API for developing Reaper plugins has this, and it is rather useful:

http://reaper.fm/sdk/js/js.php#js_intro

Here's an example of how this might be used in a stereo gain object:

// When a new gain value is requested, it updates the value of desiredGain.

/// Block (signal vector) preprocessing
void block()(void) {
    inc = (desiredGain - gain) / blocksize;
}

/// Process one sample
samples<2> operator()(sample input1, sample input2) {
    gain += inc;
    return {{ input1 * gain, input2 * gain }};
}

attributes: setting defaults needs to queued

Currently an attribute value is assigned when the attribute instance is created, on the stack, as the Min class is constructed. There are several tricky consequences:

  • Attribute setters are executed prior to the constructor
  • Attribute setters are executed prior to other attributes (upon which there may be a dependency) reaching a point of sanity
  • The max class itself is not fully constructed, the self-pointer assigned, etc.

Thus attribute defaults should not be assigned in the attribute ctor, but rather pushed onto a queue and then processed together later, e.g. just before attr_args_process()

Attributes: direct support for metadata

Currently one must create a "maxclass_setup" method as is done the xfade~ example in order to add metadata such as enum listings or labels.

As @robtherich has rightly pointed-out, we would benefit from specifying this stuff as arguments to the attribute initializer.

c74::max::post() not found

c74::max::cpost() works, but sometimes I really do want to post to the Max window. Am I missing something?

review casting usage

... and move toward best-practices in the code by using the more targeted and safe casting operators.

min::function consistency and cleanup

All constructors, attribute setters, methods, should use a consistent interface for passing data.

Some work has been on this front by @benbrackenc74 for ctors such that they receive args as const atoms& args = {}. This was previously partially tracked as Cycling74/min-devkit#33.

This new interface means that attributes will not be able to alter the values of their incoming arguments because they are now a const reference -- but that mechanism was also kind of an ugly hack. A better interface is to return the value from the function as it is supposed to be used.

Cleaning up the attribute interface for setters highlights additional looming concerns with the existing ATTRIBUTE macro:

  • it is a macro, and thus not namespaced and susceptible to various problems
  • it then requires the END macro which has the same problems but potentially even more prone to collision
  • with the above changes now all attribute setters must return values, even if the setter doesn't do anything
  • because it is a macro, and the structure of the macro is such that it hides the details of the lambda, it is impossible to offer a version that omits an unneeded setter without creating additional macros
  • the current structure does not provide a means by which to implement a getter functions as documented in Cycling74/min-devkit#28.

Thus this work will embody refining the attribute interface in such a way as to address these design problems.

index enum support

In other words an enum attribute where the values are represented as integral constants but the names are exposed to Max symbolically.

The @darwingrosse arpeggiator has immediate use for this feature.

Currently symbol attrs can define a range of symbols. We could do a similar treatment for int attrs if they received a range of symbols. what would this imply?

  • Need a mapping between symbols and ints
  • Not as strongly typed as desired

Have done experiments previously where the enum values are hashed from the symbol (e.g. in Jamoma2). The value don't count sequentially up from zero as is the traditional Max idiom -- the symbol is also not gettable (e.g. reverse-lookup). The compile-time optimization of the hash in Jamoma2 is also potentially not going to buy us anything in Max where everything is determined at runtime anyway. Thus an unordered_map might make the most sense for the internal representation.

Linker symbol collision when multiple sources include the Min headers

Min is designed as a header-only library.
http://stackoverflow.com/questions/12290639/quantifiable-metrics-benchmarks-on-the-usage-of-header-only-c-libraries

It works great when it is included in * a * source file. But I’ve had a nagging feeling that if it were included in more than one source file that there would be a problem because if there is a symbol defined in one source file (via a header include) and also defined in another source file (via a header include) then you have a the linker symbol conflict situation.

@robtherich experienced precisely this in Cycling74/jit.mo#21 .

There should be a way around this. Perhaps simply with more careful or controlled including of headers. Boost for example is mostly header-only and doesn’t have this problem as far as I know.

rename method --> message

thus avoiding ambiguity and conflicts between what is currently the max::method and the very different min::method when both namespaces are being used.

Matrix Operator additions

Specifically as it relates to the arbitrary cell access. These could also be useful for generating equations based on matrix coords
cell() - gives the current cell coordinates {x,y}
norm() - gives normalized cell coordinates {x/dim.x, y/dim.y}
snorm() - gives signed normalized cell coordinate {2x/dim.x-1,2y/dim.y-1}
dim() - gives the dimensions of the input matrix. Don't really know if necessary, since it's already covered by .width(), .height()

sample(x,y,…) - currently named "in_cell" returns the value of the input cell at given coordinates. In gen, this is linear-interpolated if a subpixel coord is given, but I don't think that's necessary to implement for this. In Gen, it also takes a normalized float coordinate as input, with is a major PITA for neighbor-cell lookups.

I don't think we need to be too beholden to gen conventions, but I could see where someone might be jumping from jit.gen to min-sdk

CI / Unit-Testing Configuration

Currently all of our CI and Unit Testing is configured for the Min-DevKit.
The result is that to evaluate changes one has to run tests etc. in the DevKit instead of in the API.

Proposed Solution: have the CI do a clone of the DevKit and run the unit tests on that.

Mock clock class crashes unit test on CI

To reproduce: enable the code in the min.beat.random unit test, it does not crash for me on my local machine (neither in Debug nor Release configs) but it does crash claiming an exception from a bad arg to a mutex.

At a minimum we should try to catch the exception.

qelem interface

currently forced to use old-school max::qelem...
need a wrapper class like we do with clocks/timers

unit test for console posting

As mentioned in the conversation on pr #1 by @impsnldavid :

In terms of unit testing I could create a separate class which forwards the messages to a different destination. Not sure about regression testing unless there's a way to programmatically get the contents of the Max window?

We cannot trap non-error messages to the Max window, so I personally would not worry about that for the initial testing.

Can we indicate to objects if they are being 'dummy' constructed?

In the case of objects which immediately attempt to make a connection with hardware, being constructed and then immediately destroyed could cause issues. Could we provide some flag that can be tested in the object constructor to determine if this is a 'dummy' construction (just for the purposes of wrapping the object)?

doc gen: refpage summaries cut off after periods

When looking at the generated refpages, the dataview listing of attrs and messages will show a shortened version of the description that cuts off after the first period. This causes trouble when displaying float values in a description, like:
"Function frequency (default = 1.0)."
becomes
"Function frequency (default = 1"

It would be good to know the appropriate workaround, or if this is just a bug in the doc gen. Feature?

console post refinements

In a conversation with @darwingrosse this week stemming from #3 it became obvious that there is room for some further enhancement of the stream-based post() mechanism.

While the post() mechanism that @impsnldavid created is far superior to the old c74::max::object_post(), it would be even better if the syntax was more familiar looking to what is found e.g. in books for people new to C++, since Max is a gateway to learning programming for many people.

Thus it would be nice if the syntax could be cout << "yay" << endl or cerr << "fooey" << endl.

The way post() current works is that it prints when the logger is freed by going out of scope. The Max window can only print one line at a time, so perhaps we could change that such that it prints when receiving << endl and then the logger would become persistent.

If you really want to post to the OS console instead of the Max console then you can still explicitly do that by using std::cout << ....

Way to 'fail' object construction

In the Max C API you could indicate object construction failure by returning null from the new instance method. This was useful in situations where an object needs to load resources at runtime (e.g. access to specific hardware) which can potentially fail.

Is there an equivalent in the Min API, perhaps by throwing an exception during the constructor?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.