Market size

ColinP
Posts: 939
Joined: Mon Aug 03, 2020 7:46 pm

Re: Market size

Post by ColinP »

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.
poetix
Posts: 54
Joined: Mon Nov 28, 2022 3:26 pm

Re: Market size

Post by poetix »

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...
London, UK
Developer, Vulpus Labs
Musician, w/trem
ColinP
Posts: 939
Joined: Mon Aug 03, 2020 7:46 pm

Re: Market size

Post by ColinP »

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.

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 )
}
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.
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: Market size

Post by UrbanCyborg »

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
Cyberwerks Heavy Industries -- viewforum.php?f=76
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: Market size

Post by UrbanCyborg »

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? :D 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
Cyberwerks Heavy Industries -- viewforum.php?f=76
User avatar
ChR_is
Posts: 106
Joined: Wed Sep 22, 2021 5:48 pm

Re: Market size

Post by ChR_is »

UrbanCyborg wrote: Wed Mar 08, 2023 8:34 pm ... for example, I wish there were a Java equivalent of CPPReference.com.
you mean like https://devdocs.io/openjdk~19/ or https://docs.oracle.com/en/java/javase/ ... index.html ?
poetix
Posts: 54
Joined: Mon Nov 28, 2022 3:26 pm

Re: Market size

Post by poetix »

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:

Code: Select all

double outputSample = inputJack.GetValue();
if (filterEnabled) {
  outputSample = filter.apply(outputSample);
}
outputJack.SetValue(outputSample);
Instead of this, I tend to have something like:

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());
}
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...
London, UK
Developer, Vulpus Labs
Musician, w/trem
UrbanCyborg
Posts: 588
Joined: Mon Nov 15, 2021 9:23 pm

Re: Market size

Post by UrbanCyborg »

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
Cyberwerks Heavy Industries -- viewforum.php?f=76
ColinP
Posts: 939
Joined: Mon Aug 03, 2020 7:46 pm

Re: Market size

Post by ColinP »

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.
If you need to get an index from an enum use .ordinal(), similarly to move from an index to an enum use .values().

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.
ColinP
Posts: 939
Joined: Mon Aug 03, 2020 7:46 pm

Re: Market size

Post by ColinP »

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'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.

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?
Post Reply

Return to “Module Designer”