VOGONS

Common searches


First post, by Akuma

User metadata
Rank Member
Rank
Member

BIN/CUE to ISO/CUE converter v1.09, supports : FLAC,MP3,OGG,OPUS
Copyright (c) 2020 by Akuma under GNU General Public License 2.0

Features:
*Converts BIN/CUE to ISO/WAV
*Encodes WAV to FLAC,MP3,OGG,OPUS
*Parallel Encoding (credit krcroft)
*Presets and presetfiles
*Writes a new CUE sheet
*Skips existing files
*Dependency checks

Step 1. The script will first use bchunk to convert BIN/CUE to
ISO/WAV. Files will be placed in a newly created folder with the
basename of the CUE file. So for /my/games/mygame.cue it will be
placed in: /my/games/mygame.

The bchunk process is logged to:
/my/games/mygame/bchunk.log

Step 2. Then it encodes all WAV files with the preset to:
/my/games/mygame/[preset]/trackXX.[codec] (XX=02-99)

The encoding process is logged to:
/my/games/mygame/[preset]/trackXX.log

Step 3. A CUE sheet is created for the new files and is
written to the [preset] folder: /my/games/mygame/[preset]/cdrom.cue

Step 4. A batch file is created to use with DOSBox
written to the [preset] folder: /my/games/mygame/[preset]/cdrom.bat

Usage

Usage:
usage: dbx-conv [-f] [-s] <cue/cdrom> <preset/file> [options]

eg:
dbx-conv myfile.cue ogg (default preset)
dbx-conv myfile.cue opus_music_simple_mono (advanced preset)
dbx-conv myfile.cue myfile.preset (preset file)
dbx-conv myfile.cue mp3 -b 192 (custom mp3)

(optional)
* -f : force overwrite
(optional) binchunker:
* -s : swap byte order in audio tracks

codecs/default presets:
* flac
* mp3
* ogg
* opus

advanced presets: (mp3/ogg/opus)
* <codec>_music_simple_mono
* <codec>_music_simple_stereo
* <codec>_music_moderate_mono
* <codec>_music_moderate_stereo
* <codec>_music_complex_mono
* <codec>_music_complex_stereo
* <codec>_speech_simple_mono
* <codec>_speech_simple_stereo
* <codec>_speech_moderate_mono
* <codec>_speech_moderate_stereo
* <codec>_speech_complex_mono
* <codec>_speech_complex_stereo
* <codec>_filler_simple_mono
* <codec>_filler_simple_stereo
* <codec>_filler_moderate_mono
* <codec>_filler_moderate_stereo
* <codec>_filler_complex_mono
* <codec>_filler_complex_stereo

available presets: (flac)
* flac_max

options:
* codec options passthrough
(see codec manpage/manual)

View: Code
#!/bin/bash

# BIN/CUE to ISO/CUE converter v$version, supports : FLAC,MP3,OGG,OPUS"
# Copyright (c) 2020 by Akuma under GNU General Public License 2.0"


#[spdx-license-identifier]-----------------------------------------------------
# GPL-2.0-only @ https://spdx.org/licenses/GPL-2.0-only.html

#[dependencies]----------------------------------------------------------------
# bchunk cdrdao flac lame opus-tools vorbis-tools
#
# *BinChunker (CUE/WAV) http://he.fi/bchunk/
# *CdrDao (CUE/BIN) http://cdrdao.sourceforge.net/
# *Free Lossless Audio Codec (FLAC) https://xiph.org/flac/
# *The LAME Project Codec (MP3) https://lame.sourceforge.io/
# *The Ogg container Codec (OGG) https://xiph.org/ogg/
# *Opus Interactive Audio Codec (OPUS) https://opus-codec.org/
#

#[versioning]------------------------------------------------------------------
version=1.09
self="$(readlink -f "$0")"

#[global settings]-------------------------------------------------------------
set -euo pipefail
OLDIFS=$IFS;IFS=$'\t\r\n' #\r for WIN/DOS cue-files
trap "result" 0 1 3 15

#[functions]-------------------------------------------------------------------
result(){
case $? in
0) echo -e "\nSuccess";;
100) usage;;
101) echo "error: '$file' file not found";;
102) echo "error: unknown preset '${preset}'";;
103) echo "error: already in ISO format";;
104) echo "error: no audio tracks found";;
105) echo "error: merge files to a single bin/cue first";;
106) echo "error: '$file' dependency not found";;
107) echo "error: encoding failed, see logs";;
108) echo "error: cdrom.bin/cue already exist";;
109) echo "error: cdrdao failed to image cdrom";;
110) echo "error: toc2cue failed to convert toc-file to cue-file'";;
111) echo "presetfile: error, tracknumber out of range '$track'";;
112) echo -e "presetfile: '$presetfile'\nerror: unknown preset '$preset'";;
esac
echo
IFS=$OLDIFS
}

