-
Notifications
You must be signed in to change notification settings - Fork 25
Micro Blog
Friday, May 15, 2009 by mhroth
This whole silliness about thread registration is a burden to programmers. Sorry about exposing it (via registerThread()
) yesterday, but at least there was a solution that worked. Based on feedback from Almer Thie (see his modular synth project here), I have removed the requirement to manually register threads. Because I don’t have the ability to test with multiple drivers, I am not entirely sure that the automatic thread registration works perfectly. I look forward to your feedback.
Thursday, May 14, 2009 by mhroth
Finally I figured out how to post javadocs. Find them here. They are also in the repository here. They aren’t complete, but it is a start and will hopefully provide you with a clearer overview of the package.
Thursday, May 14, 2009 by mhroth
The beginnings of a new version of JAsioHost
have been pushed today. See Tags for a more complete description. This release should make the library smaller and easier to understand. All known bugs have also been fixed. The ExampleHost
has been given a GUI allowing the easy selection and testing of registered ASIO drivers.
Tuesday, May 12, 2009 by mhroth
There is now an alpha release which designates the current state of things. As long as only one driver is ever loaded and only accessed from one thread, then everything works great ;-) A beta
release is imminent and will fix these issues, as well as introducing some refactorings designed to simplify the API and be conceptually easier to understand.
Friday, April 24, 2009 by mhroth
There is a known issue of loading and accessing the AsioDriver
from multiple threads. Several people have tried (as might be typically expected) to create a GUI for loading the driver (Thread 1), and then starting the driver in another thread (e.g., the audio thread, Thread 2). The second thread might then complain (i.e., crash) about the driver no longer being found. The reason for this is (this explanation may not be correct because I am fuzzy on how/if threads maintain separate memory spaces in native code) that there is a critical global variable in the native code (bad programming practice I know, but the issue is not a clear as it may seem) which seems to not be accessible to all threads. The workaround for this issue at the moment is simply to do all manipulations of the JAsioHost
library from the same thread. I will work on a most robust solution to this problem. Sorry about the pain in the ass.
Wednesday, April 22, 2009 by mhroth
Two methods, AsioChannelInfo.read(float[])
and AsioChannelInfo.write(float[])
, have been added in order to allow hosts to conveniently read from and write to buffers using float
arrays. The sample type of the channel is accounted for and the host does not need to take this into account. The methods were added because most hosts use float
as the internal sample representation. If you are using some other format, get a reference to the base ByteBuffer
and manipulate it directly.
Tuesday, April 21, 2009 by mhroth
All input ByteBuffer
are read-only buffers, as generated by ByteBuffer.asReadyOnlyBuffer()
. You shouldn’t be writing to an input buffer anyway. JAsioHost attempts to abstract the endian-ness of the buffer from the user by setting the byte order according to the sample type of the channel. However, as it turns out, calling asReadOnlyBuffer()
resets the ByteOrder
on the buffer to the default of ByteOrder.BIG_ENDIAN
. If the channel is actually little-endian, then this mismatch causes the inputs to sound like noise. The issue was resolved simply by creating the read-only buffer first, and then setting the byte order on it, instead of the other way around, which was being done originally.
Thanks to Steve Taylor of toot.org for identifying this issue.
Saturday, April 18, 2009 by mhroth
A number of updates were integrated yesterday, including:
- Add support for
systemTime
andsamplePosition
tobufferSwitch()
- Add support for
kAsioBufferSizeChange
toasioMessage()
in native code - Remove synchronization requirement from
bufferSwitch()
. Should allowopenControlPanel()
to open, while running, without preventingbufferSwitch()
from executing - Refactor
AsioChannelInfo
architecture such that objects referring to the same channel return consistent and current information - Get rid of sampleTypes native array in global variable
- Make
AsioDriverInfo
available throughAsioDriver
- Reduce
AsioChannelInfo.toString()
to one line
And what does this buy you? To quote a power user, “occasional glitches are gone.” Sounds like a win to me! ;-)
Currently there are issues with the input buffers. They don’t seem to properly report the input. “I’m on it!” Update: Inputs seem to work fine with ASIO4ALL, but maybe not with other drivers.
Wednesday, April 15, 2009 by mhroth
With many thanks to Steve Taylor of toot.org, ASIOOutputReady
has been integrated into bufferSwitch
, and now the M-Audio Delta ASIO driver is now working as well. There is still plenty of refactoring work to be done, as experience with the current API has shown. But strong progress is being made in supporting more drivers.
Tuesday, April 7, 2009 by mhroth
Here is a screenshot of the ASIO4ALL configuration panel which I use during development. Of course, your underlying audio hardware may be different and this could affect your performance. It may be necessary to play around with the settings in order to find those that work best for you. For the record, I develop on a current generation (unibody) MacBook, bootcamped to Windows XP, SP 3.
Monday, April 6, 2009 by mhroth
I have switched over to the use of NIO ByteBuffer. I wasn’t familiar with them before, and thus did not start with them. However, after stumbling across them in the JNI documentation (e.g., NewDirectByteBuffer
), I realised that I could use them to create a Java array from a native one, with the bonus of not having to copy between a Java temporary array and the native buffers. Furthermore, using ByteBuffer
allows for endian-ness to be abstracted. This allows them to be manipulated in Java without having to worry what the sample endian-ness is, or what the endian-ness of the native system is. Finally, ByteBuffers
can be written to “per sample”, or updated in bulk.
The upshot of all of this is that the AsioDriverListener.bufferSwtich()
has a new signature of void bufferSwitch(Set<AsioChannelInfo> activeChannels)
. The current buffer for each channel can then be retrieved with getByteBuffer()
, which has the current position already reset to zero. If desired, the ByteBuffer
can be viewed AsIntBuffer()
, for instance, allowing integers (i.e., samples represented as integers in 32 bits) to be written or read in bulk.
Friday, April 3, 2009 by mhroth
JAsioHost
is becoming more usable! It works wonderfully with ASIO4ALL, though I have yet to hear of it working with other ASIO drivers. I’m working on this with the help of beta testers. I am also happy to report that stability problems in the past have been mitigated and as long as the usage guidelines are followed, there is nothing to worry about.
Monday, March 30, 2009 by mhroth
Well! ASIO is working! All of my testing is done with ASIO4ALL v2.9 and I am shocked (no, really) to report that the minimum latency (64 samples @ 44100 samples per second) is possible! I was convinced that a lower latency than the Java Sound API would be possible (> 1024 samples, in my experience), but 64 samples seems none other than impressive, considering the JNI barrier! Granted, the test case only outputs a sine wave, but at 64 samples you have to be quick.
As always, get the latest versions of JAsioHost.jar
and jasiohost.dll
. There is an com.synthbot.jasiohost.ExampleHost
which loads the first driver reported by the system, and outputs a 440Hz sine wave for two seconds. While at the moment is it probably still necessary to understand the Java source in order to use the library, try it out! ASIO access from Java is a reality! (Remember, API changes are likely.)
Friday, March 27, 2009 by mhroth
The current state of the code is as follows. Much of the work has been already done (at least conceptually), except that there is one annoying problem. When running, ASIO drivers notify the host that new input and output buffers are available via a callback, running in a thread owned by the driver. This is all well and good, and it means that this native thread must interact with the JVM and call Java methods. For whatever reason this doesn’t seem to be working at the moment (i.e., it will crash your machine, not just the JVM), and I am in the process of debugging it. I thought that I had solved the problem when I switched from AttachCurrentThread
(which was blocking) to AttachCurrentThreadAsDaemon
, which seems to work fine. But even though the latter function returns a seemingly valid JNIEnv *
, which which I can FindClass
or GetMethodID
, calling, for instance, CallStaticVoidMethod
has horrible effects. Maybe I am missing an exception somewhere…
Friday, March 27, 2009 by mhroth
A somewhat useful library is now available. There are no guarantees of how well it will work for you, and the API will probably change as well. As usual, you will need to place JAsioHost.jar
into your Java classpath. jasiohost.dll
should be placed in C:\WINDOWS\system32
, or any other location where Java can find it. After that you, can do one of several interesting things. import com.synthbot.JAsioHost
, which has only static methods.
-
List<String> getDriverNames()
returns a list of the names of all ASIO drivers registered with the system. -
String getCurrentDriverName()
returns the name of the currently loaded driver.A zero-length string is returns if no driver is loaded. -
int getCurrentDriverIndex()
returns the index in thegetDriverNames
List
corresponding to the currently loaded driver. Returns -1 if no driver is loaded. -
AsioDriver getAsioDriver(String name)
returns a loaded and instantiated AsioDriver object, representing the selected driver.
The last, and certainly not least, method is shutdownAndUnloadDriver()
. WARNING: No matter what you do, call this method before ending your program. If the JVM terminates (for whatever reason), and the driver is still loaded or running, you run a significant risk of enjoying a BSOD and possibly corrupted files. You have been warned.