Edit 26.4.2016: my problem already deviated quite a lot from my original post, so I altered the title and content in order to get some more attention.
So I am trying to build a Step Sequencer in the vein of a Roland TR 808. I got a simple, bare bones gui and a sequencer engine based on javax.sound.sampled that loads a few genuine samples. You can then dynamically create a 16x16 (or precisely 12x16 as of now) pattern and vary the tempo. However, after experimenting around I have found several issues:
-It's a resource hog. I assume that has to do with the ExecutorService that runs a method with a while(true) loop (sort of). But that is a low priority.
-the timing is shaky. Every eight year old can play a tighter four-to-the-floor on his very first drum lesson than that sequencer.
-Biggest issue: If one sample is supposed to be played in quick succession, it is likely that some steps might get dropped. Let's say I have the Cowbell sample on step 7 and 11 and the tempo is 120 BPM, often only on step 7 the cowbell rings and on step 11 it stays silent. However sometimes I do get two cowbells per measure, and the probability of every sample being played increases with lower tempo. Also, shorter samples (rimshot) are more likely to work in short succession than long ones (Long Bassdrum).
I tried to utilize a mixer class (Although I honestly don't know what I was doing there. I think the official tutorial is rather poor when it comes to mixers).
I created a Mixer object in the sequencer and passed it to all Instrument instances. In Instrument class, instead of calling
clip = (Clip) AudioSystem.getLine(info);
clip = (Clip) mixer.getLine(info);
and tried all mixers that my PC offers. Only two actually worked, and there was no difference at all to my previous attempts. Also, both don't support synchronisation. So I scrapped the mixer idea.
So basically I think the problem lies in the instrument.play() method. If the clip is still currently running from a previous call, it seems to me like it is impossible to reliably stop it and restart it again immediately. If you know how to handle these issues, I'd greatly appreciate your help. Thank you!
Here's the code in question:
And the Instrument class:
/////////////////////// Old Post ////////////////////////////
I am currently teaching myself Java with the O'Reilly book "Head First Java", which also directed me to this place.It is a great book with fun projects and it inspires me to experiment further.
There is this cool beatbox program in chapter 13, where you control a midi sequencer that is apparently an official java component.
What I'm trying now is to instead of using the windows-builtin sounds, I want to play .aif samples from an 808. Great, I thought, so instead of using the javax.sound.midi sequencer I simply import the javax.sound.sampling sequencer.
Then I looked at the API.
I might have been a bit naive when thinking that I could use a filename instead of an instrument number when creating a sequencer event. But right now I'm overwhelmed by the documentation and have no Idea if it is even possible to use the sequencer for actual samples.
Then I made a feeble attempt to write a sequencer on my own but was confronted with the fact that I have no clue about how I could start my sequencer 'in the background'. I guess to achieve that, I'd need to make use of threads but that topic is a bit advanced for now.
So I would really appreciate if you gave me a hint about how to make a java sequencer play samples. Or whatever the next best thing would be, if that's not possible/feasible.
Welcome to the Ranch
Never use == true and == false. Not only are they poor style, but they are also error‑prone; if you write = for == you can get two errors for the price of one.
while (b == true) ...
while (b) ...
while (b == false) ...
while (!b) ...
I know nothing about sounds, I am afraid. I thought somebody had a similar problem a few weeks ago, but I can't seem to find it. Maybe someone else will hve more luck with a search.
posted 3 years ago
That makes sense, I changed those checks in my code.
I slightly modified my play() method:
At first all seemed to work. But then I swapped out my short clap sample for one with a rather long reverb (~700kb wav, 3-4 sec long).
Now the 2nd clap is always ignored, no matter the tempo.
Also, after the first time the clap is played, every call of play() afterwards doesn't play the sample from the beginning but somewhere in the middle.