usage(){ cat <<EOF
usage: dbx-conv [-f] [-s] <cue/cdrom> <preset/file> [options]

eg:
dbx-conv myfile.cue ogg (default preset)
dbx-conv myfile.cue opus_music_simple_mono (advanced preset)
dbx-conv myfile.cue myfile.preset (preset file)
dbx-conv myfile.cue mp3 -b 192 (custom mp3)

Show last 319 lines
(optional)
* -f : force overwrite
(optional) binchunker:
* -s : swap byte order in audio tracks

codecs/default presets:
* flac
* mp3
* ogg
* opus

advanced presets: (mp3/ogg/opus)
* <codec>_music_simple_mono
* <codec>_music_simple_stereo
* <codec>_music_moderate_mono
* <codec>_music_moderate_stereo
* <codec>_music_complex_mono
* <codec>_music_complex_stereo
* <codec>_speech_simple_mono
* <codec>_speech_simple_stereo
* <codec>_speech_moderate_mono
* <codec>_speech_moderate_stereo
* <codec>_speech_complex_mono
* <codec>_speech_complex_stereo
* <codec>_filler_simple_mono
* <codec>_filler_simple_stereo
* <codec>_filler_moderate_mono
* <codec>_filler_moderate_stereo
* <codec>_filler_complex_mono
* <codec>_filler_complex_stereo

available presets: (flac)
* flac_max

options:
* codec options passthrough
(see codec manpage/manual)
EOF
}

checkfile(){ file="$1";[[ -f "$file" ]] || exit 101;}

getbin(){ grep -Po '.*?"\K[^"]+(?=")' "$1";}

checkapp(){ file="$1";command -v "$file" >/dev/null 2>&1 || exit 104;}

dumpcdrom(){
workdir="$PWD"
bin="$workdir/cdrom.bin"
cue="${bin%.*}.cue"
local cdrom="$1" toc="${bin%.*}.toc" log="${bin%.*}.log"

[[ -f "$bin" ]] && exit 108
echo " *Dumping: \"$cdrom\" to BIN/TOC/CUE"
if [[ -f "$bin" && "$overwrite" = "false" ]]; then
checkapp "cdrdao"
[[ "$overwrite" = "true" ]] && echo " ! overwrite enabled"
echo " > ${bin##*/}"
cdrdao read-cd --datafile "$bin" --driver generic-mmc:0x20000\
--device "$cdrom" --read-raw "$toc" >"$log" 2>&1 || exit 109
else
echo " - ${bin##*/} exists"
fi
if [[ -f "$cue" && "$overwrite" = "false" ]]; then
checkapp "toc2cue"
[[ "$overwrite" = "true" ]] && echo " ! overwrite enabled"
echo " > ${cue##*/}"
toc2cue "$toc" "$cue" || exit 110
else
echo " - ${cue##*/} exists"
fi
}

range(){ seq ${1%-*} ${1#*-};}

queue(){
local workdir="$1" outdir="$2" codec="$3"
shift 3
local options=$@
local codec options infile outfile track

for infile in "$workdir"/*.wav;do
outfile="${infile##*/}";outfile="$outdir/${outfile%.*}.$codec"
track="${infile##*/}";track="${track:5:2}"
queue+=([10#$track]="compress \"$infile\" \"$outfile\" $codec $options")
done
}

queue_presetfile(){
local workdir="$1" outdir="$2" presetfile="$3" que="$4"
local codec options infile outfile track tracks saveifs
saveifs=$IFS

total=$(grep -c TRACK "$que")

while read line;do
IFS='=';set -- $line
preset=${1:-}
grep -q "^$preset=" "$presets" || exit 112
codec=${1:-};codec=${codec/_*}
options=${!1:-}
tracks=${2:-}
IFS=$' \t\r\n'
tracks=$(
for track in $tracks
do case $track in
default) range 2-$total;; #fill queue with the default preset
*-*) range $track;; #change preset for range eg: 12-20
[0-9]*) echo $track;; #change preset per track eg: 13
*) exit 130;; #presetfile script error
esac
done
)

for track in $tracks;do
[[ $track -ge 2 && $track -le $total ]] || exit 111
infile=$(printf "$workdir/track%02i.wav" $track)
outfile=$(printf "$outdir/track%02i.$codec" $track)
queue+=([$track]="compress \"$infile\" \"$outfile\" $codec $options")
done
done < <(grep '^[^#].*=' "$presetfile") #grep presets from presetfile
IFS=$saveifs
}

compress(){ #infile outfile codec options
local infile="$1" outfile="$2" codec=$3; shift 3; options=$@
local log="${outfile%.*}.log"
trap "rm \"$outfile\";exit 106" 2
IFS=$' \t\r\n'
case "$codec" in
flac) set flac $options "$infile" -o "$outfile";;
ogg) set oggenc $options "$infile" -o "$outfile";;
opus) set opusenc $options "$infile" "$outfile";;
mp3) set lame $options "$infile" "$outfile";;
esac
IFS=$'\t\r\n'
checkapp $1
echo $@ >"$log"; $@ >>"$log" 2>&1 || exit 112;
}

