Wednesday, April 22, 2015

Web Audio

Good source of web audio features

http://labs.music.baidu.com/demo/audiolab/?p=0
http://labs.music.baidu.com/demo/interactions/visualization/
Getting Started with Web Audio API
Web Audio API - High-level JavaScript API for processing and synthesizing audio
http://www.sitepoint.com/5-libraries-html5-audio-api/
http://codegeekz.com/10-javascript-audio-libraries-for-developers/
http://www.smartjava.org/content/exploring-html5-web-audio-visualizing-sound
http://ianreah.com/2013/02/28/Real-time-analysis-of-streaming-audio-data-with-Web-Audio-API.html
https://blog.groupbuddies.com/posts/39-tutorial-html-audio-capture-streaming-to-node-js-no-browser-extensions

https://nusofthq.com/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/
https://github.com/icatcher-at/MP3RecorderJS
https://github.com/akrennmair/libmp3lame-js

http://www.patrick-wied.at/blog/how-to-create-audio-visualizations-with-javascript-html
http://www.schillmania.com/projects/soundmanager2/demo/360-player/canvas-visualization.html
http://www.sitepoint.com/3-breakthrough-ways-to-visualize-html5-audio/

Audio: visualization
http://readwrite.com/2008/03/13/the_best_tools_for_visualization


Programming with sound - Introduction

http://blogs.msdn.com/b/dawate/archive/2009/06/22/intro-to-audio-programming-part-1-how-audio-data-is-represented.aspx

Digital audio:
- stereo: 2 channels, for left/right ear
- mono: 1 channel only.
- sampling rate: ~ 44,100/sec, 44.1k Hz. Number of points/second. Other rate: 8/48/96/192K Hz.
- fundamental frequency: Number of oscillations of the wave per sec. 440 Hz - Concert A. 261.25 Hz - Concert C. Higher frequency == higher pitch.
- decibel: amplitude of the wave
- bit depth/bits per sample: 8-bit/16-bit waveform - use 8/16 samples for a waveform. The larger, the better quality.
- multiple tones: sound in real world is overlap of multiple sine waves/tones.

http://blogs.msdn.com/b/dawate/archive/2009/06/23/intro-to-audio-programming-part-2-demystifying-the-wav-format.aspx

- wave format: maybe the most basic sound format. Developed by Microsoft and IBM.
- uncompressed. but cannot go over 4GB, since file size header field is 32-bit unsigned int.
- chunks
- header
- format chunk
- data chunk
- making a wave file.

http://blogs.msdn.com/b/dawate/archive/2009/06/24/intro-to-audio-programming-part-3-synthesizing-simple-wave-audio-using-c.aspx

http://blogs.msdn.com/b/dawate/archive/2009/06/25/intro-to-audio-programming-part-4-algorithms-for-different-sound-waves-in-c.aspx


Pure Data

http://puredata.info/

Pure Data (aka Pd) is an open source visual programming language. Pd enables musicians, visual artists, performers, researchers, and developers to create software graphically, without writing lines of code. Pd is used to process and generate sound, video, 2D/3D graphics, and interface sensors, input devices, and MIDI. Pd can easily work over local and remote networks to integrate wearable technology, motor systems, lighting rigs, and other equipment. Pd is suitable for learning basic multimedia processing and visual programming methods as well as for realizing complex systems for large-scale projects.

Pd is free software and can be downloaded in different versions.

http://en.wikipedia.org/wiki/List_of_audio_programming_languages


Programming with sound - Overview

http://forum.devmaster.net/t/what-is-sound-programming/20773


Unlike most other things, it's real-time stuff (we're talking 0.02ms stuff here, as oposed to video's 17ms; and nobody cares if you miss a frame here or there, but audio must be flawless), and you have to deal with latencies and all sort of fun stuff like that.


Again, it looks simple and the concepts are pretty easy, but for some reason it always ends up being tricky. Thus, most people end up using libraries like FMOD, and *still* end up having issues here and there.

Also, if you want to synthesize audio, there is indeed a whole lot of interesting mathematics and theory you won't see much in other places.


I like to lump "sound programming" into 3 broad (sometimes overlapping) categories.

1) Sound Implementation programmer. This sounds like what you probalby think of. That's the programmer (often an intern ;0) whose job is to sprinkle the code with calls like "PlaySound(SNDTag, Parameters); through the game. (it can be quite a bit more than that, of course). Sound Implementation is usually, but not always, pretty straightforward

2) Sound Engine/Tool programmer. These programmers write the high-level sound engines that perform things like real-time streaming, data file parsing, etc. That requires pretty good knowledge of real-time and system programming. They may need to write entire (friendly and robust) User interfaces that a sound designer or composer will use when creating content. They are the essential link between content and code in content-driven audio development systems.

3) low-level audio signal processing programmer. These programmers typically need to know assembly language like the back of their hands as well as the complex mathematics behind the processing of audio. FFTs, DFT's, MLTs, IIR, FIR filters, data compression/decompression algorithms. That's pretty heavy stuff. And there's a ton of stuff going on out there. People do entire PhD dissertations on things like physical modelling of sound, real-time analysis of music, or environmental modeling..

So there's a lot of "meaty" stuff in game audio programming-- way more so than it may seem on the surface. Video game music and sound design still need a lot of specialized code to make it work
Brian Schmidt
Executive Director
www.GameSoundCon.com5


http://stackoverflow.com/questions/4801690/i-want-to-learn-audio-programming

- analogue sound: magnetic tape.. complex numbers, fourier transformation.
- sampled sound: CD, mp3, Ogg vorbis.. DSP.
- synthesized sound: sound + instrument type.

A programmer's guide to sound (1997)


Tuesday, April 21, 2015

Create daemon in Java

This can be a windows service or a unix daemon. The implementation might be different depending on platform. So I'm starting to do some research.


1. Apache Commons Daemon [1]

Apache Commons Daemon is a good alternative. It has Procrun [2] for windows services, and Jsvc [3] for unix daemons. It uses less restrictive Apache license, and Apache Tomcat uses it as a part of itself to run on Windows and Linux! To get it work is a bit tricky, but there is an exhaustive article [4] with working example. With Apache Commons Daemon you can now have a custom executable name and icon! You can also get a custom Windows tray monitor with your own name and icon!

Jsvc is a set of libraries and applications for making Java applications run on UNIX more easily.
Jsvc allows the application (e.g. Tomcat) to perform some privileged operations as root (e.g. bind to a port < 1024), and then switch identity to a non-privileged user.It can run on Win32 via the Cygwin emulation layer, however Win32 users may prefer to use procrun instead.

Procrun is a set of applications that allow Windows users to wrap (mostly) Java applications (e.g. Tomcat) as a Windows service. The service can be set to automatically start when the machine boots and will continue to run with no user logged onto the machine.


2. Java Service Wrapper (JSW) [download]

See short introduction in [5]. Also an implementation of it: YAJSW - Yet Another Java Service Wrapper [6]. Cons (?): community version cannot be run on a server.


References:

[1] http://commons.apache.org/daemon/
[2] http://commons.apache.org/daemon/procrun.html
[3] http://commons.apache.org/daemon/jsvc.html
[4] Java as Windows Service with Apache Commons Daemon
[5] Running Java Applications as a Windows Service
[6] YAJSW - Yet Another Java Service Wrapper 
[7] http://stackoverflow.com/questions/68113/how-to-create-a-windows-service-from-java-app
[8] Creating a Java Daemon (System Service) for Debian using Apache Commons Jsvc


Greasemonkey

Greasemonkey can do some interesting tricks on a webpage.

Greasemonkey scripts (Javascript) can alter web page elements, add a div or box to the page, trigger button click events and others.

For example, here is a script that adds a checkbox before the link tag for ever <li> element:


// ==UserScript==
// @name       script name
// @namespace  http://my.homepage/
// @version    0.1
// @description  add marking checkbox.
// @match      http://matched_website.com

// @match      https://matched_website.com
// ==/UserScript==

function changhandler(event) {
    if (event.target.checked) {
        localStorage[event.target.name] = true;
    } else {
        localStorage.removeItem(event.target.name);
    }
}

