Sunday, December 16, 2018

Change the tempo of your audio track with WaveShop

If you ever want to edit audio on Windows, the free GPL-licensed WaveShop would come up top on the list.

However, if you are trying to edit the tempo of your audio track using WaveShop, you would quickly notice that there is no such option (effect or plugin).

But it is possible (at least for MP3s) in a somewhat obscure way: changing the sampling rate.

I'm not an expert on acoustics, music or MP3; but a quick googling shows that the sampling rate is the number of samples of audio carried per second.

Thus, if you reduce your sampling rate to 80% (say 44100Hz → 35280Hz), it would make your MP3 player think that the samples in your file were taken at 28.34-microsecond intervals instead of 22.67 - a 25% "stretch".

So your track will actually play 20% slower, taking 2 min 5 sec if it was originally 1 min 40 sec. Exactly what we need!

To use WaveShop to change your audio track's tempo in this manner:

  • open your track in WaveShop.
  • go to Audio → Format....
  • based on the tempo change you need (say x%), enter the correct Sample Rate value; note that if you want to slow down, x would be negative!

current sampling rate × (x/100 + 1)

  • click OK.

SEO: Add meta descriptions to your AsciiBinder-powered website

Despite the importance of meta descriptions, AsciiBinder native distribution does not add meta description tags to your output web pages.

However, AsciiDoctor (which AsciiBinder uses internally) does return meta tag content as attributes in its parse output.

Patch AsciiBinder to propagate meta descriptions to your template

Apply the following patch on ASCII_BINDER_HOME/lib/ascii_binder/engine.rb to propagate these meta values into the output rendering logic:

--- /var/lib/gems/2.3.0/gems/ascii_binder-0.1.15.1/lib/ascii_binder/engine.rb
+++ /var/lib/gems/2.3.0/gems/ascii_binder-0.1.15.1/lib/ascii_binder/engine.rb
@@ -516,6 +516,13 @@
         :repo_path         => topic.repo_path,
       }

+      description = doc.attr 'description'
+      if description and description.length > 0
+          page_args['description'] = description
+      else
+          log_warn("!!! #{topic.repo_path} has no meta description!")
+      end
       full_file_text = page(page_args)
       File.write(preview_path,full_file_text)
     end

Quick 'n' dirty way to locate engine.rb

An easy way to locate engine.rb is to introduce a syntax error; just type an extra character somewhere in the middle of one of the templating (.erb) scripts in your source project. Now when you run the build, AsciiBinder will print out an error stacktrace containing the locations of each file that it tried to invoke.

...
/var/lib/gems/2.3.0/gems/tilt-2.0.8/lib/tilt/template.rb:274:in `class_eval': /mnt/c/Users/janaka/code/website/_templates/page.html.erb:2: syntax error, unexpected '\n', expecting => (SyntaxError)
...                               ^
        from /var/lib/gems/2.3.0/gems/tilt-2.0.8/lib/tilt/template.rb:274:in `compile_template_method'
...
        from /var/lib/gems/2.3.0/gems/tilt-2.0.8/lib/tilt/template.rb:109:in `render'
        from /var/lib/gems/2.3.0/gems/ascii_binder-0.1.15.1/lib/ascii_binder/template_renderer.rb:20:in `render'
        from /var/lib/gems/2.3.0/gems/ascii_binder-0.1.15.1/lib/ascii_binder/engine.rb:198:in `page'
        from /var/lib/gems/2.3.0/gems/ascii_binder-0.1.15.1/lib/ascii_binder/engine.rb:526:in `configure_and_generate_page'
...
        from /usr/local/bin/asciibinder:23:in `<main>'

The line numbers may differ based on your platform and AsciiBinder version, in which case you would need to manually add the above lines to your AsciiBinder engine.rb; right before the line full_file_text = page(page_args).

Update your template with the meta description text

On the source docs repository, pass-through the received meta content into the template file; e.g. for _templates/page.html.erb:

<%= render(("_templates/_page_custom.html.erb"),
           :distro_key => distro_key,
...
           :description => defined?(description).nil? ? [topic_title, subgroup_title, group_title].compact.join(': ') : description,
...

And use it in your template (_page_custom.html.erb):

...
    <meta charset="utf-8">
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="width=device-width, initial-scale=1.0" name="viewport">
    <meta content="<%= description %>" name="description">
...

Bonus: a warning to never forget your custom meta descriptions in AsciiBinder

If the meta description is missing, the above would default it to a concatenation of the section, subsection and topic names; however it is highly recommended to provide a good meta description via the :description: tag on each AsciiDoc source file.

With the above patch, AsciiBinder will print a warning for each file that does not have a custom meta description:

...
INFO:   - overview/terminology.adoc
WARN: !!! overview/terminology.adoc has no meta description!
INFO:   - overview/faq.adoc
WARN: !!! overview/faq.adoc has no meta description!
...

Feel free to modify the above patch to process any other desired meta tags as well, such as keywords.