to_frames(){ set ${1//:/ }; echo $(((60*10#$1+10#$2)*75+10#$3));}

to_time(){\
printf "%02d:%02d:%02d" $(((10#$1/75)/60)) $(((10#$1/75)%60)) $((10#$1%75));}

makecue(){ #cue outdir
local cue="$1" outdir="$2" line file type c zero offset time
IFS=$' \t\r\n'
while read line;do
set $line
case "$1" in
FILE)
unset offset #reset offset on new file
;;
TRACK)
c=$(printf "%02d" $((10#$2)))
for file in "$outdir"/track$c.*;do
case "${file##*.}" in
iso) type=BINARY;;
mp3|ogg|flac|opus) type=${file##*.};type="${type^^}";;
*) unset type zero;; #reset index zero on new track
esac
[[ -n "${type:=}" ]] && {
printf "FILE \"${file##*/}\" $type\n"
printf "${line/MODE*/MODE1\/2048}\n"
}
done
;;
INDEX)
time="00:00:00"
[[ -n "${zero:=}" ]] && {
offset="$(to_frames $3)"
time="$(to_time $((offset-zero)))"
}
[[ $2 -eq 0 ]] && zero="$(to_frames $3)"
printf "${line/??:??:??/$time}\n";;
*)
printf "$line\n"
;;
esac
done < <(cat "$cue")
IFS=$'\t\r\n'
}

#[title]-----------------------------------------------------------------------
echo "BIN/CUE to ISO/CUE converter v$version, supports : FLAC,MP3,OGG,OPUS"
echo "Copyright (c) 2020 by Akuma under GNU General Public License 2.0"
echo

#[codec presets]---------------------------------------------------------------
presets="${self%.*}.presets"
checkfile "$presets"
source "$presets"

#[commandline arguments]-------------------------------------------------------
#usage: self [-f] [-s] cue-file preset/presetfile/codec [codec-options]

#options
byteswap=""
overwrite=false
while :; do
case ${1:-} in
-f) overwrite="true";; #set overwrite flag
-s) byteswap="-s";; #bchunk: swap byteorder in audiotracks
*) break;;
esac
shift
done

#2+ arguments remaining else show usage
[[ $# -ge 2 ]] || exit 100

#if cdrom then create bin/cue and set cue
if [[ -b "$1" ]]; then
dumpcdrom
else
cue="$(readlink -f "$1")"
fi

#check cue-file
checkfile "$cue"
grep -q 'MODE2/2048' "$cue" && exit 103
grep -q 'TRACK.*AUDIO' "$cue" || exit 104
[[ $(grep -c 'FILE' "$cue") -eq 1 ]] || exit 105

bin="${cue%/*}/$(getbin $cue)"
checkfile "$bin"
shift

#[workdir]---------------------------------------------------------------------
workdir="${cue%.*}"
[[ -d "$workdir" ]] || mkdir -p "$workdir"

#[queue]-----------------------------------------------------------------------
case $# in
0) exit 100
;;
1) if [[ -f "$1" ]]; then
presetfile="$(readlink -f $1)"
checkfile "$presetfile"
outdir="$workdir/presetfile"
queue_presetfile "$workdir" "$outdir" "$presetfile" "$cue"
encoding="${presetfile##*/}"
else
preset="${1,,}"
grep -q "^$preset=" "$presets" || exit 102
outdir="$workdir/$preset"
codec="${preset/_*}"
options="${!preset}"
queue "$workdir" "$outdir" "$codec" "$options"
encoding="$preset"
fi
;;
*) outdir="$workdir/custom"
queue "$workdir" "$outdir" $@
encoding="CUSTOM: $@"
;;
esac
[[ -d "$outdir" ]] || mkdir -p "$outdir"
set --

#[conversion]------------------------------------------------------------------
cd "$workdir"
echo " *Converting BIN/CUE to ISO/WAV"
outfile="$workdir/track01.iso"
if [[ -f "$outfile" ]]; then
echo " - ${outfile##*/} exists"
else
echo " > ${outfile##*/}"
checkapp bchunk
[[ -n "${byteswap:-}" ]] && echo " > swapping byte order in audio tracks"
bchunk $byteswap -w "$bin" "$cue" track >> "bchunk.log" 2>&1
fi
symlink="$outdir/${outfile##*/}"
[[ -h "$symlink" ]] || ln -s "../${outfile##*/}" "$symlink" >/dev/null 2>&1
[[ -f "${outfile%.*}.ugh" ]] && mv "${outfile%.*}.ugh" "${outfile}"

#[encoding]--------------------------------------------------------------------
echo " *Encoding WAV with: \"$encoding\""
[[ -d "$outdir" ]] || mkdir -p "$outdir"
[[ "$overwrite" = "true" ]] && echo " ! overwrite enabled"
nproc="$(nproc)"
for command in "${!queue[@]}"; do
IFS='"';set -- ${queue[$command]}
outfile="$4";IFS=$' \t\r\n'
if [[ -f "$outfile" && "$overwrite" = "false" ]]; then
echo " - ${outfile##*/} exists";continue
else
echo " > ${outfile##*/}"
( set -e; eval ${queue[$command]} ) &
[[ $? -eq 0 ]] || exit 107
while [[ "$(jobs -p | wc -l)" -gt "$nproc" ]]; do sleep 0.3; done
fi
done

#[cuesheet]--------------------------------------------------------------------
echo " *Writing CUE sheet"
outfile="$outdir/cdrom.cue"
[[ -f "$outfile" ]] && rm "$outfile"

if [[ -f "$outfile" ]]; then
echo " - ${outfile##*/} exists"
else
echo " > ${outfile##*/}"
makecue "$cue" "$outdir" >"$outfile"
fi

#[cdrom.bat]-------------------------------------------------------------------
echo " *Writing BAT file"
outfile="$outdir/cdrom.bat"
if [[ -f "$outfile" ]]; then
echo " - ${outfile##*/} exists"
else
echo " > ${outfile##*/}"
echo imgmount d -t cdrom cdrom.cue >"$outfile"
fi

exit 0
View: Presets (credit krcroft)
# BIN/CUE to ISO/CUE converter v$version, supports : FLAC,MP3,OGG,OPUS
# Copyright (c) 2020 by Akuma & krcroft under GNU General Public License 2.0

# This preset file can be customized to your needs

