LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-05-2009, 05:19 AM   #1
jamesan
LQ Newbie
 
Registered: Aug 2009
Posts: 3

Rep: Reputation: 0
FLAC decoding script


Hi,

I have a library of FLAC files which I need to convert to WAVs. The FLAC files are in a folder called FLAC, with each album in a uniquely named folder. The WAV files will be in a folder called WAV, again with each album in its own folder, named the same as the FLAC album folder.

So I guess I need to know how to recursively descend into folders and decode the FLAC files into similar directory structures elsewhere.

/home/FLAC/Album1/track1.flac becomes /home/WAV/Album1/track1.wav
/home/FLAC/Album1/track2.flac becomes /home/WAV/Album1/track2.wav
/home/FLAC/Album2/track1.flac becomes /home/WAV/Album2/track1.wav

...etc

This code is currently working for a single album folder:

Code:
#!/bin/bash
LIST="$(ls /home/FLAC/)"
for file in "$LIST"; do
LIST2="$(ls /home/FLAC/$file/)"
for ffile in "$LIST2"; do
cd /home/FLAC/$file/
flac -d --output-prefix=/home/WAV/$file/ $ffile
done
done
But is fails with this error when there are two or more albums to decode:

Code:
[root@server52870 bms002]# flacdecode

flac 1.2.1, Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  Josh Coalson
flac comes with ABSOLUTELY NO WARRANTY.  This is free software, and you are
welcome to redistribute it under certain conditions.  Type `flac' for details.

: ERROR: can't open output file /home/WAV/bms001bms002/.wav: No such file or directory

bms002:: ERROR initializing decoder
         init status = FLAC__STREAM_DECODER_INIT_STATUS_ERROR_OPENING_FILE

An error occurred opening the input file; it is likely that it does not exist
or is not readable.
bms001:: ERROR: can't open output file /home/WAV/bms001/home/FLAC/bms001:.wav: No such file or directory
bms001_01.flac: done
ERROR: output file /home/WAV/bms001bms001_01.wav already exists, use -f to override
bms001_02.flac: done
ERROR: output file /home/WAV/bms001bms001_02.wav already exists, use -f to override
bms001_03.flac: done
ERROR: output file /home/WAV/bms001bms001_03.wav already exists, use -f to override

bms002: ERROR while decoding metadata
        state = FLAC__STREAM_DECODER_ABORTED
I'm sure that spells out a very obvious logic error to someone... any pointers much appreciated!
 
Old 08-05-2009, 06:01 AM   #2
vonbiber
Member
 
Registered: Apr 2009
Distribution: slackware 14.1 64-bit, slackware 14.2 64-bit, SystemRescueCD
Posts: 533

Rep: Reputation: 129Reputation: 129
you might try this (test it first, then remove the comments
and the echo lines)

assuming your flac cmd works as: flac inputfile outputfile

### cut and paste into a shell script ###
#!/bin/sh

TOP=replace_here_by_the_folder_above_both_FLAC_n_WAV
FLAC=$TOP/FLAC
WAV=$TOP/WAV

find $FLAC/* | while read f
do
cmd="echo $f | sed 's?^$FLAC?$WAV?'"
g="$(eval $cmd)"
d=${g%/*}
echo "mkdir -p $WAV/$d"
# mkdir -p $WAV/$d
if [ -d $f ]; then
continue
fi
ext=${f##*.}
if [ "$ext" == "flac" ]; then
echo "flac $f $g || exit 1"
# flac $f $g || exit 1
fi
done

#### end of script
 
Old 08-05-2009, 06:32 AM   #3
jamesan
LQ Newbie
 
Registered: Aug 2009
Posts: 3

Original Poster
Rep: Reputation: 0
Hi vonbiber,

Thanks for the reply - can you explain what the code does? I think it's very close to what I need but currently doesn't quite do it...

Here's my script:

Code:
#!/bin/sh

TOP=/media_library
FLAC=$TOP/98
WAV=$TOP/12

find $FLAC/* | while read f
do
cmd="echo $f | sed 's?^$FLAC?$WAV?'"
g="$(eval $cmd)"
d=${g%/*}
echo "mkdir -p $WAV/$d"
# mkdir -p $WAV/$d
if [ -d $f ]; then
continue
fi
ext=${f##*.}
if [ "$ext" == "flac" ]; then
echo "flac -d $f $g || exit 1"
# flac -d $f $g || exit 1
fi
done
And here's the output:

Code:
mkdir -p /media_library/12//media_library/12
mkdir -p /media_library/12//media_library/12/bms001
mkdir -p /media_library/12//media_library/12/bms001
flac -d /media_library/98/bms001/bms001_03.flac /media_library/12/bms001/bms001_03.flac || exit 1
mkdir -p /media_library/12//media_library/12/bms001
flac -d /media_library/98/bms001/bms001_02.flac /media_library/12/bms001/bms001_02.flac || exit 1
mkdir -p /media_library/12//media_library/12/bms001
flac -d /media_library/98/bms001/bms001_01.flac /media_library/12/bms001/bms001_01.flac || exit 1
mkdir -p /media_library/12//media_library/12
mkdir -p /media_library/12//media_library/12/bms002
flac /media_library/98/bms002/bms002_01.flac /media_library/12/bms002/bms002_01.flac || exit 1
mkdir -p /media_library/12//media_library/12/bms002
flac -d /media_library/98/bms002/bms002_02.flac /media_library/12/bms002/bms002_02.flac || exit 1
mkdir -p /media_library/12//media_library/12/bms002
flac -d /media_library/98/bms002/bms002_03.flac /media_library/12/bms002/bms002_03.flac || exit 1
mkdir -p /media_library/12//media_library/12
 
Old 08-05-2009, 07:02 AM   #4
jamesan
LQ Newbie
 
Registered: Aug 2009
Posts: 3

Original Poster
Rep: Reputation: 0
Sussed it! Probably a weird hack, but works... thanks loads for your help vonbiber. Here's what worked in the end:


Code:
#!/bin/sh

TOP=/media_library
FLAC=$TOP/flacfiles
WAV=$TOP/wavfiles

find $FLAC/* | while read f
do
cmd="echo $f | sed 's?^$FLAC?$WAV?'"
g="$(eval $cmd)"
d=${g%/*}
# echo "mkdir -p $d"
mkdir -p $d
if [ -d $f ]; then
continue
fi
ext=${f##*.}
if [ "$ext" == "flac" ]; then
BASEFLAC=`basename $f`
FLACDIR=`dirname $f`
WAVDIR=`dirname $g`
# echo "cd $FLACDIR"
cd $FLACDIR
# echo "flac -d $BASEFLAC --output-prefix=$WAVDIR/ || exit 1"
flac -d $BASEFLAC --output-prefix=$WAVDIR/
fi
done
 
Old 08-05-2009, 07:39 AM   #5
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
FWIW and not that it has any bearing on your script or would apply if your .flac don't have any information, or if .wav is not just an intermediate conversion stage, but FLAC can store quite a lot of information and a flac->wav conversion won't transfer it. As in 'metaflac --export-tags.*'.
 
Old 08-05-2009, 07:45 AM   #6
vonbiber
Member
 
Registered: Apr 2009
Distribution: slackware 14.1 64-bit, slackware 14.2 64-bit, SystemRescueCD
Posts: 533

Rep: Reputation: 129Reputation: 129
Quote:
Originally Posted by jamesan View Post

TOP=/media_library
FLAC=$TOP/flacfiles
WAV=$TOP/wavfiles

find $FLAC/* | while read f
do
cmd="echo $f | sed 's?^$FLAC?$WAV?'"
g="$(eval $cmd)"
d=${g%/*}
# echo "mkdir -p $d"
mkdir -p $d
if [ -d $f ]; then
continue
fi
ext=${f##*.}
if [ "$ext" == "flac" ]; then
BASEFLAC=`basename $f`
FLACDIR=`dirname $f`
WAVDIR=`dirname $g`
# echo "cd $FLACDIR"
cd $FLACDIR
# echo "flac -d $BASEFLAC --output-prefix=$WAVDIR/ || exit 1"
flac -d $BASEFLAC --output-prefix=$WAVDIR/
fi
done[/CODE]
that's the reason why you must test (thru echo) before
actually doing the conversion

I'll try to explain
The idea is to store the output files in a tree similar to
the input files (except for the top directory which
for the input files is $FLAC and it exists
for the output files is $WAV and it doesn't necessarily exists

1. first we look for all files/folders/subfolders in the input
directory $FLAC
find $FLAC/* | while read f
do
...
done

2.
cmd="echo $f | sed 's?^$FLAC?$WAV?'"
g="$(eval $cmd)"

the 2 lines above help us form the target path
we can't directly do g=$(echo $f | sed 's?^$FLAC?$WAV?'")
that wouldn't work (eval replaces the variables FLAC and WAV
by their actual values before executing sed)

d=${g%/*}
this one forms the directory part of the complete path $g

so for instance, if the input file is
/media_library/flacfiles/folder0/folderA/file.avi

g is gonna be
/media_library/wavefiles/folder0/folderA/file.avi

and d: /media_library/wavefiles/folder0/folderA

mkdir -p $d
we create the directory $d if it doesn't already exist

if [ -d $f ]; then
continue
fi
if $f is a directory proceed, do nothing

ext=${f##*.}
this store the extension of the file in the variable ext
if the test below is true
if [ "$ext" == "flac" ]; then
do the conversion
...

These shell constructions are quite useful (and more efficient
than the commands 'basename', 'sed', etc.) so whenever you can use
them do so

g=${f##*/} : filename (without the directory part)
n=${g%.*} : name (without the extension)

hope this is clear enough
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
quick bash script to convert flac to mp3 zuralin Programming 8 08-19-2011 03:50 AM
image decoding pjpunnoose Linux - Newbie 7 05-07-2008 01:43 AM
decoding alsamixer geomatt Linux - Software 3 07-13-2005 06:25 AM
decoding TazLinux Linux - General 4 11-29-2003 11:47 AM
usb decoding StoneX Programming 1 02-12-2002 03:07 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:18 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration