Generate an extremely long brown/pink/white noise MP3 in Linux

Using https://bitbucket.org/rsvp/gists/src/fc42e2068cf0e2109bf58c94f59bfb1976405755/noise.sh?at=default, simplified. Added fade-in and fade-out. Compile sox and lame with sndfile support to get the w64 format.

#!/bin/bash

noise='brown'
# ^your choice: 'white', 'pink', 'brown', 'tpdf'
# where tpdf stands for Triangular Probability Density Function (cf. dither).
# N.B. - white and pink noise have higher frequencies than Brown.

#does not determine the size of the output when "fade" is used, but must be at least
#as long as the fade cutoff.
len='10000:00'

progress='--show-progress'

# FYI Channels: 2 @ 32-bit, Samplerate: 48000Hz.

#w64 format eliminates the 2GB sox barrier with conventional wav files
mkfifo out.w64
rm -fr noise.mp3

#Makes for a ~7hr, 1GB MP3 with these lame settings (320 kbps CBR)
real_len='414:00'
#This volume was selected to just barely avoid clipping (view the MP3 in Audacity)
volume='-0.4dB'

sox -c 2 --null out.w64 synth $len ${noise}noise vol $volume fade t 3 $real_len &

lame --preset insane out.w64 out.mp3

#for some reason, lame puts a little loud blip at the beginning of the file,
#at position 0.05s or so. So remove it here
ffmpeg -ss 0.1 -i out.mp3 -acodec copy noise.mp3

rm out.w64
rm out.mp3
Posted in hacks | Leave a comment

jQuery UI button tweaks

I recently completed a project which included a complicated web application. jQuery UI looked really nice, so I went with it. I don’t regret that decision, but one thing was especially annoying: the buttons are unpolished to the point of being almost broken. They just don’t behave at all like desktop GUI buttons. I guess I could post this stuff over at jQuery UI, but I feel like these are all things you would notice within five minutes of playing around with the buttons, so they must have been deliberate design decisions (although I can’t fathom why). I used jQuery 1.6.2 and jQuery UI 1.8.14, so perhaps one or more of the issues are already fixed.

1. Firefox F5 refresh bug

Firefox has a bug which can cause jQueryUI buttons to sometimes retain their disabled state through a page refresh. This can happen on a normal refresh (hitting F5) but a complete refresh (hitting Ctrl-R) always completely resets the state. To fix it I added a line to the top of a $(function){}) block that is the first thing to execute on page load:

$("button").removeAttr('disabled').button();

2. Normal buttons

Themes define several colors for buttons, which are used for normal, mouseover, and mousedown states. But when you click a button, sometimes the button remembers the mouseover state even after you mouse away–so normal buttons (not checkboxes) seem to behave like checkboxes. My fix is to call an additional function from every button’s onclick event:

function resetButton(obj)
{
   $(obj).removeClass("ui-state-focus ui-state-hover");
}

...

$("#a_button").button();

...

<button id="a_button" onclick="resetButton(this); doSomething();">Click Me</button>

3. Checkboxes

Checkboxes can get into a funky state where the button highlight is opposite what you would expect given the “checked” status of the input. It’s easy to reproduce: just double-click the checkbox. They also suffer from the mouseover issues that normal buttons have:

function resetCheckBox(obj)
{
   if($("#" + $(obj).attr("for")).attr("checked") == "checked")
   {
      $(obj).addClass("ui-state-active");
   }
   else
   {
      $(obj).removeClass("ui-state-active");
   }
   resetButton(obj);
}

...

<input type="checkbox" id="checkbox1" onclick="doSomething();"/>
<label id="checkbox1_label" for="checkbox1" ondblclick="resetCheckBox(this);"></label>

4. Radio buttons

Radios are even buggier. I can’t remember all the debugging steps it took me to arrive at this function; as you can see, I’m reimplementing every part of the radio functionality. It makes me think I must have been doing something wrong, to need to do all this.

function resetRadio(obj)
{
   resetButton(obj); //remove hover classes
   $(obj).parent().children('label').removeClass('ui-state-active');
   $(obj).addClass('ui-state-active');
   $(obj).parent().children("input").removeAttr("checked");
   $("#" + $(obj).attr("for")).attr("checked", "checked");
}

...

<form>
   <div id="radio1">
      <input type="radio" name="radio1" id="radio1_opt1" checked="true" />
      <label for="radio1_opt1" onclick="resetRadio(this); doSomething();">Option 1</label>
      <input type="radio" name="radio1" id="radio1_opt2"/>
      <label for="radio1_opt2" onclick="resetRadio(this); doSomething();">Option 2</label>
   </div>
</form>

In sum, jQuery UI buttons: kinda buggy.

Posted in hacks | 1 Comment

midilog-0.1: MIDI logging of practice sessions

If you play keyboard and practice on an instrument that features MIDI output, it’s quite feasible to save all your practice sessions, using standard MIDI files (which are very compact). This program does just that!

For me, it’s nice to have a record of my progress over the years. It’s also nice knowing that if I ever lose interest and my skill starts to erode, or I am otherwise unable to play anymore, that I will have a few recordings representative of the zenith of my skill level. Lastly, knowing that every note is being recorded seems good for working on my performance confidence.

In Linux, just “make”. Since I used the RtMidi library, a Windows port would be possible, in theory.

midilog-0.1.tgz (GPL)

midilog version 0.1 for GNU/Linux, released under the GPL v. 3 or later license (see LICENSE)
RtMidi licensed under its respective license

by geekamole, 2011

usage: midilog LOG_DIR PORT_NAME

e.g., ./midilog /files/midilogs "MidAir:0"

This program is intended to run as a daemon. It looks for the specified PORT_NAME among the input ALSA MIDI ports on the system. It then waits for input on the port, and creates timestamped standard MIDI files in the specified LOG_DIR corresponding to periods of input.

I created this to work with my Yamaha P80 digital piano, to record all my practice sessions. It may require tweaking for other instruments. Sys-ex messages and all other events are saved, but the one-per-millisecond status updates from the P80 are filtered out. After 10 minutes of note/sysex inactivity on the port, or 2.5 seconds of missing millisecond status messages on the port (indicating the piano was turned off), the MIDI file is closed out and midilog prepares to create a new file when needed.

All MIDI messages are saved to a single track.

Somehow, when I created this I was unaware of the program "arecordmidi," which might have allowed me to avoid learning about the MIDI file format. However, studying the format allowed me to select parameters to guarantee 1/2 millisecond resolution at 120 bpm.

The included version of the RtMidi-1.0.11 library was slightly modified to signal when a MIDI port is no longer available. midilog then periodically attempts to reconnect to the port.

What the files look like:

MidiLog_20101031__1927_51.mid
Posted in hacks | Leave a comment