You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MicroDexed/addon/tools/wav2c.sh

252 lines
6.2 KiB

#!/bin/bash
#
# Converter for WAV to C Header
# Used for MicroDexed sampler
#
# (c) 2021 Holger Wirtz
#
SOX=`which sox`
XXD=`which xxd`
TMP="/tmp/wav2c"
AUDIO_BLOCK_SIZE=128
DRUMSET_H="drumset.h"
DRUMS_H="drums.h"
function cleanexit()
{
#rm -rf "${TMP}"
echo -n ""
}
trap cleanexit EXIT
if [ -z "${SOX}" ]
then
echo "Cannot find 'sox' in your PATH." >&2
exit 100
fi
if [ -z "${XXD}" ]
then
echo "Cannot find 'xxd' in your PATH." >&2
exit 101
fi
POSITIONAL=()
while [[ $# -gt 0 ]]; do
key="$1"
case $key in
-c|--config)
CONFIG="$2"
shift # past argument
shift # past value
;;
-w|--wavs)
WAV_DIR="$2"
shift # past argument
shift # past value
;;
# -t|--test)
# TEST="true"
# shift # past argument
# ;;
*) # unknown option
POSITIONAL+=("$1") # save it in an array for later
shift # past argument
;;
esac
done
if [ ! -f "${CONFIG}" ]
then
echo "Cannot find configuration file." >&2
exit 200
fi
if [ ! -d "${WAV_DIR}" ]
then
echo "Cannot find folder for WAV files." >&2
exit 201
fi
if (( `ls "${WAV_DIR}" | wc -l` == 0 ))
then
echo "Cannot find any file in ${WAV_DIR}." >&2
exit 202
fi
mkdir -p "${TMP}"
rm -f "${DRUMSET_H}"
touch drumset.h
rm -f "${DRUMS_H}"
cat >> "${DRUMS_H}" << EOF
/*
MicroDexed
MicroDexed is a port of the Dexed sound engine
Dexed ist heavily based on https://github.com/google/music-synthesizer-for-an
droid
(c)2018-2021 H. Wirtz <wirtz@parasitstudio.de>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
THE SOFTWARE.
*/
#include <Arduino.h>
#include "config.h"
#include "drumset.h"
#ifndef _DRUMS_H
#define _DRUMS_H
typedef struct drum_config_s {
uint8_t drum_class; // Type of drum
uint8_t midinote; // Triggered by note
char name[DRUM_NAME_LEN];
const unsigned int* drum_data;
char shortname[2]; // 1 char name for sequencer
uint32_t len; // number of elements in drum_data
float32_t pitch; //
float32_t pan; // Panorama (-1.0 - +1.0)
float32_t vol_max; // max. Volume (0.0 - 1.0)
float32_t vol_min; // min. Volume (0.0 - 1.0, should be <= vol_max)
float32_t reverb_send; // how much signal to send to the reverb (0.0 - 1.0)
} drum_config_t;
enum {DRUM_NONE, DRUM_BASS, DRUM_SNARE, DRUM_HIHAT, DRUM_HANDCLAP, DRUM_RIDE, DRUM_CHRASH, DRUM_LOWTOM, DRUM_MIDTOM, DRUM_HIGHTOM, DRUM_PERCUSSION};
// DEFAULT MIDI CHANNEL FOR SAMPLEDRUMS
uint8_t drum_midi_channel = 10;
drum_config_t drum_config[NUM_DRUMSET_CONFIG] =
{
EOF
declare -A converted_files
while IFS= read -r l
do
declare -A sample
if [[ "${l:0:1}" == "#" ]]
then
continue
fi
IFS=',' read -ra samplecfg <<< "${l}"
3 years ago
sample['class']=`echo "${samplecfg[0]}" | xargs`
sample['midinote']=`echo "${samplecfg[1]}" | xargs`
sample['name']=`echo "${samplecfg[2]}" | xargs`
sample['data_name']="${sample['name']}"
3 years ago
sample['shortname']=`echo "${samplecfg[3]}" | xargs`
sample['pitch']=`echo "${samplecfg[4]}" | xargs`
sample['pan']=`echo "${samplecfg[5]}" | xargs`
sample['vol_max']=`echo "${samplecfg[6]}" | xargs`
sample['vol_min']=`echo "${samplecfg[7]}" | xargs`
sample['reverb_send']=`echo "${samplecfg[8]}" | xargs`
sample['filename']=`echo "${samplecfg[9]}" | xargs`
if [ -f "${WAV_DIR}/${sample['filename']}" ]
then
file "${WAV_DIR}/${sample['filename']}" | grep -i -q "WAVE audio"
if [ "${?}" == 0 ]
then
# Generate drumset.h
if [ -z "${converted_files[${sample['filename']}]}" ]
then
basename=`echo "${sample['filename']}" | cut -d'.' -f1`
sox "${WAV_DIR}/${sample['filename']}" -c 1 -b 16 -L "${TMP}/${basename}.raw"
xxd -i "${TMP}/${basename}.raw" > "${TMP}/${basename}.h"
sample['len']=`grep "^unsigned int" "${TMP}/${basename}.h" | cut -d"=" -f2 | sed 's/\s*\([0-9]\+\);/\1/'`
fill_mod=`expr "${sample['len']}" % "${AUDIO_BLOCK_SIZE}"`
fill=`expr "${AUDIO_BLOCK_SIZE}" - "${fill_mod}"`
sample['len']=`expr "${sample['len']}" + "${fill}"`
sample['len']=`expr "${sample['len']}" / 2`
echo "// Converted from ${sample['filename']}, length = ${sample['len']} bytes" >> "${DRUMSET_H}"
echo "PROGMEM const int8_t ${sample['name']}[] = {" >> "${DRUMSET_H}"
grep "^ " "${TMP}/${basename}.h" >> "${DRUMSET_H}"
if (( "${fill}" > 0 ))
then
echo -n "," >> "${DRUMSET_H}"
fill_counter=0
for i in $(seq 1 "${fill}")
do
echo -n "0x00" >> "${DRUMSET_H}"
let fill_counter+=1
if (( "${fill_counter}" >= 8 ))
then
echo "" >> "${DRUMSET_H}"
fill_counter=0
else
echo -n ", " >> "${DRUMSET_H}"
fi
done
fi
echo "};" >> "${DRUMSET_H}"
converted_files["${sample['filename']}"]="${sample['name']},${sample['len']}"
else
sample['data_name']=`echo ${converted_files[${sample['filename']}]} | cut -d"," -f1`
sample['len']=`echo ${converted_files[${sample['filename']}]} | cut -d"," -f2`
fi
# Generate drums.h
cat >> "${DRUMS_H}" << EOF
{
${sample[class]},
${sample[midinote]},
"${sample[name]}",
${sample[data_name]},
"${sample[shortname]}",
${sample[len]},
${sample[pitch]},
${sample[pan]},
${sample[vol_max]},
${sample[vol_min]},
${sample[reverb_send]}
},
EOF
fi
else
echo "File \'${WAV_DIR}/${sample['filename']}\' does not exits." >&2
fi
done < "${CONFIG}"
cat >> "${DRUMS_H}" << EOF
3 years ago
{
DRUM_NONE,
0,
"EMPTY",
NULL,
"-",
0,
0.0,
0.0,
0.0,
0.0,
0.0
}
};
#endif
EOF