Market size
Re: Market size
I'm one of the few, possibly even the only third party developer who is doing this full-time. That's not to say it didn't start as a hobby and like virtually everyone else I wanted to create modules that I desired myself. Unfortunately the kind of modules I wanted required enormous amounts of development time so I kind of got sucked into a black hole.
The financial rewards are meagre but still useful. I spend two half days a week doing other work but hope eventually to be able to earn just enough from Adroit to drop that. I'm an old hippy living completely off grid so my living costs are low. I'm also getting more and more efficient at VM development so instead of projects like LSSP and GS taking nine months each, in the future the time investment will gradually become easier to manage. As an aside one fabulous thing I've discovered in recent months is that in Java enums are a class and fully exploiting this has pretty much doubled my productivity. Not something that would impact simple modules but in large scale complex ones it massively simplifies all kinds of things.
On marketing it's really an art rather than a science. I spent about £600 total on exhibiting at Synthfest and probably haven't yet recouped that in extra sales but I'm taking a long view trying to establish Adroit as a recognisable brand.
Having a website is useful too. I get about 1,000 unique visitors per month and about 10% spend more than an hour browsing. That doesn't all convert into sales but developing people's interest is important. Especially when working in the fairly esoteric field that I'm ploughing.
The financial rewards are meagre but still useful. I spend two half days a week doing other work but hope eventually to be able to earn just enough from Adroit to drop that. I'm an old hippy living completely off grid so my living costs are low. I'm also getting more and more efficient at VM development so instead of projects like LSSP and GS taking nine months each, in the future the time investment will gradually become easier to manage. As an aside one fabulous thing I've discovered in recent months is that in Java enums are a class and fully exploiting this has pretty much doubled my productivity. Not something that would impact simple modules but in large scale complex ones it massively simplifies all kinds of things.
On marketing it's really an art rather than a science. I spent about £600 total on exhibiting at Synthfest and probably haven't yet recouped that in extra sales but I'm taking a long view trying to establish Adroit as a recognisable brand.
Having a website is useful too. I get about 1,000 unique visitors per month and about 10% spend more than an hour browsing. That doesn't all convert into sales but developing people's interest is important. Especially when working in the fairly esoteric field that I'm ploughing.
Re: Market size
Very curious now to know how the class-nature of enums specifically helps. I'm guessing you could for example make an enum implement an interface which takes a pair of doubles representing frequency and Q and returns the coefficients of a filter, then have LP / HP / BP / HIGH_SHELF etc as enum values - useful for binding filter selection from a drop-down to the behaviour of the filter circuit...
Re: Market size
The main benefit of enum being a class is that one can collect all the functionality related to the enum in one place rather than it being dispersed over thousands of lines of hard to scan code in other classes.
An important related subject is the use of EnumMap but we are already going way off topic!
Here's a very redacted copy of the Range enum class from my upcoming N-Step project, it should give you some insight.
Unfortunately the tabs are messed up by the forum sw but in my editor it's all neat and tidy.
The getLabels() method returns the string array required by VM's pop-up menu and I wanted dividers between sections so that's why there are mysterious {sep} values.
An important related subject is the use of EnumMap but we are already going way off topic!
Here's a very redacted copy of the Range enum class from my upcoming N-Step project, it should give you some insight.
Unfortunately the tabs are messed up by the forum sw but in my editor it's all neat and tidy.
Code: Select all
package nstep;
import adroit.SPoly;
import nstep.QType;
public enum Range
{
ONE_OCTAVE( "1 OCTAVE", 0, 1, QType.REGULAR_Q ),
TWO_OCTAVES( "2 OCTAVES", 0, 2, QType.REGULAR_Q ),
THREE_OCTAVES( "3 OCTAVES", 0, 3, QType.REGULAR_Q ),
FOUR_OCTAVES( "4 OCTAVES", 0, 4, QType.REGULAR_Q ),
SEP1( "{sep}", 0, 1, QType.NO_Q ),
DYNAMIC_TUNING( "DYNAMIC TUNING", 0, 2, QType.DYNAMIC_TUNING_Q ),
SEP2( "{sep}", 0, 1, QType.NO_Q ),
ZERO_TO_ONE( "0 V TO 1 V", 0, 1, QType.NO_Q ),
ZERO_TO_TWO( "0 V TO 2 V", 0, 2, QType.NO_Q ),
ZERO_TO_FIVE( "0 V TO 5 V", 0, 5, QType.NO_Q ),
ZERO_TO_TEN( "0 V TO 10 V", 0, 10, QType.NO_Q ),
SEP3( "{sep}", 0, 1, QType.NO_Q ),
MINUS_ONE_TO_ONE( "-1 V TO 1 V", -1, 2, QType.NO_Q ),
MINUS_TWO_TO_TWO( "-2 V TO 2 V", -2, 4, QType.NO_Q ),
MINUS_FIVE_TO_FIVE( "-5 V TO 5 V", -5, 10, QType.NO_Q );
public String getLabel()
public QType getQType()
public double getScale()
public static final String[] getLabels()
public double transform( double x )
public double transformAndChromaticQuantize( double x )
public double transformAndPolyQuantize( double x, SPoly quantizeIn )
public double parseValue( String string )
}
-
- Posts: 625
- Joined: Mon Nov 15, 2021 9:23 pm
Re: Market size
That's very interesting, Colin. I barely use Java enums, mainly because they don't work like C++ ones, so they don't do what I want, which is usually simple indexing. However, I'll have to do a bit of thinking about your example. I'm sure I can learn a lot from it. My basic problem has generally been a dearth of useful sources. Got to get some more involved books. It's quite a difference in level moving from Nico Josuttis' C++ texts to entry-level Java texts, like I've been doing. Similarly, I haven't been able to come up with online resources as good as the ones I know of for C++; for example, I wish there were a Java equivalent of CPPReference.com.
Thanks for sharing, Mate.
Reid
Thanks for sharing, Mate.
Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
-
- Posts: 625
- Joined: Mon Nov 15, 2021 9:23 pm
Re: Market size
I should also have mentioned that I'm one of the other devs who does this full time-ish, in that I'm retired and don't have anything else to take up my time and interest. But for me, yeah, it's basically a hobby. After a string of mostly fairly basic modules (I except Poly Permuter, Poly SideChain, and Poly VMeter from that; they were somewhat beastly to get right), I'm starting to expand into more DSP-oriented material. Spent the morning beating my head against some FIR messiness. But what's a hobby if it doesn't drive you insane? I could always dig out the hundred or so unbuilt model kits going back forty years and get insane over that, but that's not learning much new, or creating something that others might benefit from. Guess models and watercolors are my fallback resort.
Reid
Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
Re: Market size
you mean like https://devdocs.io/openjdk~19/ or https://docs.oracle.com/en/java/javase/ ... index.html ?UrbanCyborg wrote: ↑Wed Mar 08, 2023 8:34 pm ... for example, I wish there were a Java equivalent of CPPReference.com.
Re: Market size
I kind of want to do a "Java for C++ developers" thread just guiding people towards the cool bits of the language and helping them over roadblocks, because it seems like a lot of people are in that boat - missing familiar capabilities, unfamiliar with cool stuff modern Java can do.
For example, lambdas / functional interfaces and method references are all over my code. Here's a simple use case. Suppose you have a toggle switch that controls whether or not a filter is applied to an output. One way to do this is with a boolean condition in ProcessSample:
Instead of this, I tend to have something like:
It eliminates the conditional in the ProcessSample loop, and allows me to configure behaviour in response to UI events. In a trivial example like the above that doesn't buy you much, but when there are multiple variations of possible behaviour in play, being able to define an object that captures the behaviour you want, then apply that behaviour directly to an input stream, becomes very powerful (and can save a lot of convoluted nested if-else logic). As programs get more complex, being able to represent behaviour with objects rather than with logic controlled by a bunch of boolean conditions becomes an increasingly helpful abstraction.
I'm going to open up the Vulpus Labs library repo a bit later on. It's a bit of a jumble of bits and pieces, without documentation or tests, but maybe it will be useful to someone...
For example, lambdas / functional interfaces and method references are all over my code. Here's a simple use case. Suppose you have a toggle switch that controls whether or not a filter is applied to an output. One way to do this is with a boolean condition in ProcessSample:
Code: Select all
double outputSample = inputJack.GetValue();
if (filterEnabled) {
outputSample = filter.apply(outputSample);
}
outputJack.SetValue(outputSample);
Code: Select all
private static final DoubleTransformer ID = (x) -> x;
private DoubleTransformer filterBehaviour = ID;
public onFilterEnabledChanged(boolean filterEnabled) {
filterBehaviour = filterEnabled ? filter::apply : ID;
}
public ProcessSample() {
outputJack.SetValue(filterBehaviour.apply(inputJack.GetValue());
}
I'm going to open up the Vulpus Labs library repo a bit later on. It's a bit of a jumble of bits and pieces, without documentation or tests, but maybe it will be useful to someone...
-
- Posts: 625
- Joined: Mon Nov 15, 2021 9:23 pm
Re: Market size
Chris, those links aren't what I had in mind. I've been using them all along, but they're not much more than raw definitions (to be fair, so is CppReference.com, so it's not exactly the best resource site for me to have set up as the basis of comparison). There's a world of juicy C++ sites out there; most of the Java stuff I come across isn't in the same league.
Reid
Reid
Cyberwerks Heavy Industries -- viewforum.php?f=76
Re: Market size
If you need to get an index from an enum use .ordinal(), similarly to move from an index to an enum use .values().UrbanCyborg wrote: ↑Wed Mar 08, 2023 8:34 pmI barely use Java enums, mainly because they don't work like C++ ones, so they don't do what I want, which is usually simple indexing.
So in the Range example...
Range.THREE_OCTAVES.ordinal() produces 2
Range.values()[ 2 ] produces Range.THREE_OCTAVES
But most of the time you can stay in the abstract realm by using EnumMap. Then you can use .put() and .get() to access anything you like with the enum as the key. Java implements this using arrays so it's just as efficient as using indexing but it's much safer and nicer looking.
Re: Market size
I've not yet looked at Java lambdas but understand how powerful such concepts are and it's on my todo list. In the early days SMoCing in assembly was pretty routine in 8 bit games programming in order to get things running fast enough. Later on function pointers were popular.poetix wrote: ↑Wed Mar 08, 2023 11:23 pm ...when there are multiple variations of possible behaviour in play, being able to define an object that captures the behaviour you want, then apply that behaviour directly to an input stream, becomes very powerful (and can save a lot of convoluted nested if-else logic). As programs get more complex, being able to represent behaviour with objects rather than with logic controlled by a bunch of boolean conditions becomes an increasingly helpful abstraction.
I worked on an experimental language similar to Self that used prototypes rather than classes and I would love to be able to get at some of the techniques this made possible. I don't think it's feasible to do exactly the same thing in Java but one could dynamically change object behaviour to avoid logic. For instance an empty collection referenced a dedicated prototype that worked purely on empty collections, adding something to it changed the reference to a prototype that handled collections with one element, adding something again changed the prototype to one handling small collections, above a certain threshold the prototype would change to yet another dedicated to efficient handling of large collections. The same thing in reverse. This is just one example, the idea was generic. It eventually turned out to be to too powerful to be safe.
So I presume it's this sort of concept you are talking about but in the confines of a nice strongly-typed universe?