#!/usr/bin/ruby

require 'wavefile'

class SampleEncoder
  attr_accessor :filename

  def initialize(params)
    self.filename = params[0]
  end

  def usage
    puts <<-EOS

  Usage:

    #{$0} <filename>

  Where <filename> is a path to a valid WAV format file

    EOS
  end

  def generate!
    if reader
      print_encoded_structure
    else
      usage
    end
  rescue => e
    log e.message
    usage
  end

  def reader
    @reader ||= WaveFile::Reader.new(filename)
  end

  def target_format
    @target_format ||= WaveFile::Format.new(:mono, :pcm_8, 8000)
  end

  def playing_time(duration)
    duration.hours.to_s.rjust(2, "0") << ":" <<
    duration.minutes.to_s.rjust(2, "0") << ":" <<
    duration.seconds.to_s.rjust(2, "0") << "." <<
    duration.milliseconds.to_s.rjust(3, "0")
  end

  def print_header
    puts <<-EOS
#pragma once

/*
  SAMPLE DATA
  generated by : sample_generator.rb
  Source file  : #{filename}
  Format       : #{reader.native_format.audio_format}
  Channels     : #{reader.native_format.channels}
  Bits/sample  : #{reader.native_format.bits_per_sample}
  Sample rate  : #{reader.native_format.sample_rate}
  Byte rate    : #{reader.native_format.byte_rate}
  Frame count  : #{reader.total_sample_frames}
  Playing time : #{playing_time(reader.total_duration)}
*/
    EOS
  end

  def print_encoded_structure
    print_header
    print_samples
  end

  def print_samples
    puts "const unsigned char sample[] PROGMEM = {"
    reader.each_buffer do |buffer|
      converted_buffer = buffer.convert(target_format)
      converted_buffer.samples.each do |value|
        puts "    #{sprintf("0x%X", value)}, // #{value}"
      end
    end
    puts "};"
  end

  def log(message)
    STDERR.puts message
  end

end

SampleEncoder.new(ARGV).generate!