#FLAC: (flac 1.3.3-1 libflac8 1.3.3-1)
# flac <preset> "$infile" -o "$outfile"
flac="-8 -b 512 -P=4096 -S=1s"
flac_max="-8 -e -p -b 512 -P=4096 -S=1s"

#OGG: (vorbis-tools 1.4.0-11, libogg0 1.3.4-0)
# oggenc <preset> "$infile" -o "$outfile"
ogg=""
ogg_speech_simple_mono="--advanced-encode-option lowpass_frequency=13000 --bitrate 44 --downmix"
ogg_speech_moderate_mono="--advanced-encode-option lowpass_frequency=14000 --bitrate 50 --downmix"
ogg_speech_complex_mono="--advanced-encode-option lowpass_frequency=16000 --bitrate 52 --downmix"
ogg_speech_simple_stereo="--advanced-encode-option lowpass_frequency=13000 --bitrate 50"
ogg_speech_moderate_stereo="--advanced-encode-option lowpass_frequency=14000 --bitrate 56"
ogg_speech_complex_stereo="--advanced-encode-option lowpass_frequency=16000 --quality 1.4"
ogg_music_simple_mono="--quality 2.2 --downmix"
ogg_music_moderate_mono="--quality 2.3 --downmix"
ogg_music_complex_mono="--quality 2.5 --downmix"
ogg_music_simple_stereo="--quality 3.5"
ogg_music_moderate_stereo="--quality 4.3"
ogg_music_complex_stereo="--quality 5.0"
ogg_filler_simple_mono="--quality -1 --resample 512 --downmix"
ogg_filler_moderate_mono="--quality -1 --resample 512 --downmix"
ogg_filler_complex_mono="--quality -1 --resample 512 --downmix"
ogg_filler_simple_stereo="--quality -1 --resample 512 --downmix"
ogg_filler_moderate_stereo="--quality -1 --resample 512 --downmix"
ogg_filler_complex_stereo="--quality -1 --resample 512 --downmix"

#Opus: (opus-tools 0.1.10-1 libopus0 1.3.1-0)
# opusenc <preset> "$infile" "$outfile"
opus=""
opus_speech_simple_mono="--bitrate 24 --downmix-mono"
opus_speech_moderate_mono="--bitrate 28 --downmix-mono"
opus_speech_complex_mono="--bitrate 36 --downmix-mono"
opus_speech_simple_stereo="--bitrate 32"
opus_speech_moderate_stereo="--bitrate 36"
opus_speech_complex_stereo="--bitrate 40"
opus_music_simple_mono="--bitrate 50 --downmix-mono"
opus_music_moderate_mono="--bitrate 56 --downmix-mono"
opus_music_complex_mono="--bitrate 72 --downmix-mono"
opus_music_simple_stereo="--bitrate 72"
opus_music_moderate_stereo="--bitrate 84"
opus_music_complex_stereo="--bitrate 96"
opus_filler_simple_mono="--bitrate 1 --downmix-mono"
opus_filler_moderate_mono="--bitrate 1 --downmix-mono"
opus_filler_complex_mono="--bitrate 1 --downmix-mono"
opus_filler_simple_stereo="--bitrate 1 --downmix-mono"
opus_filler_moderate_stereo="--bitrate 1 --downmix-mono"
opus_filler_complex_stereo="--bitrate 1 --downmix-mono"

#Mp3: (lame 3.100-3 libmp3lame0 3.100-3)
# lame <preset> "$infile" "$outfile"
mp3="-q0 -b4 -T"
mp3_speech_simple_mono="-V7.0 --lowpass 13000 -mm -q0 -b4 -T"
mp3_speech_moderate_mono="-V6.5 --lowpass 14000 -mm -q0 -b4 -T"
mp3_speech_complex_mono="-V6.3 --lowpass 15000 -mm -q0 -b4 -T"
Show last 16 lines
mp3_speech_simple_stereo="-V6.0 --lowpass 13000 -q0 -b4 -T"
mp3_speech_moderate_stereo="-V5.7 --lowpass 15000 -q0 -b4 -T"
mp3_speech_complex_stereo="-V5.5 --lowpass 16000 -q0 -b4 -T"
mp3_music_simple_mono="-V6.0 -mm -q0 -b4 -T"
mp3_music_moderate_mono="-V5.5 -mm -q0 -b4 -T"
mp3_music_complex_mono="-V5.0 -mm -q0 -b4 -T"
mp3_music_simple_stereo="-V4.5 -q0 -b4 -T"
mp3_music_moderate_stereo="-V3.5 -q0 -b4 -T"
mp3_music_complex_stereo="-V2.5 -q0 -b4 -T"
mp3_filler_simple_mono="-mm -q0 -b4 -T"
mp3_filler_moderate_mono="-mm -q0 -b4 -T"
mp3_filler_complex_mono="-mm -q0 -b4 -T"
mp3_filler_simple_stereo="-mm -q0 -b4 -T"
mp3_filler_moderate_stereo="-mm -q0 -b4 -T"
mp3_filler_complex_stereo="-mm -q0 -b4 -T"
View : Cdrom/track Specific Example
# PRESET: example file
#
# comment with #
# empty lines allowed
# preset=tracknumbers

# set default for all files
opus_music_moderate_stereo=default

# set ranges
mp3_speech_simple_mono=19-61

# set individual files
ogg_music_moderate_mono=21
opus_music_complex_stereo=20 23 27

History:
2020-11-02 1.09 Completely rewritten
2020-10-27 1.08 Added presets file *not released*
2020-10-25 1.07 Implemented parallel encoding + bugfixes
2020-10-22 1.06 First public release version