[].forEach.call(
    document.getElementById('main').getElementsByTagName('li'),
    function(e) {
        var checkBox = document.createElement('input');
        checkBox.type = 'checkbox';
        checkBox.name = e.getElementsByTagName('a')[0].innerHTML;
        checkBox.checked = localStorage[e.getElementsByTagName('a')[0].innerHTML];
        checkBox.addEventListener('change', changhandler, false);
        oj.insertBefore(checkBox, null);
    }
);


[1] http://en.wikipedia.org/wiki/Greasemonkey

Sunday, April 12, 2015

Create animated and transparent GIF image

Gifsicle: Very useful tool to manipulate gif, and create animated gif:

http://www.lcdf.org/gifsicle/


== How to make an existing animated gif loop repeatedly ==

Solution involving the Terminal [1]:
  1. Download the sources of Gifsicle
  2. Unpack the sources and go to the unpacked directory
  3. Do ./configure --disable-gifview --disable-gifdiff
  4. Do make
  5. Do cd src
  6. And finally do ./gifsicle -bl /path/to/image.gif
Note: to install, after step 4, do: sudo make install

Solutions using GUI tools (I didn't test any them !):
  1. You can try GifBuilder (requires Rosetta to work with Snow Leopard).
  2. Pixen also seems to be a Gif Editor.

[1] http://superuser.com/questions/159212/how-do-i-make-an-existing-animated-gif-loop-repeatedly
[2] http://blog.iharder.net/2009/10/22/gif-create-animated-gifs-with-mac-os-x-preview-app/
[3] http://osxdaily.com/2013/01/27/make-a-transparent-image-png-or-gif-easily-with-preview-for-mac-os-x/
[4] http://osxdaily.com/2010/01/24/convert-images-in-mac-os-x-jpg-to-gif-psd-to-jpg-gif-to-jpg-bmp-to-jpg-png-to-pdf-and-more/ 

Monday, April 6, 2015

Compress javascript a.js into a.min.js

Compress javascript a.js into a.min.js can be done on this site: http://jscompress.com/

Perl - extend lib path

See: http://www.perlhowto.com/extending_the_library_path

This is useful when you want to use personal lib for perl modules, which is not on perl path (@INC) and cannot be found.

3 methods are mentioned.

1) The non-invasive method is to use -I switch:

perl -I /home/path/lib -I /usr/another/lib script.pl

2) add path to environment:

# unix, bourne shell
PERL5LIB=/home/path/lib:/usr/another/path/lib; export PERL5LIB


3) add path to perl code:

#!/usr/bin/perl
use lib "/home/path/lib";
use lib "/usr/another/lib";

use MyCustomModule;

General Game Playing

General Game Playing is a course given by Stanford on the application of AI in computer games.

The course material is available here: http://logic.stanford.edu/ggp/chapters/


Saturday, April 4, 2015

Some readings today

Here are links to some readings today:

- Java equals()和hashCode()

   Q: 怎样实现正确的equals()方法
   A: 首先,我们需要遵守Java API文档中equals()方法的约定,如下:
    自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
    对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
    传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
    一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。

    对于任何非空引用值 x,x.equals(null) 都应返回 false。
    其次,当我们重写equals()方法时 , 不同类型的属性比较方式不同,如下:
    属性是Object类型, 包括集合: 使用equals()方法。
    属性是类型安全的枚举: 使用equals()方法或==运算符(在这种情况下,它们是相同的)。
    属性是可能为空的Object类型: 使用==运算符和equals()方法。
    属性是数组类型: 使用Arrays.equals()方法。
    属性是除float和double之外的基本类型: 使用==运算符。
    属性是float: 使用Float.floatToIntBits方法转化成int,然后使用 ==运算符。
    属性是double: 使用Double.doubleToLongBits方法转化成long , 然后使用==运算符。

  Q: 重写equals()方法为什么一定要重写hashCode()方法
  A: 如果不这样做就会违反Java API中Object类的hashCode()方法的约定,从而导致该类无法很好的用于基于散列的数据结构(HashSet、HashMap、Hashtable、LinkedHashSet、LinkedHashMap等等)。i.e., when search in hashtable based data structure, it'll first find the bucket based on hashCode(), then do compare by equals() to find exact match. Object.hashCode() by default is different for every object. This can't be used when, say, 2 strings "aaa" and "aaa", are different objects so have different hashCode, then you cannot find "aaa" in a container that contains "aaa".


