<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Atsushi Eno</title>
    <description>The latest articles on DEV Community by Atsushi Eno (@atsushieno).</description>
    <link>https://dev.to/atsushieno</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F41382%2F87cbf8e7-d204-49a7-bced-1a1862ffd4a4.jpeg</url>
      <title>DEV Community: Atsushi Eno</title>
      <link>https://dev.to/atsushieno</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/atsushieno"/>
    <language>en</language>
    <item>
      <title>moving</title>
      <dc:creator>Atsushi Eno</dc:creator>
      <pubDate>Sun, 10 Mar 2019 10:08:42 +0000</pubDate>
      <link>https://dev.to/atsushieno/moving-4on9</link>
      <guid>https://dev.to/atsushieno/moving-4on9</guid>
      <description>&lt;p&gt;I need easy and kind-of-safe options to store and embed images on the posts. Therefore I'm moving the blog to &lt;a href="https://atsushieno.github.io/"&gt;https://atsushieno.github.io/&lt;/a&gt; . I'm using jekyll + prose there and prose is far from an ideal solution especially wrt images, but I can kind of hack around it. So far, newer posts will appear there, unless I dump the new solution away (I'm still kind of indeccisive yet).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>ADC2018, SOUL and APLs</title>
      <dc:creator>Atsushi Eno</dc:creator>
      <pubDate>Thu, 22 Nov 2018 11:50:52 +0000</pubDate>
      <link>https://dev.to/atsushieno/adc2018-soul-and-apls-18ob</link>
      <guid>https://dev.to/atsushieno/adc2018-soul-and-apls-18ob</guid>
      <description>&lt;h2&gt;
  
  
  ADC2018
&lt;/h2&gt;

&lt;p&gt;When I kind of decided that I leave Xamarin development job and dive into audio development world in early summer, I had one thing to do in mind: join &lt;a href="https://juce.com/adc/" rel="noopener noreferrer"&gt;Audio Developers Conference (ADC) 2018&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The two days conference (three days if training day is counted) is over, and I was quite happy there. There was an announcement about a new language called SOUL, the SOUnd Language. You can find the session recording on Youtube.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/UHK1QQM0bnE?t=910" rel="noopener noreferrer"&gt;https://youtu.be/UHK1QQM0bnE?t=910&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These days I had been checking various music and audio related software libraries and tools to write many blog entries for my experimental &lt;a href="https://adventar.org/calendars/3353" rel="noopener noreferrer"&gt;audio tech/library/tools Advent Calendar&lt;/a&gt; in Japanese, and  reading a handful of text about this kind of stuff for it. I think I understand how awesome this SOUL stuff &lt;em&gt;could&lt;/em&gt; be (as a skeptical developer I would keep saying that it was still just an announcement) and thought I should describe why. It is partly translated from what I have prepared in Japanese, even before ADC had started.&lt;/p&gt;

&lt;p&gt;I have to say, I have never been familiar with audio development. I joined ADC2018, while I didn't know that it is actually mostly about JUCE. I kept telling friends like "I will be joining ADC to possibly find a next job there", but I was not sure what it is like. I was not even serious about joining it ("I would join it, but I'd quickly give up if something more fun thing happens" kind of). There are things that are likely obvious to those audio devs attending there and yet I didn't know. I am never a dedicated C++ programmer. But ADC was still fun, I learned a lot of things.&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what is APL like?
&lt;/h2&gt;

&lt;p&gt;SOUL is meant to be a new &lt;a href="https://en.wikipedia.org/wiki/List_of_audio_programming_languages" rel="noopener noreferrer"&gt;APL（audio programming language）&lt;/a&gt; and further, platform. APLs are languages, not just a single language (and here it does not mean "A Programming Language"). Take it like VPLs-alike (visual programming languages).&lt;/p&gt;

&lt;p&gt;They designed to process audio and compose (or more precisely, "create" ?) music or realize sound effects. Ideally, they are designed for non-programmers (or maybe "not very advanced" programmers).&lt;/p&gt;

&lt;p&gt;They are actually language-based tools rather than language specifications. Examples of APLs are: Csound, ChucK, Pure Data, Alda, Faust, Tidal. What is interesting there is, they always define their own languages. Actually some of those languages are simply based on Lisp or Scheme and it is argurable that they are under their own "language", but let's skip that so far, they ultimately end up with their own ecosystem.&lt;/p&gt;

&lt;p&gt;An interesting aspect of those languages is that they never make use of virtual machines like Java or .NET. Describing music or sound effects would be very useful especially in apps like games, and there are many apps or games written in Java or .NET. Why should we learn a completely different language? Can't they just be some audio libraries like raw-audio libs or raw-midi libs so that we can arbitrarily manipulate those sound objects...?&lt;/p&gt;

&lt;p&gt;However, those APL designers have reasons to do so. Interestingly some of those are described in academic papers. Among those papers I pick up an interesting one from Andrew Sorensen, regarding his language Extempore. It is described from very primitive level, examining every possibility to achieve minimal latency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://openresearch-repository.anu.edu.au/handle/1885/144603" rel="noopener noreferrer"&gt;https://openresearch-repository.anu.edu.au/handle/1885/144603&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Extempore is a language for "live coding" (he calls it a "cyber-physical" programming language). You can find it from this keynote recroding from OSCON 2014:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=yY1FSsUV-8c" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=yY1FSsUV-8c&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Audio processing use cases
&lt;/h2&gt;

&lt;p&gt;Typical jobs that APLs deal with are often about "realtime" processing of audio. What are such jobs for example?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Think about a virtual piano app. You press a key, and the app reacts it by sending out piano sound to audio output. If you pressed a key and it took one second, then you don't want to use it.&lt;/li&gt;
&lt;li&gt;MP3 players decode &lt;code&gt;*.mp3&lt;/code&gt; files and send the result to audio output. Time of decoding is usually shorter than raw PCM playtime, but if the output was flaky then it's useless.&lt;/li&gt;
&lt;li&gt;DAWs (digital audio workstations) are used to compose music in mutiple tracks. Depending on songs, it might have to send audio outputs as well as MIDI outputs in sync. If they are out of sync, the resulting music does not sound right.&lt;/li&gt;
&lt;li&gt;Think about live performance using digital instruments (like the OSCON keynote video), optionally with visuals synchronized. If the app freezes even very short time like less than 0.1 sec, it is still problematic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those tasks might not necessarily be "realtime" in the context discussed here, but those tasks are under tight requirement on "precise" processing time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Realtime requirement
&lt;/h2&gt;

&lt;p&gt;So, it seems precise processing time is important. But how precise they need to be? How "realtime" should they be? 1 second delay is obviously wrong. 100 milliseconds? 10? 1? ... It's not obvious to us anymore. Similar realtime-ness is required in 3D animation frame rates in VRs e.g. 60fps, 120fps... Audio is similarly constrained, it is said that if latency becomes like 20 milliseconds of delay then some people would notice.&lt;/p&gt;

&lt;p&gt;I should make one point clear; realtime processing is NOT about high-performance processing as in "most efficient performance". The requirement is: &lt;strong&gt;a recurring task must be always invoked and run within the expected time frame&lt;/strong&gt;. It is in a sense completely opposite of high-performance computing.&lt;/p&gt;

&lt;p&gt;In modern general computing environment, there are preemptive multitasking (processes and/or threads) that are managed by the operating system. The Sorensen paper discusses other possibilities (manually-cooperative multitasking) and they are real on some embedded environment, but for APLs it would be mostly preemptive world. (Devices like ROLI Blocks and Littlefoot compiler might be the other way.)&lt;/p&gt;

&lt;p&gt;In any case, what is important here is that such a realtime app needs to run on a raltime thread (or process) which needs to be supported by the OS. General threads don't have such guarantee that it must be invoked in "timely" manner.&lt;/p&gt;

&lt;p&gt;And virtual machines have further problems. Namely, garbage collectors "stop the world" (including app threads) to collect unused memory blocks, and JIT compilers compiles VM code to the actual machine code at run-time. They result in uncountable delays.&lt;/p&gt;

&lt;p&gt;Sorensen mentions SonicPi on Ruby, Gibber on JavaScript, Impromptu on Scheme, and Overtone on Clojure as examples.&lt;/p&gt;

&lt;p&gt;Therefore, languages like Extempore, avoids those problems by designing their own language to generate native code statically, and require explicit memory allocation. These days LLVM-IR is the common code generator solution to them. Probably Lisp/Scheme parsers were their frontend solution too, that's my guess.&lt;/p&gt;

&lt;p&gt;As of 2018 we, virtual machine based developers, would have some words on that premise (e.g. we have AOT solution), but let's put it aside. Today I'm more interested in what SOUL provides.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language runtime and sound server communication
&lt;/h2&gt;

&lt;p&gt;One interesting point that Sorensen made in that paper was that a full stack solution vs. half stack solution for an APL - it is still possible to write client-server system, and it can be either intra-process or inter-process. So, instead of implementing everything in one single language and framework, it is possible to use multiple languages and frameworks, implementing each interested parts and cooperate together.&lt;/p&gt;

&lt;p&gt;For intra-process design, there would be a realtime sound server implementation and client language bridge by FFI. According to the paper, ChucK, Impromptu, and Fluxus are based on them. For inter-process model, SuperCollider is an example. Extempore is based on inter-process model too, at this state (the paper says it's been inbetween those two models).&lt;/p&gt;

&lt;h2&gt;
  
  
  the Language Barriers
&lt;/h2&gt;

&lt;p&gt;Leaving Sorensen paper aside, I have been always interested in having some sound objects model that can be manipulated in C# and Mono. I had almost no interest in whatever .NET Windows people had created. Windows-only stuff will just die soon. I'm only interested in cross-platform solution.&lt;/p&gt;

&lt;p&gt;There are still some hackers who created portaudio bindings or rtaudio bindings. I have my own binding for libsoundio, but there are other people who did it too. There is Web Audio API in Javascript world, and at ADC2018 there was a session about bringing audio API into C++ Standards ("std::audio"). There is no such thing in .NET. They are years behind C++ or Web.&lt;/p&gt;

&lt;p&gt;Anyhow, the next step to raw audio, what I wanted was to have some common sound object models that those APLs could possibly share. Right now they are living around Babel tower, but some commonplace could help improve the situation towards cross-language solution.&lt;/p&gt;

&lt;p&gt;Then I can instantiate audio output tracks and play in timely manner, coordinating them all, just like DAWs do. I have my own MIDI player and even text macro compiler to generate MIDI files, so I had some foundation.&lt;/p&gt;

&lt;p&gt;I had some look at a couple of APLs, and I always end up to find no general music solution there. Their outputs are specific to some genres of music. It's not what I had seen back in 20th century in Japan - people use FM synthesizers and MIDI instruments for various kind of music, even with limited expressiveness.&lt;/p&gt;

&lt;p&gt;My understanding is that there can be unlikely good language. Instead there could be common sound platform among any new possible languages.&lt;/p&gt;

&lt;p&gt;Another concern I had was that I should probably write everything in C (or at least provide C API). My primary language was C# (although I'm practically free to choose any language now that I'm independent) and C# still has many developers, but if it has technical difficulty (like discussed above) then it is just a bad choice on technology.&lt;/p&gt;

&lt;p&gt;The client-server model on that Sorensen paper was then likely the next thing I could try i.e. design primitive sound object system and manipulate them privately via C#.&lt;/p&gt;

&lt;p&gt;To be honest, I don't really care much about audio latency. But I would mind if I were going to perform some sort of live coding, and that's still a possible future.&lt;/p&gt;

&lt;h2&gt;
  
  
  where SOUL takes place
&lt;/h2&gt;

&lt;p&gt;SOUL announcement just appeared when my idea is like that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2Fp4hsr7ea-Ru1M0FBf20Q-qKHutAzOQC-OXwdP6noTzqNrdBttNBl5ETdMvf0sp37PK4Zn9byb_1fhukXnMLnk1IuhkKEZZRyiW8wZDHuQ9dLYdXTWjQakZl5OIrwHIwlOFokgr6bE8tSYrFY8wTYhvf2_jOuE5puQJllDEumJi6NYc0-LlhXrPPVxBzuI8UROQA0btwMS0RDRCWBSrJZB3RSKHCiwkifbAc4ziZEBmiNNVbOU1DKSgDYWxXariCZ10GCqc9TKdvymEupdpkHCC8-47QNkS5skRXMI0oSWzQeioprOOo2TmnE1iD6L296lWGZiBUB5BpCljPCzcvv2QgX5v6qmvdwAW4otJ3yEtpZ1jG7JPWBTct-1xEso3MWQ0QEjze41CXYpGHR8bECcBnChjXLmLJIEQX9xnGw4L3l8VHYxwpsM5wga4O2hKqnjxwY1Yh9lPAsQ2SONT7a11MpQcc50mzUUidVx6RQxDuvYNznUCvz9rTnV2K2hr7HJb0acLq47OkYP0KACeNbvZTbg3o1s78pzywpPyiZ34Qa5m0RGFi3c1YfRWjRjXu53j7qzbWxOGvj6l52gbnBPz282bTaetlAjt1YiDJX3wIEl9qqxAAeVjB4n3FuIk7m4c-iwswC3Wm3MyGDvFO9MTR2DA%3Dw971-h491-no" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2Fp4hsr7ea-Ru1M0FBf20Q-qKHutAzOQC-OXwdP6noTzqNrdBttNBl5ETdMvf0sp37PK4Zn9byb_1fhukXnMLnk1IuhkKEZZRyiW8wZDHuQ9dLYdXTWjQakZl5OIrwHIwlOFokgr6bE8tSYrFY8wTYhvf2_jOuE5puQJllDEumJi6NYc0-LlhXrPPVxBzuI8UROQA0btwMS0RDRCWBSrJZB3RSKHCiwkifbAc4ziZEBmiNNVbOU1DKSgDYWxXariCZ10GCqc9TKdvymEupdpkHCC8-47QNkS5skRXMI0oSWzQeioprOOo2TmnE1iD6L296lWGZiBUB5BpCljPCzcvv2QgX5v6qmvdwAW4otJ3yEtpZ1jG7JPWBTct-1xEso3MWQ0QEjze41CXYpGHR8bECcBnChjXLmLJIEQX9xnGw4L3l8VHYxwpsM5wga4O2hKqnjxwY1Yh9lPAsQ2SONT7a11MpQcc50mzUUidVx6RQxDuvYNznUCvz9rTnV2K2hr7HJb0acLq47OkYP0KACeNbvZTbg3o1s78pzywpPyiZ34Qa5m0RGFi3c1YfRWjRjXu53j7qzbWxOGvj6l52gbnBPz282bTaetlAjt1YiDJX3wIEl9qqxAAeVjB4n3FuIk7m4c-iwswC3Wm3MyGDvFO9MTR2DA%3Dw971-h491-no" alt="soul-worst-case-scenario" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(I have no images storage so I put them on Google photos, that you have to navigate to them...)&lt;/p&gt;

&lt;p&gt;This is a screenshot from the video streaming. You can use any language to write a programm that manipulates SOUL API, which is likely something like OpenGL Shader. The SOUL language sources are compiled into some native code using LLVM IR and run by JIT.&lt;/p&gt;

&lt;p&gt;What's good there is that the sound platform itself does not give up audio latency. It actually aims to provide better solution, by providing chance for hardware-accelerated processing of the sound platform:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2F-wiCGiJanLo66PJ0R78nzCbACHiK1iCiQHc7jBMOp8nUMnxQMVUCIbTCTIJ9Tmgc3lOO9Bf6dpoYZY2XbqsluE77UqmdFpTDHssTH0FwjLmUN6c8DpKEqwstCK9QAM_l_IcJpEZLxCdaLYhJqsM29yS6W5Dbb9CUcx_qI6aoFGgZ6W0oQEe_eRW98C8ese6ZWrBdZw7mOQOOcNUlGb27vXvOWHABC1mAlQuLCvpntMHrhlrvzeYvlAYsx9kg-crlIp4_Z3g23xxTFeIAsvsKUrRnHemsYxAhG61gzBdwoyub6OlZSe6lJd2MgQgvO3nE9oahdNNtJ8uwXmOPHD4TJEOVbbi8SDQj0P7s6kANdzVhDdkn0nKjwva7kMDTLDQFYpcsZ48aZ7WDHS_C4N8eV1YyNGwUZyH3C5J4tkyBzZexX5NpRoI0diibcdcpEj81DRvm9wsomm5TtnOd3FDq91zUdRbZ5-VtomCYcG2RNSfKf5YTlIayjh_NZpGlEETOgSrfXFzxyNm11CjgK_QNOnPyxKe_cYMx9AtPxQhJTtdn_0ZN_uFyBj39Y2EiL1oRFsvaiwtivsllatDjLJ8xAoKU6ANkkhg0wsQ4CqP04JdpV_oY5HpEG_ReHR3q8HcnM7uAvO5REwxh6Cn9eE_ZI4VDBg%3Dw972-h490-no" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2F-wiCGiJanLo66PJ0R78nzCbACHiK1iCiQHc7jBMOp8nUMnxQMVUCIbTCTIJ9Tmgc3lOO9Bf6dpoYZY2XbqsluE77UqmdFpTDHssTH0FwjLmUN6c8DpKEqwstCK9QAM_l_IcJpEZLxCdaLYhJqsM29yS6W5Dbb9CUcx_qI6aoFGgZ6W0oQEe_eRW98C8ese6ZWrBdZw7mOQOOcNUlGb27vXvOWHABC1mAlQuLCvpntMHrhlrvzeYvlAYsx9kg-crlIp4_Z3g23xxTFeIAsvsKUrRnHemsYxAhG61gzBdwoyub6OlZSe6lJd2MgQgvO3nE9oahdNNtJ8uwXmOPHD4TJEOVbbi8SDQj0P7s6kANdzVhDdkn0nKjwva7kMDTLDQFYpcsZ48aZ7WDHS_C4N8eV1YyNGwUZyH3C5J4tkyBzZexX5NpRoI0diibcdcpEj81DRvm9wsomm5TtnOd3FDq91zUdRbZ5-VtomCYcG2RNSfKf5YTlIayjh_NZpGlEETOgSrfXFzxyNm11CjgK_QNOnPyxKe_cYMx9AtPxQhJTtdn_0ZN_uFyBj39Y2EiL1oRFsvaiwtivsllatDjLJ8xAoKU6ANkkhg0wsQ4CqP04JdpV_oY5HpEG_ReHR3q8HcnM7uAvO5REwxh6Cn9eE_ZI4VDBg%3Dw972-h490-no" alt="soul-hardware-accelerated-case-scenario" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hardware driver accelerated programs run on better (less) latency. (Of course there are some business opportunities that the SOUL language developers could aim at.)&lt;/p&gt;

&lt;p&gt;Yes, JIT is something that those APL designers worry about, so as I assume in theory. The solution here is similar to how shaders are compiled i.e. GPUs. GPUs are popular, but for this SOUL devices we would be mostly skeptical. That may or may not be a matter of time, I have no idea now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thoughts
&lt;/h2&gt;

&lt;p&gt;My concern on SOUL is mostly about compilation pipeline, especially on how instant the turnaround time would be. If generating piano sound from keypress is somewhat slow, then it may not be a solution.&lt;/p&gt;

&lt;p&gt;Extempore, as a live-coding ready language, compiles their XTLang sources into LLVM IR so that when it is invoked it is instantly executed. But it also involves compilation, which those language users would pre-compile on their editor. Compilation should still take some time, unless the language itself is not very expressive.&lt;/p&gt;

&lt;p&gt;SOUL itself is not likely highly expressive (it does not seeem to aim to be a universal language) so the client languages (for me maybe C#) have to generate fairly complicated code.&lt;/p&gt;

&lt;p&gt;But since there is no actual piece of code out yet, we'll see what happens. Even if it was just a vaporware (which I guess highly unlikely), it is still a great idea that could be accomplished by anyone so far.&lt;/p&gt;

</description>
      <category>audio</category>
      <category>soul</category>
      <category>apl</category>
    </item>
    <item>
      <title>Fluidsynth hack continued: Oboe driver</title>
      <dc:creator>Atsushi Eno</dc:creator>
      <pubDate>Thu, 15 Nov 2018 15:44:01 +0000</pubDate>
      <link>https://dev.to/atsushieno/fluidsynth-hack-continued-oboe-driver-10fg</link>
      <guid>https://dev.to/atsushieno/fluidsynth-hack-continued-oboe-driver-10fg</guid>
      <description>&lt;h2&gt;
  
  
  Updates since the last effort
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/atsushieno/fluidsynth-20x-for-android-4j6b"&gt;It was two weeks ago&lt;/a&gt; that I finally got a practically working fluidsynth port with OpenSLES driver support. It was after big restructuring on the build system (building glib is a complicated task, and my build setup was messed due to Android NDK evolution). And by the time I got back successful builds there is already a new "better" audio driver Oboe (which is modern and ready for low latency than before).&lt;/p&gt;

&lt;p&gt;And here you are, the Oboe driver is done: &lt;a href="https://github.com/FluidSynth/fluidsynth/pull/464" rel="noopener noreferrer"&gt;https://github.com/FluidSynth/fluidsynth/pull/464&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This post is a handful of followups on the new Oboe driver implementation. There were many traps that drugged me on the ground...&lt;/p&gt;

&lt;h2&gt;
  
  
  Mixing C++ and C
&lt;/h2&gt;

&lt;p&gt;If you are not familiar with CMake, like me, you'd find it problematic on finding the right way to not let CMake ignore c++ sources. You need &lt;code&gt;CXX&lt;/code&gt; in the &lt;code&gt;add_library&lt;/code&gt; function call explicitly, which takes a list of languages to use for compilation. CMake silently ignores your &lt;code&gt;*.cxx&lt;/code&gt; files, even if you clearly specify them in the source list.&lt;/p&gt;

&lt;h2&gt;
  
  
  (historical) Oboe needs Android NDK r17, while Cerbero specified r16
&lt;/h2&gt;

&lt;p&gt;It is now only a past issue, but Cerbero &lt;code&gt;android.config&lt;/code&gt; specified Android NDK r16 explicitly. It was upgraded to r18 about 5 days ago.&lt;/p&gt;

&lt;p&gt;NDK r16 lacks some required constant definition in AAudio API, which results in Oboe build failure. Therefore it is mandatory to use NDK r17 or later anyways.&lt;/p&gt;

&lt;p&gt;I ended up to hack around Cerbero sources (again!) - this time it was trivial and that particular AAudio issue was resolved. But then another problem showed up...&lt;/p&gt;

&lt;h2&gt;
  
  
  gnustl and libc++
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/android-ndk/ndk/wiki/Changelog-r17" rel="noopener noreferrer"&gt;Since Android NDK r17&lt;/a&gt;, it's moving away from gnustl and started using libc++ in clang. And with r18 gcc and co. are totally gone, meaning that there is no gnustl anymore.&lt;/p&gt;

&lt;p&gt;I have been using Cerbero build system to get a working glib build with all the dependencies. Unfortunately, their build script still specifies android-16 (JellyBean) in &lt;code&gt;config/cross-android-*.cbc&lt;/code&gt;, and that triggered some problem. Let's see NDK r17 release notes...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;libc++ is now the default STL for CMake and standalone toolchains. If you manually selected a different STL, we strongly encourage you to move to libc++. Note that ndk-build still defaults to no STL. For more details, see this blog post.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;also...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The platform static libraries (libc.a, libm.a, etc.) have been updated.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All NDK platforms now contain a modern version of these static libraries. Previously they were all Gingerbread (perhaps even older) or Lollipop.&lt;/li&gt;
&lt;li&gt;Prior NDKs could not use the static libraries with a modern NDK API level because of symbol collisions between libc.a and libandroid_support. This has been solved by removing libandroid_support for modern API levels. A side effect of this is that you must now target at least android-21 to use the static libraries, but these binaries will still work on older devices."&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;What makes things complicated is Cerbero android build which in general (namely &lt;code&gt;android/external/cerbero/packages/base-system-1.0.package&lt;/code&gt;) specifies 'gnustl' as part of the dependencies. gnustl is the standard C++ STL implementation library from GCC. See the first quote from NDK r17 release notes. They now have switched to libc++ and "strongly encourage" to move to libc++...&lt;/p&gt;

&lt;p&gt;What happens if we mix uses of both? Some "unresolved reference" errors due to lack of either at linking.&lt;/p&gt;

&lt;p&gt;Unfortunately, gnustl is widely used among many recipes and that should be handled by whoever is involved in Cerbero well (which is hopefully not very complicated).&lt;/p&gt;

&lt;h2&gt;
  
  
  solution: two shared libraries
&lt;/h2&gt;

&lt;p&gt;Compared to the problem above, it is much easier to deal with, but another minor problem with Oboe was that it requires C++ build support. And that slightly messed up existing &lt;code&gt;CMakeLists.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To sort out those issues, I ended up to build a C-based oboe shared library &lt;code&gt;liboboe-c.so&lt;/code&gt; and &lt;code&gt;libfluidsynth.so&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;liboboe-c.so: based on C++, links libc++&lt;/li&gt;
&lt;li&gt;libfluidsynth.so: based on C, links gnustl&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While I had been trying to get this working, there were some new commits in Cerbero and it had moved to NDK r18. But since gnustl is still in use, the symbol expectation mismatch still happens. I decided to keep this &lt;code&gt;liboboe-c.so&lt;/code&gt; until it can go totally unnecessary...&lt;/p&gt;

&lt;p&gt;(And in the future when Android NDK r19 lands, it will also migrate from gold linker to lld, which could bring in other kinds of problem.)&lt;/p&gt;

&lt;p&gt;(I might add more lines later, but so far I'd publish this first to make it visible on what I've been doing regarding them.)&lt;/p&gt;

</description>
      <category>fluidsynth</category>
      <category>android</category>
      <category>ndk</category>
      <category>midi</category>
    </item>
    <item>
      <title>Fluidsynth 2.0.x for Android</title>
      <dc:creator>Atsushi Eno</dc:creator>
      <pubDate>Wed, 31 Oct 2018 17:18:21 +0000</pubDate>
      <link>https://dev.to/atsushieno/fluidsynth-20x-for-android-4j6b</link>
      <guid>https://dev.to/atsushieno/fluidsynth-20x-for-android-4j6b</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;My fluidsynth Android port is live again, caught up with the latest Fluidsynth development (2.0.x).&lt;/li&gt;
&lt;li&gt;There is Java version of fluidsynth based on JNA.&lt;/li&gt;
&lt;li&gt;There is native asset loader now.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recap from the last post
&lt;/h2&gt;

&lt;p&gt;Back in March, I &lt;a href="https://dev.to/atsushieno/fluidsynth-for-android--269i"&gt;wrote a post&lt;/a&gt; on my Fluidsynth port to Android. Since then I spent some time or have been doing busy on other stuff (such as the latest &lt;a href="https://sangorrin.blogspot.com/2018/10/techbookfest-5.html"&gt;TechBookFest5&lt;/a&gt; as the management team). But now that I'm not employed and have a lot more flexible time, I could resume my Fluidsynth port as well as many other music related software I had been working on. Anyhow...&lt;/p&gt;

&lt;p&gt;To recap the latest state, I had &lt;a href="https://github.com/atsushieno/fluidsynth"&gt;an Android port of fluidsynth&lt;/a&gt;, using &lt;a href="https://github.com/atsushieno/cerbero/tree/add-fluidsynth"&gt;a fork of Cerbero&lt;/a&gt;, organized by my own module called &lt;a href="https://github.com/atsushieno/android-fluidsynth/"&gt;android-fluidsynth&lt;/a&gt;. The build is complicated so that almost no one could use my outcome, and the original Fluidsynth had &lt;a href="https://github.com/Fluidsynth/fluidsynth"&gt;moved to github&lt;/a&gt; with evolving changes e.g. migration to CMake build system. The CMake build system on Cerbero didn't work nicely for Android.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resurrection and restructuring
&lt;/h2&gt;

&lt;p&gt;To make things worse, my android-fluidsynth build got broken when Google updated Android NDK to whichever version I don't even remember - I had to manage Android NDK support in my Cerbero fork tree, and it's been somewhat annoying. And NDK had various changes that make updates messy - aarch64 support, switch to unified headers (that means, file lookup paths change), and the default toolchains switch to Clang (and gcc getting obsoleted).&lt;/p&gt;

&lt;p&gt;So, I began with refactoring the entire build dependencies. This was what I had in the beginning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;atsushieno/fluidsynth-midi-service
  atsushieno/android-fluidsynth (submodule)
    atsushieno/cerbero (submodule)
      atsushieno/fluidsynth (git checkout)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;My cerbero changes were for 1) NDK lookup changes, and 2) additional fluidsynth build recipe. I decided to remove fluidsynth build from there. That means, cerbero still builds glib (still required as a dependency) but I could just use the outcome and reference it from another CMake-based fluidsynth build (which is the current build system).&lt;/p&gt;

&lt;p&gt;(I could even package those native binaries for glib, but now it is just to checkout and run cerbero build, which is maintained by their own team, which is simple enough for me.)&lt;/p&gt;

&lt;p&gt;To align with that, I ended up to create another fluidsynth fork which is based on the latest original tree (Fluidsynth/fluidsynth on github) and ported my opensles additions (which needed some additional changes, but that's not important here).&lt;/p&gt;

&lt;p&gt;Along with this way, I could significantly reduced my dependency tree:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;atsushieno/fluidsynth-midi-service
  atsyshieno/fluidsynth-fork (new, submodule)
    GStreamer/cerbero (on-the-fly checkout at build time. Not on github)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;... and build it again(!)&lt;/p&gt;

&lt;p&gt;Once I could submit a PR to the original Fluidsynth repo and got accepted, then the dependencies will look even simpler, but let's think about it later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kotlin based application
&lt;/h2&gt;

&lt;p&gt;In the earlier days, I had been using Xamarin.Android as the primary app development framework for this fluidsynth port. However after I quit the development team, it became impossible to keep using the IDE on Linux. I still continue the development, but it became quite tough without IDE.&lt;/p&gt;

&lt;p&gt;After many thoughts I ended up to start &lt;a href="https://github.com/atsushieno/fluidsynth-midi-service-j"&gt;porting part of my C# app to Kotlin&lt;/a&gt;, using &lt;a href="https://github.com/java-native-access/jna"&gt;JNA&lt;/a&gt; for my &lt;a href="https://github.com/atsushieno/nfluidsynth"&gt;NFluidsynth&lt;/a&gt; replacement. The actual API binding is almost automatically generated using &lt;a href="https://github.com/nativelibs4java/JNAerator"&gt;JNAerator&lt;/a&gt;. Since I didn't want to mess with JNI, it was a big help to me. (I was a &lt;a href="https://github.com/nativelibs4java/BridJ"&gt;BridJ&lt;/a&gt; contributor in the past, but now JNA looks easier to depend on.)&lt;/p&gt;

&lt;p&gt;The ported app is far from a feature parity port, but at least it is enough to dogfood the fluidsynth Android port. In the end there will be fully functional MidiDeviceService implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Custom SoundFont loader for Android Assets
&lt;/h2&gt;

&lt;p&gt;One of the big API changes in Fluidsynth 2.0 was a completely rewritten custom SoundFont loader. In Fluidsynth 1.x we had to completely implement SF loader that does not only provide custom stream processor but also had to build the entire SoundFont structure, which makes it almost impossible to customize. Fluidsynth 2.0 offers a new way to provide a set of custom "stream callbacks" (for open/read/seek/tell/close) that lets us implement our own stream loader.&lt;/p&gt;

&lt;p&gt;My previous port had some changes to provide custom stream loader which had exactly the same purpose, so I could totally remove those changes. Instead, now I (kind of) have to provide custom SF loader functionality for Android Assets that aligns with the new way.&lt;/p&gt;

&lt;p&gt;There are two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;implement custom callbacks in native (as in NDK manner) API.&lt;/li&gt;
&lt;li&gt;implement callbacks in the wrapper languages (C# for Xamarin.Android, Java for ordinal Android developers).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What makes the former (native API approeach) annoying is that the NDK Assets API requires &lt;code&gt;JNIEnv&lt;/code&gt; and &lt;code&gt;jobject&lt;/code&gt; to acquire &lt;code&gt;AAssetManager&lt;/code&gt;. It was especially annoying for my new Kotlin-based app. I ended up to add &lt;code&gt;Java_fluidsynth_androidextensions_NativeHandler_setAssetManagerContext()&lt;/code&gt; function in the Android port. (It is nasty especially because any Java code that tries to use this API needs to have &lt;code&gt;NativeHelper&lt;/code&gt; class in &lt;code&gt;fluidsynth.androidextensions&lt;/code&gt; package, that I offer in my Kotlin app. I even renamed my Kotlin app package from &lt;code&gt;name.atsushieno.fluidsynth&lt;/code&gt; to &lt;code&gt;fluidsynth&lt;/code&gt; to make it less nasty...)&lt;/p&gt;

&lt;p&gt;The second approach (to write callbacks in wrapper languages) looks viable, but it needs some special care about GlobalRefs for the Java objects that provide those callback functionality - whenever GC moves your method references, the Asset SF loader crashes! I haven't resolved that issue with my JNAerated API yet (C# version works as I made it "pinned" with &lt;code&gt;GCHandle&lt;/code&gt;). Native interop is a wild where you're killed without sufficient crash information or chance to debug...&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a debuggable libfluidsynth.so
&lt;/h2&gt;

&lt;p&gt;Even after I got a "successful" &lt;code&gt;libfluidsynth.so&lt;/code&gt; builds, it never worked successfully. The longstanting problem was &lt;a href="https://github.com/atsushieno/fluidsynth-midi-service-j/issues/2"&gt;an unexpected SIGILL&lt;/a&gt;. This issue was even registered at luckier state than at first, as it has a debuggable binary(!)&lt;/p&gt;

&lt;p&gt;There had been wide variety of chances that &lt;code&gt;libfluidsynth.so&lt;/code&gt; was built without debug symbols. For example, you have to...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explicitly specify debugging options such as &lt;code&gt;-Denable-debug=on&lt;/code&gt; and give additional &lt;code&gt;-fsanitize=undefined&lt;/code&gt; and &lt;code&gt;-fsanitize-trap=undefined&lt;/code&gt; flags at CMake,&lt;/li&gt;
&lt;li&gt;make sure to pass &lt;code&gt;-g&lt;/code&gt; or those &lt;code&gt;-fsanitize=undefined&lt;/code&gt; etc. to gcc execution (for standalone toolchain uses), or&lt;/li&gt;
&lt;li&gt;specify &lt;code&gt;NDK_DEBUG&lt;/code&gt; and make sure to kill &lt;code&gt;cmd-strip&lt;/code&gt; for &lt;code&gt;ndk-build&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After those struggles, I could finally get lldb working with my &lt;code&gt;libfluidsynth.so&lt;/code&gt;. It was a long journey.&lt;/p&gt;

&lt;p&gt;I ended up to write a lengthy article about these kind of tricks for &lt;a href="https://techbooster.booth.pm/items/1046485"&gt;our indie tech book&lt;/a&gt; for that TechBookFest5 (in Japanese) from this experience...&lt;/p&gt;

&lt;h2&gt;
  
  
  Fighting against SIGILL
&lt;/h2&gt;

&lt;p&gt;The SIGILL issue I mentioned at the top of the previous section actually took a while... the debugger did not give much information about "why" (while it gives "where" which is still informative). The relevant function is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static int chunkid(unsigned int id)
{
    unsigned int i;
    const unsigned int *p;

    p = (const unsigned int *)&amp;amp;idlist;

    for(i = 0; i &amp;lt; sizeof(idlist) / sizeof(int); i++, p += 1)
    {
        if(*p == id)
        {
            return (i + 1);
        }
    }

    return UNKN_ID;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It was weird especially because &lt;a href="https://github.com/FluidSynth/fluidsynth/blob/da6a2e7a91820bf97f89d3bcdb15b76e94e90bc2/src/sfloader/fluid_sffile.c#L494"&gt;the problematic code&lt;/a&gt; was working fine in the past.&lt;/p&gt;

&lt;p&gt;Actually, it was problematic. This is what clang reports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/sources/fluidsynth-midi-service-j/external/fluidsynth/src/sfloader/fluid_sffile.c:494:9: warning: 
      cast from 'const char (*)[117]' to 'const unsigned int *' increases
      required alignment from 1 to 4 [-Wcast-align]
    p = (const unsigned int *)&amp;amp;idlist;
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you google the part of the message "increases required alignment from " then you'll find that it could indeed result in undefined behavior such as SIGILL.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/atsushieno/fluidsynth-fork/commit/0239d37"&gt;An unsophisticated workaround&lt;/a&gt; fixed the issue.&lt;/p&gt;

&lt;p&gt;It is possible that the latest NDK changes from gcc to clang or possible compiler option changes in Fluidsynth build (in CMakeLists.txt) triggered the breakage, but I have no precise idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fixing audio glitches
&lt;/h2&gt;

&lt;p&gt;Even at the previous working state with old Fluidsynth port, the audio playback was "glitchy". There was always noise inbetween, which was like it had some blank between synthesized samples.&lt;/p&gt;

&lt;p&gt;There was also annoying warnings that OpenSLES spewed onto device logs saying that there was insufficient playback buffer, meaning that there were too much synthesized buffers to enque, before consuming them. It looked like I was enqueuing too much.&lt;/p&gt;

&lt;p&gt;Before going forward, I should explain a bit about the buffering internals. There are two approaches to enqueue synthesized audio buffers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run an isolated audio loop. Get synthesized buffers and enqueue them while it's alive.&lt;/li&gt;
&lt;li&gt;Register OpenSLES callback. Get synthesized buffers and enqueue them within the callback.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the earlier codebase, I had a hacky workaround to "adjust" the latency to calculate exact buffering time, which often adjusts timing with synchronous usleep() calls. It still made sense when it's running an isolated audio run thread (the former model), but only if the buffering was at "earlier than the expected schedule". And it didn't make sense to try to adjust latency along with OpenSLES callback.&lt;/p&gt;

&lt;p&gt;And to make investigation complicated, it took a while for me to find that the buffering option switching by settings API didn't work as expected (due to bogus default value retrieval in my own code). I was also confused by two different "callbacks", one for OpenSLES and the other for Fluidsynth. After all, precise understanding of code and code cleanup to reduce confusion led me to &lt;a href="https://github.com/FluidSynth/fluidsynth/commit/9a4c265"&gt;the right solution&lt;/a&gt;...&lt;/p&gt;

&lt;p&gt;After fixing this, all those buffering related issues are gone and the port became really usable. &lt;a href="https://github.com/atsushieno/fluidsynth-midi-service-j/blob/dac3149/app/src/main/java/name/atsushieno/fluidsynthmidideviceservicej/FluidsynthMidiReceiver.kt#L29"&gt;It still needs some settings&lt;/a&gt; to get working in good state, but I'm quite happy with the outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next step
&lt;/h2&gt;

&lt;p&gt;Android audio situation keeps moving forward. Google had introduced new &lt;a href="https://developer.android.com/ndk/guides/audio/aaudio/aaudio"&gt;AAudio API&lt;/a&gt; since Android O (API Level 26) which brings chance for lower latency by handful of means (direct buffers, high priority audio callback, low latency mode specification in the API). Google first stated that AAudio will be backported to earlier Androids, but what realized instead was a new audio API called &lt;a href="https://github.com/google/oboe"&gt;Oboe&lt;/a&gt; that provides an unified API which switches two backend implementations (AAudio and OpenSLES).&lt;/p&gt;

&lt;p&gt;Oboe was at preview state when I wrote the previous post (or, it didn't even exist when I started porting) but now that Oboe is officially stable, it makes more sense to support it instead of OpenSLES. It is even fair to say that supporting OpenSLES became totally redundant... therefore, the next step is to support Oboe.&lt;/p&gt;

</description>
      <category>android</category>
      <category>midi</category>
      <category>audio</category>
      <category>fluidsynth</category>
    </item>
    <item>
      <title>managed-midi updates</title>
      <dc:creator>Atsushi Eno</dc:creator>
      <pubDate>Thu, 31 May 2018 03:16:46 +0000</pubDate>
      <link>https://dev.to/atsushieno/managed-midi-updates-5e01</link>
      <guid>https://dev.to/atsushieno/managed-midi-updates-5e01</guid>
      <description>

&lt;p&gt;Back in January, I wrote an introduction &lt;a href="https://dev.to/atsushieno/managed-midi-the-truly-cross-platform-net-midi-api-56hk"&gt;blog post&lt;/a&gt; about &lt;a href="https://github.com/atsushieno/managed-midi"&gt;managed-midi&lt;/a&gt;. It's been 4 months since then, and there are couple of updates, so it's nice to sum them up.&lt;/p&gt;

&lt;h3&gt;
  
  
  MIDI input supported
&lt;/h3&gt;

&lt;p&gt;I have a few MIDI input devices now, especially Seaboard Block is cool (it's quite useless for my actual use though :p).&lt;/p&gt;

&lt;p&gt;Maybe you think I'm just showing off my cool toy, but it's slightly more than that. Seaboard Block is based on BLE MIDI, which used to be supported only on iOS. Android 6.0 supported BLE MIDI as part of its Android MIDI API too. But Linux had no chance to use it until fairly recent &lt;a href="https://blog.felipetonello.com/2017/01/13/midi-over-bluetooth-low-energy-on-linux-finally-accepted/"&gt;Bluez and Linux kernel got support for that&lt;/a&gt;. I'm on Ubuntu 17.10, so I also needed to switch to &lt;a href="https://bugs.launchpad.net/ubuntu/+source/bluez/+bug/1713017"&gt;some patched build&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Anyhow, I got some reason to work on MIDI input support in managed-midi and it's done there. I also have M-AUDIO KeyStation Mini 32, but those two devices give totally different input messages... what Seaboard brings in is &lt;a href="http://expressiveness.org/2015/04/24/midi-specifications-for-multidimensional-polyphonic-expression-mpe"&gt;MPE&lt;/a&gt; - for each keypress it sends pitchbend, PAf etc. accordingly to the specification, which is a lot of information (like accelerometer multi-axes inputs). It will be fun once I can think of apps and support nicer handling of those MPE messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  netstandard2 based NuGet packaging
&lt;/h3&gt;

&lt;p&gt;I don't care much about nuget packaging, but it is of some goodness to spread use of this library (which, well, again, I don't care...). As explained in the &lt;a href="https://dev.to/atsushieno/managed-midi-the-truly-cross-platform-net-midi-api-56hk"&gt;previous post&lt;/a&gt;, Xamarin.Mac Full project is blocked and it's unchanged. Probably few people cares, but I do care - Xamarin.Mac full is the only profile that I can get Xwt working, and therefore my xwt-based &lt;a href="https://github.com/atsushieno/xmdsp"&gt;xmdsp&lt;/a&gt; working) too.&lt;/p&gt;

&lt;p&gt;Anyhow Xamarin, which brings the primary reason for me to "package" managed-midi, has migrated to .NET Standard 2.0 world from PCL-based world. So I moved forward too.&lt;/p&gt;

&lt;p&gt;There should be .NET Core version of this library too (unlike the netstandard2.0 library, it will contain ALSA support etc.), hopefully in the near future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Precise time controller
&lt;/h3&gt;

&lt;p&gt;managed-midi used to be a dumb, simple MIDI player that never dealt with latency. It was somehow significant and not ignorable, and it was &lt;a href="https://github.com/atsushieno/managed-midi/issues/14"&gt;reported a while ago&lt;/a&gt;. It's been a big concern for me too.&lt;/p&gt;

&lt;p&gt;managed-midi comes with a timer class called MidiTimeManager. Usually we use the default timer, which waits for the specified time span (simple as Task.Delay()), while we can alternatively use virtual time manager. It is just like TestScheduler in Rx.NET. You don't want to wait forever when running unit tests.&lt;/p&gt;

&lt;p&gt;So, technically timers can do more than simple and stupid wait. And any MIDI libraries would be dealing with that. I was lazy to actually implement it until very recently.&lt;/p&gt;

&lt;p&gt;While it is still impossible to test this improvements (unless I actually play some  songs and measure the actual play time within the unit tests...), I use my xmdsp MIDI player to examine the latest accuracy. I used to author quite complicated song files (either copies or original songs) that I use for dogfooding.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next
&lt;/h3&gt;

&lt;p&gt;I have no idea TBH. My target is shifting to either raw audio based stuff (such as android-fluidsynth) and some MIDI composition environment. But since managed-midi is foundation for all my existing apps, it will keep going.&lt;/p&gt;


</description>
      <category>midimonoxamarin</category>
    </item>
    <item>
      <title>TechBookFest: the most passionate book authors sell their indie tech books in Japan</title>
      <dc:creator>Atsushi Eno</dc:creator>
      <pubDate>Sat, 21 Apr 2018 13:08:27 +0000</pubDate>
      <link>https://dev.to/atsushieno/techbookfest-the-most-passionate-book-authors-sell-their-tech-books-in-japan-218m</link>
      <guid>https://dev.to/atsushieno/techbookfest-the-most-passionate-book-authors-sell-their-tech-books-in-japan-218m</guid>
      <description>&lt;h2&gt;
  
  
  What is it?
&lt;/h2&gt;

&lt;p&gt;One of the big events I have been involved in Japan is "tech book festival" (技術書典). If you have ever heard of Comic Market in Japan, you'd find it similar but the targets are limited to technology.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftechbookfest.org%2Fassets%2Ftbf04%2Fimages%2Ftop.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftechbookfest.org%2Fassets%2Ftbf04%2Fimages%2Ftop.jpg" alt="TechBookFest4"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is one-day festival in Tokyo, held at Akiba, where all the geeky things get together. The visitors are mostly engineers. Last time it was in October, unfortunately on a Typhoon day, yet there were more than 3000 people. The next one will be on Apr. 22nd (tomorrow, at the time of writing).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.google.com/search?tbm=isch&amp;amp;q=%E6%8A%80%E8%A1%93%E6%9B%B8%E5%85%B8&amp;amp;tbs=imgo:1" rel="noopener noreferrer"&gt;Google images about it and see what it is like&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In Japan, and I assume everywhere in the world, book publishers are shrinking and the industry is sunsetting. Programming and engineering books are not exceptional. But on the contrary, this festival is super active. How is it possible??&lt;/p&gt;

&lt;p&gt;There are some factors that make it happen.&lt;/p&gt;

&lt;p&gt;There are lots of "circles" (independent people or communities who write books), and they don't have to be very popular. The first TechBookFest was done with 50-ish circles, and the next one will be 246 of those. Their topics are often quite niche, sometimes super niche. They write about whatever they are most interested and would like to write. Just like comic authors at the Comic Market, they don't care much about sales - or they do care, but it's not the top priority. They are not publisher companies and it's not commercial driven.&lt;/p&gt;

&lt;p&gt;And since it's a face-to-face festival, it is not only about selling and buying books. They can have some (brief) talk about the technology the circles are writing, and get connected if they want. Similarly, we, the event organizers, lay out those similar circles close, so those neighbors can friend and chat. &lt;a href="https://atsushieno.github.io/xamaritans/" rel="noopener noreferrer"&gt;I have my own circle&lt;/a&gt; about Xamarin too, and it is laid out right next to the circle for React Native next time. Flutter circle is on the counterpart too. (Actually we are already all friends.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Indie books get popular
&lt;/h2&gt;

&lt;p&gt;So you think they won't sell at all? But there are 3000-ish visitors who are really interested in technology. What happens if there are such a lot of visitors browsing all the books at the market? Tenth of people, often hundreds, get interested in your books. It does not have to be sold for thousands. And the number is power. You are not alone to get attraction. There are &amp;gt;200 similar authors.&lt;/p&gt;

&lt;p&gt;One of an interesting move that happened from the festival is that there are commercial book publishers (they can also join, sell and exhibit their publications at the festival) that are always looking for interesting books that are in commercial quality.&lt;/p&gt;

&lt;p&gt;For example, at the second fest we have published two books about Xamarin (I tried to organize all into one book, but the authors were too passionate and wrote a lot of pages so that I had to split them).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fa%2Fatsushieno%2F20170330%2F20170330191800.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fa%2Fatsushieno%2F20170330%2F20170330191800.png" alt="Essential Xamarin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I made &lt;a href="https://atsushieno.github.io/xamaritans/tbf2.html" rel="noopener noreferrer"&gt;a minimalist promotion page&lt;/a&gt; for that (which is written in 199Xs markup technology), but it didn't matter. Most of the promotions were done by the co-authors, and those 100 copies for each book were all sold out in 2.5 hours.&lt;/p&gt;

&lt;p&gt;I have to say, our book was supreme as of the time of writing, written by top local developers, so some of the publishers got contacted with me if we were interested in publishing those books commercially. &lt;a href="https://www.amazon.co.jp//dp/B07539YT44/" rel="noopener noreferrer"&gt;So we did&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The next book at the next festival (TBF3) didn't sell that much, but it is still commercially published too. I'm not interested in managing everything for commercial publishing, so our next book won't go commercial (I decided so). But I'm totally happy with indie publication. The commercial publisher takes 85% of the revenue for printed books, which is, well, absurd. We can publish by our own and what they do is only to make some edits and manage everything for Amazon/Kindle (I can do that too).&lt;/p&gt;

&lt;p&gt;That's a "successful" case, but you don't even have to be "successful". It's not really the point when you are enjoying the festival. Your publications don't have to be "great". You can find inspiring books, even better if you are distributing your books of your own best interest, and find friends of the same interest.&lt;/p&gt;

&lt;p&gt;For the upcoming one, I wrote a book by myself about my Music Macro Language (MML) to MIDI compiler, explaining how to use it, what the syntax is like, and tips for authoring each instrument part e.g. for bass, guitar, drums and keyboards. It is kind of normal content for MML authors, but MML itself is super niche, technology from 20th century. But after I announced it, I received a handful of (not many) requests for and interest in that book ("I want your MML book!"). They are "music to my ears" ...!&lt;/p&gt;

&lt;h2&gt;
  
  
  The event organizers
&lt;/h2&gt;

&lt;p&gt;The entire festival is managed by two organizations: &lt;a href="https://techbooster.org/" rel="noopener noreferrer"&gt;TechBooster&lt;/a&gt; is a software engineer community. The group has been publishing their indie books about Android/mobile and Web at the Comic Market, and now the festival by themselves too. &lt;a href="https://tatsu-zine.com/" rel="noopener noreferrer"&gt;tatsu-zine.com&lt;/a&gt; (達人出版会) is an ebook publisher that has been for many years. I'm one of the members of the former and sometimes write about Android stuff.&lt;/p&gt;

&lt;p&gt;After some experiences at the Comic Market, the leader started saying like "what if we organize our own festival for tech books?" ...That sounded crazy (the leader always have some crazy ideas), but it somehow realized, and now it's huge.&lt;/p&gt;

&lt;p&gt;The core event organizer group is of a few people, and there are like ~50 staffs on the festival day. The group prepares all the websites, organizes the list of circles which visitors can bookmark them (and those at circles can see how many bookmarks they get), support them by several means, even offering online payment system will mobile apps. It's super busy activity especially in the week before the day.&lt;/p&gt;

&lt;p&gt;They are highly skilled developers and they often solves the problems technologically. For example, at TBF2 we had to make a lengthy line for waiting people to enter. At TBF3 we have a ticketing system and web page which notifies visitors the maximum ID number of the ticket ("People with ticket number XXX can enter") and the stressful queue is gone.&lt;/p&gt;

&lt;p&gt;(And of course the organizer asks for support in money too - each circle has to pay 7000JPY, but that's of course not enough to run the entire event. That's mostly the leader's job.)&lt;/p&gt;

&lt;h2&gt;
  
  
  How we compose books
&lt;/h2&gt;

&lt;p&gt;TechBooster takes an interesting approach to compose books. When we are authoring them, our circle uses Github repos (in my private account) that are tailored for it. We use a specific markup language called &lt;a href="https://github.com/kmuto/review" rel="noopener noreferrer"&gt;Re:VIEW&lt;/a&gt; as the text format, which is suited for book rendering to PDF (using latex) as well as HTML and EPUB. The group publishes an open repository for &lt;a href="https://github.com/TechBooster/ReVIEW-Template" rel="noopener noreferrer"&gt;ReVIEW template&lt;/a&gt; as well as their open book on &lt;a href="https://github.com/TechBooster/C89-FirstStepReVIEW-v2" rel="noopener noreferrer"&gt;How to write a book using Re:VIEW&lt;/a&gt;. There is even &lt;a href="https://hub.docker.com/r/vvakame/review/" rel="noopener noreferrer"&gt;a Docker image for Re:VIEW&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the editor side, we also have editor plugins support for Re:VIEW too. Atom has the first support, and I brought it to VSCode too. It supports preview, spell-check-like editorial helpers, and jump to sections.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fatsushieno%2Fvscode-language-review%2Fmaster%2Fdocs%2Fimages%2Fsshot-preview.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fatsushieno%2Fvscode-language-review%2Fmaster%2Fdocs%2Fimages%2Fsshot-preview.png" alt="vscode-language-review"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those drafts written in that simple markup language is easy to manage on Github - easy to get diffs, comment, create pull requests, integrating CI builds (for books!) and so on. It's very modern way. It's possible because almost all people in the group are software engineers and know how to git (we often have designers too).&lt;/p&gt;

&lt;p&gt;The approach is then taken by many circles and thus helped growing the tech book community. Now I have my own circle for Xamarin too, and it's also based on their project template.&lt;/p&gt;

&lt;p&gt;After writing the first draft, we have some "review" process. Usually TechBooster does mutual review each other, but this time for my own circle there were not many authors, so I only asked some friends to do it for our drafts. They did awesome job, so I could make a lot of improvements.&lt;/p&gt;

&lt;h2&gt;
  
  
  How they go paper
&lt;/h2&gt;

&lt;p&gt;I usually ask my friend painter to draw something I indicate (I pay for it), but this time (for the upcoming festival) I had to do it by myself, and it was hackily done. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fa%2Fatsushieno%2F20180419%2F20180419085023.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fa%2Fatsushieno%2F20180419%2F20180419085023.png" alt="mythbusters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are many small printing companies which offers support for indie books (同人誌 in Japanese) and printings can be done by sending a book body PDF and a cover page PSD like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fa%2Fatsushieno%2F20180419%2F20180419082929.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-ak.f.st-hatena.com%2Fimages%2Ffotolife%2Fa%2Fatsushieno%2F20180419%2F20180419082929.png" alt="cover page on the printing templates"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Those small companies are used to this kind of books because of the huge printing need at the Comic Market. There are similar domain-specific events (which we often call "[xyz-]only event" which deals only with [xyz]-stuff) and we TechBookFest are just one of those.&lt;/p&gt;

&lt;p&gt;I get familiar with command line tools for manipulating PDFs like pdftk or ImageMagick, as well as dealing with coverpages templates using Krita (which is AFAIK the only tool that I can generate Photoshop *.psd files in CMYK on Linux desktop).&lt;/p&gt;

&lt;p&gt;Some of the printing companies are "supported" by the event organizer, and they ship the printed books to the festival venue (for free for my case). The organizer group takes a lot of care about the circles' activities.&lt;/p&gt;

&lt;h2&gt;
  
  
  I'm writing this because...
&lt;/h2&gt;

&lt;p&gt;Did you get interested? Basically it began with a small independent activity, grew up in public manner. How about your city? It was possible in Tokyo. There weren't ComicCon before but now there are. How about book festival?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Fluidsynth for Android</title>
      <dc:creator>Atsushi Eno</dc:creator>
      <pubDate>Sat, 10 Mar 2018 08:59:21 +0000</pubDate>
      <link>https://dev.to/atsushieno/fluidsynth-for-android--269i</link>
      <guid>https://dev.to/atsushieno/fluidsynth-for-android--269i</guid>
      <description>&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;One of my unknown projects is Fluidsynth for Android. Since Android 6.0, it supports its own &lt;a href="https://developer.android.com/reference/android/media/midi/package-summary.html"&gt;MIDI API&lt;/a&gt; as well as MIDI connection over BLE, so it became possible to connect MIDI devices to Android (if you would like to read my Japanese article, it's part of the book &lt;a href="https://booth.pm/ja/items/126263"&gt;"Android Masters!"&lt;/a&gt;). A technically-looking-cool feature is that it supports virtual MIDI device services so that anyone can implement a MIDI device service that can provide either MIDI input devices or MIDI output devices (or both) that other apps can connect as clients and play them just like other operating systems (Windows, Mac, Linux, iOS...).&lt;/p&gt;

&lt;p&gt;It was designed to make it capable to run a software MIDI synthesizer through the service, so why not porting any of the existing bits? I thought so, and ended up to bring &lt;a href="http://www.fluidsynth.org/"&gt;Fluidsynth&lt;/a&gt; into Android land.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build system
&lt;/h2&gt;

&lt;p&gt;It was not simple; first of all, it does not make sense if there is no sound output. Fluidsynth is a software synthesizer that supports various audio APIs but not for Android. For Android, AudioTrack and &lt;a href="https://developer.android.com/ndk/guides/audio/opensl/index.html"&gt;OpenSL ES&lt;/a&gt; are the available choices (when I was implementing it; there was no AAudio nor Oboe). Fluidsynth has its audio abstraction layer in their &lt;a href="https://github.com/FluidSynth/fluidsynth/tree/master/src/drivers"&gt;&lt;code&gt;drivers&lt;/code&gt;&lt;/a&gt; source directory, so the only thing I had to do would be just to add another one there, right?&lt;/p&gt;

&lt;p&gt;It was not that simple.&lt;/p&gt;

&lt;p&gt;First, fluidsynth needed to be built with Android NDK toolchains. The original fluidsynth does not support Android builds. It would be particularly because of glib dependency; there is no intuitive way to build it for Android. glib is autotools-based and NDK did not play with it nicely.&lt;/p&gt;

&lt;p&gt;... Wait. There are handful of glib-dependent apps and libraries that are known to work on Android. There is &lt;a href="https://play.google.com/store/apps/details?id=org.dandroidmobile.xgimp"&gt;Gimp&lt;/a&gt;, right? ... but it runs on top of some weird X server. Next, how about GStreamer? It is &lt;a href="https://gstreamer.freedesktop.org/modules/gst-android.html"&gt;known to support Android&lt;/a&gt;. How is it built? ... that's how I found &lt;a href="https://gstreamer.freedesktop.org/documentation/installing/building-from-source-using-cerbero.html"&gt;Cerbero&lt;/a&gt; build system. It builds everything, including glib, in autotools manner, for Android as well as other targets.&lt;/p&gt;

&lt;p&gt;All those dependency libraries can be built with "recipe", which customize each library build. cerbero's ultimate purpose would be to build GStreamer, but it can be anything if a recipe is added to the tree. And it was quite easy to add fluidsynth to the catalog.&lt;/p&gt;

&lt;p&gt;I had to make some changes to support custom Android NDK setup, so my cerbero tree ended up to become an incompatible fork with the original tree, but I could build libfluidsynth.so for Android in the end.&lt;/p&gt;

&lt;p&gt;Everything ended up to become this repo: &lt;a href="https://github.com/atsushieno/android-fluidsynth/"&gt;https://github.com/atsushieno/android-fluidsynth/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Android/OpenSLES implementation
&lt;/h2&gt;

&lt;p&gt;Second, I had to add opensles implementation. The source structure was nice enough and I could easily add &lt;code&gt;fluid_opensles.c&lt;/code&gt; to the tree. A minor problem was that there was almost only one &lt;a href="https://bitbucket.org/victorlazzarini/android-audiotest/src"&gt;reference sample&lt;/a&gt; by Victor Lazzarini (&lt;a href="https://audioprograming.wordpress.com/category/android/"&gt;his blog&lt;/a&gt; used to be publicly visible but now it's private...). Even samples from an NDK book published in Japanese were almost the same as these samples.&lt;/p&gt;

&lt;p&gt;One another thing I had to implement was to support custom stream loader for SoundFont files. Fluidsynth only offered filename-based loader which simply used local file I/O. So I had to extend fluidsynth itself to accept custom SF loader - the abstraction API and Android assets-based implementation.&lt;/p&gt;

&lt;p&gt;Since my application is written in C#, I added those extensions to my P/Invoke wrappers (that's only what I had to do - if I were using Java, I'd also have to add JNI entrypoints too...).&lt;/p&gt;

&lt;h2&gt;
  
  
  NFluidsynth and FluidsynthMidiService
&lt;/h2&gt;

&lt;p&gt;Fluidsynth is cross-platform and works fine on Linux, which makes it easier for me to develop C# binding. Fluidsynth itself works as a virtual MIDI synthesizer, but to bridge from the system's MIDI service entrypoints, we have to make fluidsynth functions callable and map from those entrypoints.&lt;/p&gt;

&lt;p&gt;Therefore I made binding for  fluidsynth API using P/Invoke, released as &lt;a href="https://github.com/atsushieno/nfluidsynth"&gt;https://github.com/atsushieno/nfluidsynth&lt;/a&gt; . And making it as a Xamarin.Android library is almost at zero cost. I only had to care about Android-specific extensions built only for Android.&lt;/p&gt;

&lt;p&gt;At last, I created an  Android MIDI device service on top of this NFluidsynth.Android. To build such a service, we have to implement android.media.midi.MidiDeviceService. The entire API is super weird regarding inputs and outputs directions, but is not very difficult to implement.&lt;/p&gt;

&lt;p&gt;During this attempts, I found that supporting Android MIDI API is almost no benefits. My managed-midi API is cross-platform, inspired by Web MIDI API, and it makes more sense to rather implement Android backend for it. Therefore I came up with two implementations; one for MidiDeviceService and another for my API.&lt;/p&gt;

&lt;p&gt;They end up to become this repo: &lt;a href="https://github.com/atsushieno/fluidsynth-midi-service"&gt;https://github.com/atsushieno/fluidsynth-midi-service&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  CMake switches and android-fluidsynth port
&lt;/h2&gt;

&lt;p&gt;All those works were done in earlier years, so it is kind of weird that I write this post in 2018. I thought there would have been more software MIDI synthesizers for Android being released, but it did not seem to happen. What I got instead was, a handful of inquiries about my android-fluidsynth port. Since the entire build system is quite tricky, most of those who attempted to build failed hard (I feel sorry for that...).&lt;/p&gt;

&lt;p&gt;One of the reasons it is kept undocumented was that the current state is (to me) very temporary - when I started this project, it was &lt;a href="https://sourceforge.net/projects/fluidsynth/"&gt;hosted at sourceforge&lt;/a&gt; and it was based on autotools. Now it is &lt;a href="https://github.com/Fluidsynth/fluidsynth/"&gt;hosted at Github&lt;/a&gt;  and the build system moved to CMake.&lt;/p&gt;

&lt;p&gt;CMake is problematic right now - cerbero technically supports CMake, but it never seemed to support Android. What cerbero does there is to specify custom toolchains (CC, LD, etc.). And when you override some toolchains specified by cmake toolchains config (there is one in Android NDK) ... it will detect inconsistent build specification and restarts the build again, without specified cmake options(!). That ends up to ignore my build options and the build fails. I still find no answer to solve this problem.&lt;/p&gt;

&lt;p&gt;Graduating Cerbero is an option, and the option comes with a handful of choices - cerbero is in our build system because it resolves glib dependency problem. To eliminate cerbero, we have to find ways to resolve glib build issue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/VolcanoMobile/fluidsynth-android"&gt;VolcanoMobile/fluidsynth-android&lt;/a&gt; is an option; it removed all glib dependencies. This tree however became incompatible with the original tree, and I don't feel comfortable with that. However, &lt;a href="https://github.com/degill/fluidsynth-android-opensles"&gt;there is an effort&lt;/a&gt; to incorporate my OpenSLES implementation into that diverged version. I'm thinking to switch the basis for binary build artifacts to the ones from this tree.&lt;/p&gt;

&lt;p&gt;Other choices are &lt;a href="https://github.com/google/cdep/"&gt;Google cdep&lt;/a&gt; (I don't like their basic idea of forking sources to make their own changes, which makes it merging origin unnecessarily messy), or incorporating &lt;a href="https://github.com/mono/eglib"&gt;mono eglib&lt;/a&gt; instead of depending on glib. But so far I'm okay with the glib-less port above.&lt;/p&gt;

&lt;p&gt;UPDATE (2018-03/12): eglib doesn't provide gthreads, so it's not an option.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's different from user's point of view
&lt;/h2&gt;

&lt;p&gt;Fluidsynth automatically chooses the available options to build, for each platform. And opensles will be the default driver in my Android port.&lt;/p&gt;

&lt;p&gt;There are some changes in SoundFont loader API and Android developers would like to use it (explained a bit, above). But other than that, there is no difference from the original source tree.&lt;/p&gt;

</description>
      <category>android</category>
      <category>audio</category>
      <category>midi</category>
      <category>xamarin</category>
    </item>
    <item>
      <title>managed-midi: the truly cross platform .NET MIDI API</title>
      <dc:creator>Atsushi Eno</dc:creator>
      <pubDate>Wed, 10 Jan 2018 14:54:42 +0000</pubDate>
      <link>https://dev.to/atsushieno/managed-midi-the-truly-cross-platform-net-midi-api-56hk</link>
      <guid>https://dev.to/atsushieno/managed-midi-the-truly-cross-platform-net-midi-api-56hk</guid>
      <description>&lt;p&gt;I have a (surprisingly) long term project called &lt;a href="https://github.com/atsushieno/managed-midi"&gt;"managed-midi"&lt;/a&gt; which is to offer cross platform C#/.NET MIDI access API. My "cross platform" here is not a marketing term; it targets Linux (ALSA), macOS (CoreMIDI) and Windows (WinMM), along with Android, iOS and UWP.&lt;/p&gt;

&lt;p&gt;Actually, my managed-midi project is not about cross-platform goodness. It's more of a structured music composition as well as messaging foundation. This is my primary motivation to develop this library.&lt;/p&gt;

&lt;p&gt;But I'm going to discuss cross-platform part.&lt;/p&gt;

&lt;p&gt;Wasn't there any existing effort to provide Midi access API? The only project I can think of is &lt;a href="https://github.com/naudio/NAudio"&gt;NAudio&lt;/a&gt;, which only cares about Windows. My primary desktop is GNOME on Linux, so it's no-go. This is a typical huge problem in C# developer ecosystem that they only care about Windows.&lt;/p&gt;

&lt;p&gt;Audio and music libraries are always like that, and few people have interest in cross-platform AND platform specific development. This development situation is similar to developing "bait-and-switch" PCLs, but like I generally don't care about Mac and UWP, people don't care about platforms they don't use.&lt;/p&gt;

&lt;p&gt;It is kind of ironic that MIDI features are categorized within very platform specific API groups, whereas MIDI itself is designed to be device independent.&lt;/p&gt;

&lt;p&gt;The situation in C++ world is however changing. VST is now available on Linux too (I mean, the original library from Steinberg). We are seeing new-generation DAWs working on Linux (Renoise, Bitwig Studio, Tracktion WaveForm etc.).&lt;/p&gt;

&lt;h2&gt;
  
  
  wrapping around cross-platform MIDI API
&lt;/h2&gt;

&lt;p&gt;Back in 2009 when I started launching this project among other small projects I had in mind (when this project didn't even have a name and repo), I found &lt;a href="http://portmedia.sourceforge.net/"&gt;PortMIDI&lt;/a&gt;, which is a cross-platform MIDI library that supports Windows, Mac and Linux, and I found it cool. I didn't want to deal with platform-specific MIDI APIs, especially whatever I was not familiar with. Instead, I wrote a P/Invoke wrapper and OO-style API around it. I think my idea was good (I still kind of) - it is important to quickly get what we need, right? Those smart native developers dealt with the platform specifics, and I made use of the outcome.&lt;/p&gt;

&lt;p&gt;That was the beginning of this library. I just wanted an SMF parser and a MIDI player that plays MIDI songs that I can compose using my music macro language compiler &lt;a href="https://github.com/atsushieno/mugene"&gt;mugene&lt;/a&gt;. There wasn't even appropriate abstraction.&lt;/p&gt;

&lt;p&gt;It was however somewhat messy to get apps that are based on this library working. My primary .NET runtime has been always Mono, and I was primarily on Windows at that time. I couldn't care much about Linux. Since portmidi is a pure third-pary library it always required binary shared libraries. portmidi was painful to me on Windows since it required JNI header files to build. And it has to be offered in 32bit for Mono (which supported only 32-bit x86 on Windows at that time) and 32bit binary didn't work on .NET Framework for some reason. I was not familiar with them. I almost dumped the idea of offering binaries by myself.&lt;/p&gt;

&lt;p&gt;A few years later, I found &lt;a href="https://github.com/thestk/rtmidi"&gt;RtMidi&lt;/a&gt; and it was simpler. Unfortunately it was C++ only, so I wrote C wrapper for that (which I &lt;a href="https://github.com/thestk/rtmidi/commit/a5c375c7"&gt;ended up to contribute&lt;/a&gt; to the project). It had the same issue as portmidi too but didn't require JNI stuff, so building binaries was not so painful. Moreover, the development was active (at that moment).&lt;/p&gt;

&lt;p&gt;There was still no proper abstraction, but it was implicitly done. The abstraction was done only as &lt;code&gt;MidiPlayer&lt;/code&gt; class (then I had &lt;code&gt;PortMidiPlayer&lt;/code&gt; and &lt;code&gt;RtMidiPlayer&lt;/code&gt;). I didn't care much about that.&lt;/p&gt;

&lt;h2&gt;
  
  
  MIDI API abstraction
&lt;/h2&gt;

&lt;p&gt;The primary reason I was developing managed-midi was to write usable MIDI application. So it does not have to be C#. There has been another effort to bring MIDI to cross-platform world - Web MIDI API. It is expected to be working on Web browsers, but right now it is only Chrome which supports it.&lt;/p&gt;

&lt;p&gt;Web MIDI support in early days was not actually great for Linux software synthesizers (Chrome supported only Mac at first, and software synthesizers need special permission to be enabled), but its API structure was informative. It gave me the basic ideas on what we can/should provide in any platform and what not.&lt;/p&gt;

&lt;p&gt;Therefore, I started refactoring the entire API structure. What's good with Web MIDI API was that it is kind of OO-style and closer to C#, compared to former C libraries.&lt;/p&gt;

&lt;p&gt;Thus, current API structure is like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IMidiAccess&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IMidiPortDetails&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;IMidiPort&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;IMidiInput&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IMidiOutput&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The MIDI messages are represented just as byte arrays. It is same as Web MIDI and RtMidi (portmidi was different, had its own message type).&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing direct access to native API
&lt;/h2&gt;

&lt;p&gt;Even with RtMidi, I was reluctant to build those libraries for Windows (I already switched my primary desktop to Linux) and Mac (I hate Apple's attitude against Adobe Flash, dumped my iPhone and switched to Android because of that), especially since I had to provide my custom library that included C API.&lt;/p&gt;

&lt;p&gt;After abstracting the API, I started to think that I could implement platform-specific implementation and switch the default implementation per platform so that I didn't have to bother to build native binaries anymore.&lt;/p&gt;

&lt;p&gt;Though the first problem I was faced was no P/Invoke availability in PCLs. I quickly thought that it's not suitable for PCLs. But there is another tech trend in .NET: PCL with "bait and switch" technology that makes it possible to provide a common API with platform-specific implementation. Technically this problem seemed resolved.&lt;/p&gt;

&lt;p&gt;The first native implementation target was Windows. Windows at this state means: Windows desktop and UWP (I don't care about WinRT, there is no official MIDI API and those users are used to be limited their ability). As of that time, what I wanted was rather getting my visual MIDI player &lt;a href="https://github.com/atsushieno/xmdsp"&gt;xmdsp&lt;/a&gt; seamlessly working on Windows and Mac as well as Linux, and it was on top of &lt;a href="https://github.com/mono/xwt"&gt;xwt&lt;/a&gt; which is based on WPF and thus desktop .NET Framework. Therefore WinMM matters. WinMM was easy. UWP is more organized API and wrapping around it was easy, but since I don't have any managed-midi apps it is totally untested.&lt;/p&gt;

&lt;p&gt;CoreMidi was different. It did not even start with desktop. What I actually thought was to get managed-midi working on Android (and it was not even for Android MIDI API - it was for my &lt;a href="https://github.com/atsushieno/fluidsynth-midi-service/"&gt;fluidsynth-midi-service&lt;/a&gt; project, but it's going to be too long to discuss that here). Anyhow mobiles got in sight at that time. Android MIDI API is shitty with the class names, but wrapping around it was easy.&lt;/p&gt;

&lt;p&gt;While I wrote CoreMidi implementation for iOS, I didn't have any managed-midi apps that work on iOS, so I didn't even try it. Even on Mac, I tried only once when Xamarin.Mac started working fine with Xwt with CoreMidi (there was complicated library resolution bug that I had to wait for fixes in 2017). API wise, CoreMidi was a bit more complicated than others due to their concept of endpoints.&lt;/p&gt;

&lt;p&gt;And... finally ALSA. I didn't want to work on ALSA because rtmidi just works, building rtmidi was always easy, and ALSA is complicated. But copying librtmidi.so everywhere is messy (like &lt;a href="https://github.com/atsushieno/managed-midi/issues/8"&gt;this issue&lt;/a&gt;) and as long as I am dependent on rtmidi I could not resolve some weird &lt;a href="https://github.com/atsushieno/managed-midi/issues/1"&gt;issues like this&lt;/a&gt;, so I ended up to learn about ALSA and implemented it as &lt;a href="https://github.com/atsushieno/alsa-sharp/"&gt;alsa-sharp&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fundamental problem with the "bait and switch" trick in .NET Standard
&lt;/h2&gt;

&lt;p&gt;At this state, managed-midi lacks a lot of features like input support everywhere (surprisingly? I didn't need it yet) and device connection state detector (which is part of Web MIDI API so it should be implemented too). I only cared about output (my primary goal is to get a MIDI player). Device detection is complicated on ALSA as it has to be done outside ALSA, and probably WinMM which doesn't provide the feature too.&lt;/p&gt;

&lt;p&gt;NuGet packaging is another bit problem - while I intended to build a cross-platform library, it does not take shape of "bait-and-switch" PCL or .NET Standard library. Here is why: Xamarin.Mac full profile requires its own &lt;code&gt;ProjectTypeGuids&lt;/code&gt;, which means it is basically different from .NET Framework desktop profile. They have to be different. And I cannot depend on Xamarin.Mac when I'm working on this library because I'm not on Mac (even if I had Mac, no one should be required to work on Mac anyways) and the entire desktop library cannot be Xamarin.Mac specific (see &lt;a href="https://medium.com/@donblas/xamarin-mac-and-netstandard2-708a06890302"&gt;this post&lt;/a&gt; for the PCL/NuGet target moniker).&lt;/p&gt;

&lt;p&gt;Therefore managed-midi has two different assemblies for the same netstandard moniker (net461). That makes it impossible to package one of either. Since there is no reason to prefer Xamarin.Mac specific assembly for net461, it is basically ignored.&lt;/p&gt;

&lt;p&gt;This is something .NET Standard designers should resolve.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>First post to dev.to</title>
      <dc:creator>Atsushi Eno</dc:creator>
      <pubDate>Wed, 10 Jan 2018 14:54:24 +0000</pubDate>
      <link>https://dev.to/atsushieno/first-post-to-devto-pc4</link>
      <guid>https://dev.to/atsushieno/first-post-to-devto-pc4</guid>
      <description>&lt;p&gt;I haven't blogged in English for a while (I do in Japanese) and that's mostly because I was always wondering where to post. dev.to looks good enough to me. My posts can be very short or very long, up to my motivation and feelings.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