Changelog

Changelog:
1.09 Fixed: Completely rewritten (to use a queue)
Added: cdrdao support *buggy*
Added: cdrom.preset file with:
|- multi codec support
|- multi preset support
`- per track support

1.08 Added: presets file, customizable by user
Fixed: commandline options
Added: (suggestions by krcroft)
|- Bash strict-mode
|- Mono option for mono audio to save diskspace
|- Speech option (Jones in the Fast Lane only has voices).
|- variable-bit-rate encodings as a default
`- filler option (unused space at lowest bitrate and in mono)

1.07 Added: (suggestions by krcroft)
|- Bash strict-mode without 'u'
|- Removed unneeded usage text brackets.
|- Options in usage elaborated
|- Renamed 'track.cue' to 'cdrom.cue'
|- Parallel Encoding
|- Double-bracket tests
`- FLAC seekpoints to reduce CPU load
1.06 Fixed: Recalculation defaults to octal instead of decimal
1.05 Added: Index time recalculation
1.04 Added: Parsing CUE sheet instead of generating it
1.03 Added: Set basename to fixed "track" instead of dynamic
1.02 Added: CTRL-C trap and resume
1.01 Added: Codec support for OGG/FLAC/OPUS
1.00 Draft: Initial draft with MP3 and BCHUNK

Dependencies

Dependencies:
*bin/cue to iso/wav : bchunk
*flac encoder : flac
*mp3 encoder : lame
*opus encoder : opus-tools
*ogg encoder : vorbis-tools
*cdripper : cdrdao

** It is probably still a bit buggy, so beware **

Attachments

Last edited by Akuma on 2020-11-02, 17:43. Edited 12 times in total.

Reply 1 of 39, by krcroft

User metadata
Rank Oldbie
Rank
Oldbie

Very nice Akuma!

Feedback on 1.06 so far:

  1. Copyright / GPL the source (top-level comment block in the source file; separate from the usage output)
  2. Highly recommend Bash strict-mode:
    #!/bin/bash
    set -euo pipefail
    IFS=$'\n\t'
  3. In the usage text, brackets commonly indicate optional arguments, so only [-s] should be in brackets.
  4. The options aren't described; suggest adding a description for them beneath the "usage:" line. For new users, recommended bitrates or typical ranges would be helpful for each codec.
  5. [-s] could be made more self-describing if it was -byteswap, or -bswap (as an example), however, I haven't come across a single DOS CDDA that required this (and I've subsequently played those tracks on big-endian hardware); so unless there's a strong need for it, this might cause more harm than good.
  6. Suggest placing the WAV tracks in their own wav directory, just like the other codecs (bitrate subdirectory being unecessary)
  7. Also suggest only ripping one copy of the ISO file and not duplicating copies of it into each codec/bitrate directory. Relative paths work to get it on all dosboxes:
    FILE "../../track01.iso" BINARY
    TRACK 01 MODE1/2048
    INDEX 01 00:00:00
    FILE "track02.opus" OPUS
    TRACK 02 AUDIO
    INDEX 01 00:00:00
  8. Suggest naming the generated CUE file "cdrom.cue" instead of "track.cue" (the CUE itself being the umbrella that describes the overall layout of the CDROM).
  9. Suggest passively guiding the user toward standardized (and always-identical) naming conventions. For example, every possible game can be served just fine with a pattern like:

    (single-CDROM)
    gamename/cd/<codec>/cdrom.cue
    (multi-CDROM)
    gamename/cd1/<codec>/cdrom.cue
    gamename/cd2/<codec>/cdrom.cue
    gamename/cd3/<codec>/cdrom.cue
    Or a similar convention (sure; need to watch out for games who have their own "cd{1..n}" data director(ies).. but I personally haven't come across any.)

    With this approach, after doing a handful of games, the users all of sudden will see all of their imgmount lines are identical. These are easy to remember or ameanable to more automation or scripting.

    But if the tool repeats unique names, like making a directory named after the CUE file, you you get stuff like:
    spiderman/my-2nd-cdrip-attempt/spdman/opus/80/track.cue
    And it's almost impossible for the user to remember.
  10. I like the bitrate subdirectory, but it too acts as more uniqueness in the directory pattern. I would suggest always holding a symlink to the latest-generate bitrate's CUE directly in the codec directory (or simply a copy of that file, if on Windows).

    That way users can still have a bunch of different bitrate encodings (maybe to compare them), but their game's startup batch file can just use the latst and greatest imgmount d cd/opus/cdrom.cue -t cdrom without constantly updating the bitrate.
  11. Suggest printing the imgmount for the user after encoding is done. imgmount d cd/flac/cdrom.cue -t cdrom
  12. Suggest offering a mono option, as a surprising number of games only use mono CDDA tracks (yes; codecs /should/ be smart enough to detect it, but forcing mono using their respective flags can give a nice savings).
  13. Suggest offering a speech option (some CDDA are just voices.. ie: Jones in the Fast Lane).
  14. Suggest always prefering variable-bit-rate encodings over fixed, as VBR always provides better bit allocations and higher quality for a given total file size.
  15. Some tracks are actually filler or just wasted space (but need to be there, none the less); so an option for these would be handy too. Basically you switch these to mono and encode at the lowest allowed bitrate or quality setting.
  16. In the readme, would be helpful to point users to where they can get recommended builds for the given codecs. For example, AoTuV-patched Vorbis provide significantly higher quality versus the Xiph baseline encoder, and has been proven through extensive ABX blinded listening tests (https://wiki.hydrogenaud.io/index.php?title=R … nded_Ogg_Vorbis)
  17. Consider pararallelizing the encode; light up those available cores!
    nproc="$(nproc)"
    for track in *.wav; do
    (
    call to bash-compress function ...
    ) &
    # yield once we're filled the queue
    while [[ "$(jobs -p | wc -l)" -gt "$nproc" ]]; do sleep 0.3; done
    done
    wait
  18. Use double-bracket tests, [[ -f filename ]] to avoid spawning sub-shells on every check and instead let bash evaluate them itself (as its own syntax).
  19. In place of the CUE, allow users to point to their physical CDROM drive where the physical disk will be ripped to BIN/CUE pair:
    cdrdao read-cd --datafile cdrom.bin --driver generic-mmc:0x20000 --device /dev/cdrom --read-raw cdrom.toc
    toc2cue cdrom.toc cdrom.cue
  20. (And you've already include metaflac addition of seekpoints after FLAC encoding in the next version)

Sorry; that turned into..well.. quite a bit! Thanks for entertaining (any / some / all) Akuma 😀

Last edited by krcroft on 2020-10-24, 17:10. Edited 1 time in total.

Reply 2 of 39, by Akuma

User metadata
Rank Member
Rank
Member

That's some feed back 😁
Not going to reply now, its late and I might start spewing nonsense.

I found a couple of bugs too, but that was to be expected:

BUGS:
* Doesn't handle spaces in filename or path (despite all my quoting 😒)
* Doesn't handle multifile CUE's yet (bchunk is not having it, but I have a workaround in progress)

Reply 3 of 39, by krcroft

User metadata
Rank Oldbie
Rank
Oldbie

> * Doesn't handle spaces in filename or path (despite all my quoting 😒)

(Just a quick response.. when you add the IFS line in strict mode, it will split variables on \n and \t, so gives you correct space-handling - without any need to escape or excessively quote).

Reply 4 of 39, by Akuma

User metadata
Rank Member
Rank
Member
krcroft wrote on 2020-10-22, 20:15:

> * Doesn't handle spaces in filename or path (despite all my quoting 😒)

(Just a quick response.. when you add the IFS line in strict mode, it will split variables on \n and \t, so gives you correct space-handling - without any need to escape or excessively quote).

That works for the filename but breaks the CUE handling as it only sees one argument 😒
I fixed a couple of other things, now working on fixing the CUE handling.
Maybe bchunk can be made obsolete, the process may not be that complicated to reproduce.

Could you enumerate instead of the bullet list ?, that makes replying easier for me

EDIT: Just curious, can we use a single file and are there any advantages/disadvantages ?

Reply 5 of 39, by krcroft

User metadata
Rank Oldbie
Rank
Oldbie

> Just curious, can we use a single file and are there any advantages/disadvantages ?

Sorry Akuma; can you rephrase? I'm not following regarding single file.

Thanks for the suggest; reformatted my post as a numbered list.

pantercat mentioned: Consider implementing things when you actually need them.

Definitely agree, and I'm only mentioning this to say that of my suggested list, I do use all of them. Happy to dump my CDDA records regarding mono tracks, voice tracks, filler tracks, and so on to help others get the most of their encodings (and save even more space when possible).

Reply 6 of 39, by Akuma

User metadata
Rank Member
Rank
Member
krcroft wrote on 2020-10-24, 17:09:

> Just curious, can we use a single file and are there any advantages/disadvantages ?

Sorry, that was a bit unclear, I meant a single audio file, so 3 files in total: 1. cue 2. iso 3. audio

I will post a new update tomorrow after some testing.

EDIT: Updated to 1.07 in first post

EDIT2: Massive edit 😒 sorry

Regarding your suggestions:

Closed

q: (closed) 1. Copyright / GPL the source
a: I want users to know its GPL2, but we can add something extra 😁

q: (closed) 2. Highly recommend Bash strict-mode:
a: Added: set -eo pipefail (removed 'u' as uninitialized variables are used)
Added: IFS=$'\r\n\t' (\r for WIN/DOS compatibility)

q: (closed) 3. In the usage text, brackets commonly indicate optional arguments
a: Fixed

q: (closed) 4. The options aren't described
a: Fixed

q: (closed) 5. [-s] byteswap could be made more self-describing
a: Fixed

q: (closed) 7. one copy of the ISO file and not duplicating
a: Is a symlink not a copy.

q: (closed) 8. Suggest naming the generated CUE file "cdrom.cue"
a: Fixed

q: (closed) 9. Suggest passively guiding the user toward standardized
a: Can't need destination folder to reflect cue-filename

q: (closed) 10. Bitrate uniqueness in the directory pattern...
a: Folder containing cdrom.cue should be copied out

q: (closed) 17. Consider pararallelizing the encode
a: Added

q: (closed) 18. Use double-bracket tests, [[ -f filename ]]
a: Fixed

q: (closed) 20. FLAC seekpoints to reduce CPU load in DOSBox
a: Added

Open
q: (open__)) 6. Suggest placing the WAV tracks in their own wav directory
a:

q: (open__) 11. Suggest printing the imgmount for the user after encoding.
a: I think a batch file would be better: cdrom.bat ?

q: (open__) 12. Mono option for mono audio to save diskspace

q: (open__) 13. Speech option (Jones in the Fast Lane only has voices).

q: (open__) 14. variable-bit-rate encodings as a default

q: (open__) 15. Filler option (unused space at lowest bitrate and in mono)

q: (open__) 16. Recommended builds for codecs
a: imo use the ones from the repo for now.

q: (open__) 19. Support for CDRDAO
a:

Last edited by Akuma on 2020-10-25, 12:19. Edited 4 times in total.

Reply 7 of 39, by pantercat

User metadata
Rank Newbie
Rank
Newbie

I've used my script to convert many many BIN/CUEs, so I've come across a few edge cases. Maybe that's useful to you.

For example, Pinball Dreams II (echo ZVhvRE9TIHY0 |base64 -d) and others are really ISO/CUE. If you don't control it, the script will fail because bchunk writes the data track to whatever.ugh instead of whatever.iso.

I've fixed it by looking at the whatever.bin magic-bytes and acting accordingly.

/usr/bin/file "$BIN_FILE" |grep "ISO 9660" [...]

Also consider making optional as much options as you can. For example, you could define some default value for bitrate, while still allowing users to change it if they wish.

My 2cents. 😀

Last edited by pantercat on 2020-10-25, 14:26. Edited 1 time in total.

Reply 8 of 39, by Akuma

User metadata
Rank Member
Rank
Member
pantercat wrote on 2020-10-24, 23:43:
I've used my script to convert many many BIN/CUEs, so I've come across a few edge cases. Maybe that's useful to you. […]
Show full quote

I've used my script to convert many many BIN/CUEs, so I've come across a few edge cases. Maybe that's useful to you.

For example, Pinball Dreams II (eXoDOS v4) and others are really ISO/CUE. If you don't control it, the script will fail because bchunk writes the data track to whatever.ugh instead of whatever.iso.

I've fixed it by looking at the whatever.bin magic-bytes and acting accordingly.

/usr/bin/file "$BIN_FILE" |grep "ISO 9660" [...]

Also consider making optional as much options as you can. For example, you could define some default value for bitrate, while still allowing users to change it if they wish.

My 2cents. 😀

Yes please, edge cases are welcome.
I think I read out the CUE file 'MODE' to determine if its an ISO or BIN.

EDIT: I did 😁

 grep -q 'MODE2/2048' "$cue" && exit 102 
Last edited by Akuma on 2020-10-25, 10:53. Edited 2 times in total.

Reply 10 of 39, by pantercat

User metadata
Rank Newbie
Rank
Newbie
Akuma wrote on 2020-10-25, 10:50:
Yes please, edge cases are welcome. I think I read out the CUE file 'MODE' to determine if its an ISO or BIN. […]
Show full quote

Yes please, edge cases are welcome.
I think I read out the CUE file 'MODE' to determine if its an ISO or BIN.

EDIT: I did 😁

 grep -q 'MODE2/2048' "$cue" && exit 102 

Well, I'm afraid it's not enough. 🙁

Pinball Dreams II (echo ZVhvRE9TIHY0 |base64 -d) has this CUE:

FILE "PDdlx.bin" BINARY
TRACK 01 MODE1/2048
INDEX 01 00:00:00
TRACK 02 AUDIO
[...]

PDdlx.bin is an ISO-9660. v1.07 (bchunk) generates track01.ugh (ISO-9660). You should "mv track01.ugh track01.iso"

Another bug (please don't kill me 😉)-> Pinball Illusions (echo ZVhvRE9TIHY0 |base64 -d) -> ./dbx.sh: line 85: (60*04+09: Value too great for base (error token is "09")

Last edited by pantercat on 2020-10-25, 14:27. Edited 2 times in total.

Reply 11 of 39, by Akuma

User metadata
Rank Member
Rank
Member
pantercat wrote on 2020-10-25, 12:12:
Well, I'm afraid it's not enough. :( […]
Show full quote

Well, I'm afraid it's not enough. 🙁

Pinball Dreams II has this CUE:

FILE "PDdlx.bin" BINARY
TRACK 01 MODE1/2048
INDEX 01 00:00:00
TRACK 02 AUDIO
[...]

PDdlx.bin is an ISO-9660. v1.07 (bchunk) generates track01.ugh (ISO-9660) and no cue. You should "mv track01.ugh track01.iso"

Ohh it does ?, I read it as a hypothetical. I'd better take a look.

pantercat wrote on 2020-10-25, 12:12:

Another bug (please don't kill me 😉)-> Pinball Illusions -> ./dbx.sh: line 85: (60*04+09: Value too great for base (error token is "09")

Yeah, I reverted some changes including this one. IIRC it has to do with defaulting to octal instead of decimal because of the leading zero.

EDIT: Could you try this ?

 to_frames(){ set ${1//:/ }; echo $(((60*10#$1+10#$2)*75+10#$3));}
Last edited by Akuma on 2020-10-26, 12:15. Edited 2 times in total.

Reply 12 of 39, by pantercat

User metadata
Rank Newbie
Rank
Newbie
Akuma wrote on 2020-10-25, 12:30:
EDIT: Could you try this ? […]
Show full quote

EDIT: Could you try this ?

 to_frames(){ set ${1//:/ }; echo $(((60*10#$1+10#$2)*75+10#$3));}

Fixed 😀

Reply 13 of 39, by DosFreak

User metadata
Rank l33t++
Rank
l33t++

For so called "abandonware" (exodos) discussion can you either discuss that elsewhere and/or have the source fix their package? We don't need the search hits coming here for that.

How To Ask Questions The Smart Way
Make your games work offline

Reply 14 of 39, by Akuma

User metadata
Rank Member
Rank
Member
pantercat wrote on 2020-10-25, 12:54:
Akuma wrote on 2020-10-25, 12:30:
EDIT: Could you try this ? […]
Show full quote

EDIT: Could you try this ?

 to_frames(){ set ${1//:/ }; echo $(((60*10#$1+10#$2)*75+10#$3));}

Fixed 😀

Nice, could you remove the references that DosFreak points out. (thanks)

Reply 15 of 39, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie

I would not expect a .bin file containing both data and audio tracks to use mode1/2048. All sectors in a source file should be the same size, so the data track should be mode1/2352 (or mode2/2352, sometimes) to match the audio tracks... Otherwise how do you determine the file offset given by the INDEX for track 2?

Reply 16 of 39, by Akuma

User metadata
Rank Member
Rank
Member
jmarsh wrote on 2020-10-25, 13:38:

I would not expect a .bin file containing both data and audio tracks to use mode1/2048. All sectors in a source file should be the same size, so the data track should be mode1/2352 (or mode2/2352, sometimes) to match the audio tracks... Otherwise how do you determine the file offset given by the INDEX for track 2?

I found a source of the problem being a tool called "iat".
It just converts the BIN to an ISO, without a CUE 😒 , metadata seems to be lost in the conversion.

Iso9660 Analyzer Tool v0.1.3 by Salvatore Santagati
Licensed under GPL v2 or later

I think I will rename the .ugh file, by the looks of it the binchunker author felt the the same way.

Reply 17 of 39, by Akuma

User metadata
Rank Member
Rank
Member
pantercat wrote on 2020-10-25, 12:12:
Well, I'm afraid it's not enough. :( […]
Show full quote
Akuma wrote on 2020-10-25, 10:50:
Yes please, edge cases are welcome. I think I read out the CUE file 'MODE' to determine if its an ISO or BIN. […]
Show full quote

Yes please, edge cases are welcome.
I think I read out the CUE file 'MODE' to determine if its an ISO or BIN.

EDIT: I did 😁

 grep -q 'MODE2/2048' "$cue" && exit 102 

Well, I'm afraid it's not enough. 🙁

Pinball Dreams II (echo ZVhvRE9TIHY0 |base64 -d) has this CUE:

FILE "PDdlx.bin" BINARY
TRACK 01 MODE1/2048
INDEX 01 00:00:00
TRACK 02 AUDIO
[...]

PDdlx.bin is an ISO-9660. v1.07 (bchunk) generates track01.ugh (ISO-9660). You should "mv track01.ugh track01.iso"

Add this line above [encoding] line 133-ish

[[ -f "${outfile%.*}.ugh" ]] && mv "${outfile%.*}.ugh" "${outfile}"

#[encoding]------------------------------------------------

Reply 18 of 39, by krcroft

User metadata
Rank Oldbie
Rank
Oldbie

q: (closed) 1. Copyright / GPL the source
a: I want users to know its GPL2, but we can add something extra 😁

Absolutely; it's just recommended that the source file(s) themselves contain a short GPL banner first-thing.

#  SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2002-2020 Akuma (etc..)

q: (closed) 2. Highly recommend Bash strict-mode:
a: Added: set -eo pipefail (removed 'u' as uninitialized variables are used)
Added: IFS=$'\r\n\t' (\r for WIN/DOS compatibility)

Explicit is better (if you can). For the variables that you absolutely want/need to use uninitialized, you can set a default value:

${varname:-defvalue}

Example

echo ${myundefvar:-hello}

Returns: "hello"

This way, -u will still catch any unexpectedly undefined variables. Handy for stuff like: rm -rf "$myvar/"

q: (open__) 11. Suggest printing the imgmount for the user after encoding.
a: I think a batch file would be better: cdrom.bat ?

Yeah; even more encapsulated, and if you're launching stuff from the DOSBox shell, users can always count on simply running "cdrom" to mount their disk (I'm looking forward to this!).

q: (open__) 16. Recommended builds for codecs
a: imo use the ones from the repo for now.

Not suggesting you install stuff or download anything in the shell-script.

But in the README, you could point users to recommended codec sites, which would be especially useful for Windows users running your script via WSL. Alternatively for Windows users, a separate ZIP pack of best-of-the-best executables would get them up and running right away.

Your script is very nicely timed given pre-Windows 10 bash-scripts weren't readily runnable without mingw / msys* / cygwin / etc.. but WSL + Windows 10 makes this accessible to general users. So I think your script has a good change of seeing wide-spread use.

This brings up another point:

21: Scan for dependent executables (bchunk, flac, ..) and provide a warning if not found, and either quit or optionally block out just that functionality.

Looking forward to 0.8!

Reply 19 of 39, by krcroft

User metadata
Rank Oldbie
Rank
Oldbie
jmarsh wrote on 2020-10-25, 13:38:

I would not expect a .bin file containing both data and audio tracks to use mode1/2048.

Yup; there are some releases that incorrectly rename the ISO to BIN (or vice-versa).

Akuma, you can use: file <binname> and grep for the ISO string to pre-detect these broken scenarios.

If the user is trying to to rip a BIN+CUE where the BIN is simply an ISO, then they won't have audio tracks anyway, in which case they also don't need the CUE.. just mount the ISO straight away. In that scenario, you could suggest that or still generate a cdrom.bat for them.