Self-publishing a book with CreateSpace and Amazon

Recently, I finished a book publishing project I started around last Christmas. The book is titled “12 Partitions pour Xylophone & Métallophone à 8 Barres” and contains sheet music of French children songs that can be played on toy metallophones (aka glockenspiel) or xylophones. To self-publish the book, I used CreateSpace, a subsidiary of Amazon. It is now for sale via Print-on-Demand on all North-American and European Amazon stores (for example Amazon.com or Amazon.fr).

Above, the front cover, with a matte finish.

Animambo Metallophone

Some background about the project: I had offered a toy metallophone (Animambo, above) as a Christmas gift to my 3 year-old niece. It came bundled with a couple of scores that represented notes using the colors of the bars on the instrument. However those songs were not the kind that would be known to a young French child so I started to put together a dozen classics of the French children songbook, based on scores I found online (mainly Wikisource Partitions).

I had to adapt the scores so they could be played on the instrument: It is limited to 1 octave and the C major scale. I also added hints of which bar to play under each note, a bit like with the Animambo scores. Since the various models of xylophones / metallophones have different color schemes for the bars, it made sense to let the end user color the hints depending on their instrument and therefore I left them blank.

The book was created using LilyPond, for typesetting the sheet music, and Latex, for the book interior and covers. The Latex book embeds the PDF’s generated by LilyPond to make the final, printable book. The full source code of the book is available on Github.

I thought the whole publishing process was quick and quite painless:

  • CreateSpace offers the ISBN so it is free to publish the book: CreateSpace Independent Publishing Platform is credited as the publisher however. Above, the attributed ISBN on the back cover.
  • There is a 24h delay after submission of the book PDF + covers where they check the book for technical issues.
  • After that, you are supposed to order a proof copy: It is possible to buy one for the cost of material but it is sent from the USA. Therefore, it takes either 6 weeks to arrive in France or 1 week with an additional $12 fee for priority mail. Instead, I didn’t do any check and waited for the book to show up on Amazon.fr to order a normal copy.
  • After confirmation of the proof copy, the book was listed almost right away on Amazon.com, Amazon.fr and the other Amazon stores, although it took an additional ~48h to be able to actually purchase the book on the French Amazon store (listed as Unavailable until then).

At first, I was not sure of the quality I should expect with a Print-on-Demand book but now that I got hold of a physical copy, I am quite pleased with the result. I may be biased but I think it looks pretty good!

Above, score for Il court, il court, le furet, a song written in the 18th century.

Advertisements

Chasm of the Apocalypse

I am aware it is indeed quite a boring / droning track but as my first foray into audio synthesis, it will do for now. Using Paulstretch Mono algorithm as a starting point, here is the Chuck code I used to generate that garbage:

SndBuf  buff => FFT fft =^ IFFT ifft => blackhole;
Impulse imp => LPF lpf => blackhole;
dac => WvOut w => blackhole;
lpf => PitShift ps1 => dac;
lpf => PitShift ps2 => dac;
lpf => PitShift ps3 => dac;

1000 => lpf.freq;
0.25 => ps1.shift;
0.5 => ps1.gain;
2 => ps2.shift;
0.8 => ps2.gain;
0.125 => ps3.shift;
0.5 => ps3.gain;

30.0 => float stretch;
5::second => dur window_dur;

me.sourceDir() + "/cc.wav" => string filename;
buff.read(filename);
buff.samples() / (buff.length() / 1::second) => float sample_rate;

me.sourceDir() + "/output_cc.wav" => w.wavFilename;

((window_dur / 1::second) * sample_rate) $ int => int window_size;
(window_size / 2) $ int => int half_window_size;

window_size => fft.size;
Windowing.hann(window_size) => fft.window;
Windowing.hann(window_size) => ifft.window;

complex s[half_window_size];
float ifft_s[window_size];
float old_ifft_s[half_window_size];

(1+Math.sqrt(0.5))*0.5 => float hinv_sqrt2;
float hinv_buf[half_window_size];
for(int i; i < half_window_size; i++) {
    hinv_sqrt2-(1.0-hinv_sqrt2)*Math.cos(i*2.0*pi/half_window_size) => hinv_buf[i];
}

0 => int start_pos;
(half_window_size / stretch) $ int => int displace_pos;

// control loop
while( start_pos < buff.samples())
{
    start_pos => buff.pos;

    fft.upchuck();
    fft.spectrum(s);
    polar pol;
    for(int i; i< window_size;i++) {
        s[i] $ polar => pol;
        Math.random2f(0, 2 * pi) => pol.phase;
        pol $ complex => s[i];
    }
    ifft.transform(s);
    ifft.samples(ifft_s);

    float output;
    for(int i; i < half_window_size ; i++) {
        hinv_buf[i] * (ifft_s[i] + old_ifft_s[i]) => output;
        ifft_s[i+half_window_size] => old_ifft_s[i];
        if(output > 1.0) {
            1.0 => output;
        } else if(output < -1.0) {
            -1.0 => output;
        }
        output => imp.next;
        1::samp => now;
    }

    displace_pos +=> start_pos;
}