- 揭秘阿里服务互联网金融的关系数据库——OceanBase
  This lacks details though.

JS前台加密,java后台解密实现
   This is not hard to decode though since JS is open.





用 Python 绘制音乐图谱

用 Python 绘制音乐图谱
Original post is from http://www.christianpeccei.com/
And Articles by: PyPer

Very nice. Might worth the time to try to reproduce.

Friday, April 3, 2015

Play midi in browser by Javascript only

Midi files usually have very small size, but rich sound effects. HTML5 Audio tag supports wav, mp3 and ogg formats so far.  Here are methods to play midi music in web browser using Javascript only, with no plugin such as QuickTime.

I wrote the one at [7].

Features

  • Can specify these in constructor parameter list: midi, target, loop, maxLoop, end_callback.
    - midi: MIDI file path.
    - target: Target html element that this MIDI player is attached to.
    - loop: Optinoal. Whether loop the play. Value is true/false, default is false.
    - maxLoop: Optional. max number of loops to play when loop is true. Negative or 0 means infinite. Default is 1.
    - end_callback: Optional. Callback function when MIDI ends.
      e.g., use this to reset target button value from "stop" back to "play".
  • Can specify a debug div, to display debug message: setDebugDiv(debug_div_id).
  • Start/stop MIDI by: start(), stop().
  • If a MIDI started play, call start() again will stop and then restart from beginning.
This depends on other 5 javascript files (audio.js, midifile.js, replayer.js, stream.js, synth.js) from [2][3], which is a demo of [1]. This is related to [4], which is a powerful tool to play MIDI in browser.

The disadvantage of [2][3] is that it does not have control over how a MIDI file is played: when clicking on the link the file will be started multiple times and sounds chaotic; and there is no loop feature. Both are well handled by MidiPlayer.js here.

Another midi player javascript is in [5], but it cannot play multiple MIDI files at the same time, cannot play a MIDI file automatically after loading the page, and has no loop feature. All are handled by MidiPlayer.js here.

It can be a good idea to add MIDI support to HTML5 Audio tag, because MIDI files have much smaller size than wav/mp3, and the sound effects are very rich.

[1] http://matt.west.co.tt/music/jasmid-midi-synthesis-with-javascript-and-html5-audio/
[2] http://jsspeccy.zxdemo.org/jasmid/
[3] https://github.com/gasman/jasmid
[4] MIDI.js - Sequencing in Javascript.
[5] MIDI.js - The 100% JavaScript MIDI Player using W3C Web Audio
[6] Dynamically generating MIDI in JavaScript
[7]  The MidiPlayer javascript class

Javascript drag/drop event listener

It is a cool feature that file processing is triggered when you drag a file and drop it onto a web page.

For example, the midi player demo page index.html from [1] has this in header javascript:

    if (FileReader){
        function cancelEvent(e){
            e.stopPropagation();
            e.preventDefault();
        }
        document.addEventListener('dragenter', cancelEvent, false);
        document.addEventListener('dragover', cancelEvent, false);
        document.addEventListener('drop', function(e){
            cancelEvent(e);
            for(var i=0;i            var
                file = e.dataTransfer.files[i]
            ;
            if(file.type != 'audio/midi' && file.type != 'audio/mid'){
                continue;
            }
            var
                reader = new FileReader()
            ;
            reader.onload = function(e){
                midiFile = MidiFile(e.target.result);
                synth = Synth(44100);
                replayer = Replayer(midiFile, synth);
                audio = AudioPlayer(replayer);
            };
            reader.readAsBinaryString(file);
            }
        }, false);
    }


What this does is, when you drag and drop a midi file on the page, it'll be read and played.

HTML5 has native support for drag/drop event. See [2].

[1] https://github.com/gasman/jasmid
[2] Native HTML5 Drag and Drop

Blog Archive

Followers