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

280 lines
6.8 KiB

#!/bin/bash
#
# Converter for WAV to C Header
# Used for MicroDexed sampler
#
# (C)2021-2022 Holger Wirtz
#
SOX=`which sox`
XXD=`which xxd`
ASTYLE=`which astyle`
TMP="/tmp/wav2c"
AUDIO_BLOCK_SIZE=128
DRUMSET_H="drumset.h"
DRUMS_H="${TMP}/drums.h"
MAX_NUM_DRUMSET_CONFIG=71 # ARDUINO_TEENSY41
#MAX_NUM_DRUMSET_CONFIG=40 # ARDUINO_TEENSY40
#MAX_NUM_DRUMSET_CONFIG=19 # ...
NUM_DRUMSET=0
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
if [ -z "${ASTYLE}" ]
then
echo "Cannot find 'astyle' in your PATH." >&2
exit 102
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=$(echo "$2" | sed 's/\/$//')
shift # past argument
shift # past value
;;
-n|--num)
MAX_NUM_DRUMSET_CONFIG="$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}"
cat >> "${DRUMSET_H}" << EOF
#pragma once
#if NUM_DRUMS > 0
#include <Arduino.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 uint8_t* drum_data;
uint32_t len; // number of elements in drum_data
float32_t pitch; // variable pitch per note
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_CRASH, DRUM_LOWTOM, DRUM_MIDTOM, DRUM_HIGHTOM, DRUM_PERCUSSION};
EOF
rm -f "${DRUMS_H}"
cat >> "${DRUMS_H}" << EOF
PROGMEM const drum_config_t drum_config[NUM_DRUMSET_CONFIG] =
{
EOF
declare -A converted_files
NUM_DRUMSET_CONFIG=1
while IFS= read -r l
do
declare -A sample
if [[ "${l:0:1}" == "#" ]]
then
continue
fi
IFS=',' read -ra samplecfg <<< "${l}"
sample['class']=`echo "${samplecfg[0]}" | xargs`
sample['midinote']=`echo "${samplecfg[1]}" | xargs`
sample['name']=`echo "${samplecfg[2]}" | xargs`
sample['c_name']=`echo "${samplecfg[2]}" | xargs | sed 's/[^a-zA-Z0-9]/_/g'`
sample['c_name']=`echo "DRUM_${sample[c_name]}"`
sample['pitch']=`echo "${samplecfg[3]}" | xargs`
sample['pan']=`echo "${samplecfg[4]}" | xargs`
sample['vol_max']=`echo "${samplecfg[5]}" | xargs`
sample['vol_min']=`echo "${samplecfg[6]}" | xargs`
sample['reverb_send']=`echo "${samplecfg[7]}" | xargs`
sample['filename']=`echo "${samplecfg[8]}" | xargs`
if [ -f "${WAV_DIR}/${sample['filename']}" ]
then
if [ ${NUM_DRUMSET_CONFIG} -gt ${MAX_NUM_DRUMSET_CONFIG} ]
then
echo "/*" >> "${DRUMSET_H}"
fi
file "${WAV_DIR}/${sample['filename']}" | grep -i -q "WAVE audio"
if [ "${?}" == 0 ]
then
# Generate drumset.h
echo "'${WAV_DIR}/${sample['filename']}' -> '${sample['c_name']}'"
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}" -c 8 -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_orig="${sample[len]}"
sample['len']=`expr "${sample['len']}" + "${fill}"`
sample['len']=`expr "${sample['len']}" / 2`
echo >> "${DRUMSET_H}"
echo "// Converted from ${sample['filename']}, length = ${sample['len']} bytes" >> "${DRUMSET_H}"
echo "PROGMEM const uint8_t ${sample['c_name']}[] = {" >> "${DRUMSET_H}"
grep "^ " "${TMP}/${basename}.h" >> "${DRUMSET_H}"
head -c -1 "${DRUMSET_H}" >> "/tmp/${DRUMSET_H}.tmp"
mv "/tmp/${DRUMSET_H}.tmp" "${DRUMSET_H}"
if (( "${fill}" > 0 ))
then
sample_fill_bytes=$(expr ${sample_len_orig} % 8 )
for i in $(seq 1 "${sample_fill_bytes}")
do
echo -n ", 0x00" >> "${DRUMSET_H}"
done
fill=$(expr ${fill} - ${sample_fill_bytes} )
if (( "${fill}" > 0 ))
then
echo "," >> "${DRUMSET_H}"
fill_cols=$(expr ${fill} / 8 )
for i in $(seq 1 "${fill_cols}")
do
echo -n " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00" >> "${DRUMSET_H}"
if (( i < fill_cols ))
then
echo "," >> "${DRUMSET_H}"
fi
done
fi
echo >> "${DRUMSET_H}"
fi
echo "};" >> "${DRUMSET_H}"
NUM_DRUMSET=`expr "${NUM_DRUMSET_CONFIG}" + 1`
converted_files["${sample['filename']}"]="${sample['c_name']},${sample['len']}"
else
sample['c_name']=`echo ${converted_files[${sample['filename']}]} | cut -d"," -f1`
sample['len']=`echo ${converted_files[${sample['filename']}]} | cut -d"," -f2`
fi
# Generate drum_config
if [ ${NUM_DRUMSET_CONFIG} -gt ${MAX_NUM_DRUMSET_CONFIG} ]
then
echo "/*" >> "${DRUMS_H}"
fi
cat >> "${DRUMS_H}" << EOF
{
${sample[class]},
${sample[midinote]},
"${sample[name]}",
${sample[c_name]},
${sample[len]},
${sample[pitch]},
${sample[pan]},
${sample[vol_max]},
${sample[vol_min]},
${sample[reverb_send]}
},
EOF
if [ ${NUM_DRUMSET_CONFIG} -gt ${MAX_NUM_DRUMSET_CONFIG} ]
then
echo "*/" >> "${DRUMS_H}"
echo "*/" >> "${DRUMSET_H}"
fi
NUM_DRUMSET_CONFIG=`expr "${NUM_DRUMSET_CONFIG}" + 1`
else
echo "File ${WAV_DIR}/${sample['filename']} is not a WAV audio file"
fi
else
echo "File \'${WAV_DIR}/${sample['filename']}\' does not exits." >&2
fi
done < "${CONFIG}"
cat >> "${DRUMS_H}" << EOF
{
DRUM_NONE,
0,
"EMPTY",
NULL,
0,
0.0,
0.0,
0.0,
0.0,
0.0
}
};
#endif
EOF
echo "" >> "${DRUMSET_H}"
cat "${DRUMS_H}" >> "${DRUMSET_H}"
"${ASTYLE}" --lineend=linux --style=kr --mode=c "${DRUMSET_H}"
echo ""
echo "Created drumset.h. Copy the file to the root dicrectory of MicroDexed and don't"
echo "forget to edit config.h and change the following line to the right number:"
echo ""
echo " #define NUM_DRUMSET_CONFIG ${NUM_DRUMSET_CONFIG}"
echo ""