There needs to be an input file named “cc.wav” in the same directory as the .ck file (for my track, I used the song “Creataceous Chasm” by Blotted Science). An output Wav file can be obtained with the command:

chuck --silent stretch_simple.ck

(Unfortunately, my stretch algorithm produces audible clicks in real-time mode so “–silent” must be used)

For contrast, here is a video for the Blotted Science song used as input:

Automating iTunes on Windows with IronRuby

I recently bought a new Windows computer and, since there is no AppleScript on Windows, I have to do without the Doug’s scripts for ITunes that I used on Mac OS X to automate the management of my music library. But Apple has made available a COM API, that can be used by any language to script iTunes, as long as it supports COM. This includes Ruby MRI, with the Win32OLE package in the standard library. But I was curious about IronRuby, the .NET implementation of Ruby, which recently reached version 1.0 and therefore, I decided to reimplement with it some of the scripts I used the most.

The scripts shown in this post can be downloaded here.

Installing IronRuby

The PATH environment variable is updated and now contains the “ir.exe” executable.

Connecting to the iTunes COM object

Since this functionality is going to be used by all the scripts, I extracted it in a separate file called “iTunesLib.rb” :


module ITunes
  def self.app
    begin
      itunes_type = System::Type.get_type_from_prog_i_d("iTunes.Application")
      itunes = System::Activator.create_instance(itunes_type)
      yield itunes
    rescue Exception => e
      puts e
    end
  end
end

This modules hides all the COM plumbing from the scripts. It uses the standard .NET libraries to interface with COM: For example, by using the System.Activator class. One nice thing IronRuby does is to allow the use of rubyfied names for methods, using undescores. It is still possible to use the original .NET names though.

Prefix to track number

The first script is very simple: All it does is check if the “Song” fields of the tracks currently selected in iTunes begin with a number, and if they do, copy this number to the “Track Number” field: “07 – Hypersurface” will have track number 7.


require "iTunesLib"

ITunes.app do |itunes|
  sels = itunes.selected_tracks

  if sels.nil?
    puts "No selection"
    break
  end

  1.upto(sels.count) do |i|
    track = sels.item(i)
    if track.name =~ /^\s*(\d+)/
      track.track_number = $1.to_i
    end
  end
end

After selecting some tracks with the iTunes interface, the script can be run on the command line like this (no arguments are necessary):

ir.exe prefix_to_track_number.rb

(Note: This really modifies the tracks. No undo is possible…)

Remove n characters from front or back

This script removes an arbitrary number of characters, from the front and/or back of either the “Artist”, “Album” or “Song” field. At the beginning, there are various checks of the arguments, followed by the main code, which loops through the tracks currently selected in iTunes. Update: Added checks for the field inside the loop


require "iTunesLib"

if ARGV.length <= 1
  puts "Usage: #{__FILE__} [a|l|n] [<f or b> <num chars to remove>]+"
  puts "a => artist, l => album, n => song name"
  exit
end

scope = ARGV.shift
if scope !~ /a|l|n/
  puts "Bad scope"
  exit
end

rff = nil
rfb = nil

ARGV.each_with_index do |a,i|
  if a == "f"
    rff = ARGV[i + 1].to_i if i < ARGV.length - 1
  elsif a == "b"
    rfb = ARGV[i + 1].to_i if i < ARGV.length - 1
  end
end

if rff.nil? and rfb.nil?
  puts "Nothing to do"
  exit
end

ITunes.app do |itunes|
  sels = itunes.selected_tracks

  if sels.nil?
    puts "No selection"
    break
  end

  1.upto(sels.count) do |i|
    track = sels.item(i)

    if scope == "n"
      name = track.name
    elsif scope == "l"
      name = track.album
    else
      name = track.artist
    end

    if !rff.nil?
      #name is an immutable .NET string
      name = name.slice(rff..-1)
    end

    if !rfb.nil?
      name = name.slice(0..-(rfb+1))
    end

    if scope == "n"
      track.name = name
    elsif scope == "l"
      track.album = name
    else
      track.artist = name
    end
  end
end

One of the only gotchas I encountered with IronRuby had to do with the fact that .NET strings are immutable. But in Ruby, strings are mutable and there are methods ending with “!” (such as “slice!”) that can be used to modify the current String instance instead of returning a new one. Those methods cannot be used on .NET/CLR strings (that are returned by the methods of .NET objects). This is why I used “name = name.slice” instead of something like “name.slice!” in the code above. I later learned that the “to_s” method could have been used on a .NET string to obtain a Ruby string.

After selecting some tracks with the iTunes interface, the script can be run on the command line like this:

ir.exe remove_n_characters_from_front_or_back.rb n f 5

(“n” means the “Song” field; “f” means the front of the field; “5” the number of characters to remove)

Using the previous song name example: “07 – Hypersurface” will become “Hypersurface”.

Bonus

You have read the complete article! Here is a great track as a reward:

Dopplereffekt – Z-Boson (from “Linear Accelerator“)