% Step Sequencer Drum Machine - ECE 4760 Final Project Cornell University
% WAV to C conversion script
% Dan Felicetta & Arun Swain
% 5/2/2011

% Converts all the .wav files in a directory to C data structures
% Files must have 44 kHz or 22 kHz sampling rate
% 44 kHz files are downsampled to 22 kHz
directory = input('Directory: ', 's');
output_filename = input('Output Filename: ', 's');
max_value = input('Max Value: ');

total_bytes_written = 0;

output_file = fopen(output_filename, 'w');

try
    fnames = dir([directory '\*.wav']);
    num_files = length(fnames);
    sample_lens = zeros(num_files);

    % define for the total number of sounds
    fprintf(output_file, '#define NUM_SAMPLES %i\n', num_files);
    
    for i=1:num_files
        [y,fs,nbits] = wavread([directory  '\' fnames(i).name]);
        
        % check the sampling rate and decimate if necessary
        if floor(fs/1000) == 44
            y = decimate(y, 2);
        elseif floor(fs/1000) ~= 22
            err = MException('WavConv:BadRate', '%s does not have a valid sampling rate.', fnames(i).name);
            throw(err);
        end
        
        sample_lens(i) = length(y);
        %conv_y = floor(.5*max_value*y); % range conversion
        conv_y = floor(.5*max_value*(y+1));
        
        % ramp it
        ramp_len = floor(.1*length(conv_y));
        up_ramp = [];
        for h=1:ramp_len+1 up_ramp(h) = (h-1)/ramp_len; end
        ramp = [up_ramp ones(1, length(conv_y)-2*ramp_len-2) fliplr(up_ramp)]';
        conv_y = floor(conv_y .* ramp);
        
        [path,name,ext,v] = fileparts(fnames(i).name);

        fprintf(output_file, '//Sound %i - %s\n', i, name);
        
        % LCD display string - filename minus extension
        fprintf(output_file, 'const uint8_t sample_text_%i[] PROGMEM = "%s\\0";\n', i, name);
        total_bytes_written = total_bytes_written + length(name) + 1; 
        
        % sample array
        fprintf(output_file, 'unsigned char sample_%i[%i] PROGMEM = {', i, length(y));
        for j=1:length(conv_y)
            total_bytes_written = total_bytes_written + 1;
            if (j < length(conv_y))
                fprintf(output_file, '%i, ', conv_y(j));
                if (mod(j, 30) == 0) fprintf(output_file, '\n');
                end
            else
                fprintf(output_file, '%i};\n', conv_y(j));
            end
        end
    end
    
    % pointers to each sample array
    fprintf(output_file, '//Sample array\n');
    fprintf(output_file, 'unsigned char * sample[%i] = {', num_files);
    for i=1:num_files
        if (i < num_files)
            fprintf(output_file, 'sample_%i, ', i);
        else
            fprintf(output_file, 'sample_%i};\n', i);
        end
    end
    
    % pointers to LCD display text
    fprintf(output_file, '//Sample text\n');
    fprintf(output_file, 'const uint8_t * sample_text[%i] = {', num_files);
    for i=1:num_files
        if (i < num_files)
            fprintf(output_file, 'sample_text_%i, ', i);
        else
            fprintf(output_file, 'sample_text_%i};\n', i);
        end
    end
    
    % sample lengths
    fprintf(output_file, '//Sample lengths\n');
    fprintf(output_file, 'unsigned int sample_len[%i] = {', num_files);
    for i=1:num_files
        if (i < num_files)
            fprintf(output_file, '%i, ', sample_lens(i));
        else
            fprintf(output_file, '%i};', sample_lens(i));
        end
    end
    
    total_bytes_written = total_bytes_written + 4*num_files

    fclose(output_file);
catch e
    fclose(output_file);
    delete(output_filename);
    rethrow(e);
end