LinuxQuestions.org
Review your favorite Linux distribution.
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 03-27-2007, 02:43 PM   #1
marwal
LQ Newbie
 
Registered: Mar 2007
Posts: 5

Rep: Reputation: 0
BASH - determine when file is no longer written to


Im writing a script that rips a CD and encodes the WAV-files to MP3. Thats kind of basic.
What I wanted to do was to have several instances of encoders running parallell with the ripping. That went kind-of alright.

Im running icedax (cdda2wav) like this :
Code:
icedax --bulk -q dev=$DEVICE --cddb 1 && eject $DEVICE &
It then starts to rip all tracks. Another script is on a look-out for WAV-files and assignes them to the encoder (making sure there is no more than 3 encoders running at the same time).

My problem is to determine when a WAV-file is completly ripped. I was trying to use 'lsof' but it reports 'in use by icedax' for all WAV-files until the ripping process is completed.
Is there a way to make sure the WAV-file I assign to an encoder is complete?

I know I could use icedax and ripp one track at-a-time but I want to beat the application Grip and rip-encode faster.

I'm also intrerested in all kinds of ideas regarding my scripting. Im kind of new at BASH and need all tips i can get .

Here are my scripts:

rip
Code:
#DEVICE=/dev/scd0
DEVICE=/dev/hdc
function what_time() {
  TIME=$(date +%H:%M:%S)
}

what_time; echo "$TIME : rip is starting"
# start ripping
icedax --bulk -q dev=$DEVICE --cddb 1 && eject $DEVICE &

#start encoding-agent (give it 10 seconds)
sleep 10
what_time; echo "$TIME : mwrip is calling encode"
./encode &
encode
Code:
function what_time() {
  TIME=$(date +%H:%M:%S)
}

function send_agent() {
  # is there job in stack
  if [ "${STACK[$POINTER]}" != "" ]; then
    NO_JOBS=$(jobs | wc -l)
    # if current jobs are fewer than 3...
    if [ $NO_JOBS -lt 3 ]; then
      what_time; echo "$TIME : found ${STACK[$POINTER]} and a free slot..."
      ./agent ${STACK[$POINTER]} &
      let "POINTER=$POINTER+1"
    fi
  fi
}


TRACKS=$(cat audio.cddb | grep TTITLE | wc -l)

STACK=[]
POINTER=1
COUNTER=1

while (($POINTER <= $TRACKS)); do
  while (($COUNTER <= $TRACKS)); do
    NO=$(printf "%02i" $COUNTER)
    FILE="audio_$NO.wav"
    if [ -f $FILE ]; then
      STACK[$COUNTER]=$FILE
      #echo ${STACK[$COUNTER]}
      let "COUNTER=$COUNTER+1"
    fi
    send_agent
  done
  send_agent
done
agent
Code:
WAV=$1
MP3=${WAV%.wav}.mp3
function what_time() {
  TIME=$(date +%H:%M:%S)
}

what_time; echo "$TIME : agent ($$) recoding $WAV to $MP3..."

lame -h -b 128 --quiet $WAV $MP3

what_time; echo "$TIME : agent ($$) is done."
exit 0

Last edited by marwal; 03-27-2007 at 02:45 PM.
 
Old 03-27-2007, 03:19 PM   #2
anomie
Senior Member
 
Registered: Nov 2004
Location: Texas
Distribution: RHEL, Scientific Linux, Debian, Fedora
Posts: 3,935
Blog Entries: 5

Rep: Reputation: Disabled
Let me suggest an idea on a conceptual level; take it or leave it.

1. Script enters a loop where it rips to wav files, one at a time.
2. After each wav file is ripped (within the loop), a bg job is submitted to encode that particular wav to mp3.

Make sense? This will ensure that each wav is ripped before you start encoding it. It also means that the ripper can continue while encoding jobs run.
 
Old 03-27-2007, 03:22 PM   #3
macemoneta
Senior Member
 
Registered: Jan 2005
Location: Manalapan, NJ
Distribution: Fedora x86 and x86_64, Debian PPC and ARM, Android
Posts: 4,593
Blog Entries: 2

Rep: Reputation: 344Reputation: 344Reputation: 344Reputation: 344
When you start the process, save its process ID. For example:

Code:
somecommand &
somecommand_pid=$!
You can then later wait for that process (or those processes) to be complete with:

Code:
wait $somecommand_pid $someOthercommand_pid
 
Old 03-27-2007, 03:28 PM   #4
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,399
Blog Entries: 2

Rep: Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908Reputation: 908
Since ripping is likely to be an IO-bound process, you may find that there is no improvement in overall performance, and there may actually be a net loss, due to cache flushing and/or additional seeking. I don't know that bash has fine enough control over process monitoring to do what you are trying to accomplish. Using something slightly more sophisticated such as perl, which would allow you you fork an arbitrary number of processes, and then do waitpid() on each of them would be a more refined method. My opinion.

--- rod.

EDIT: macemoneta has just pointed out that Bash can indeed do what I suggested as a good reason to use perl.

Last edited by theNbomr; 03-27-2007 at 03:30 PM.
 
Old 03-27-2007, 03:59 PM   #5
marwal
LQ Newbie
 
Registered: Mar 2007
Posts: 5

Original Poster
Rep: Reputation: 0
Thank you all for your responses.
anomie) I know I could rip one track at the time. That would give me control over when that track is ripped and start encoding. It is slower though to rip track 1,2,3,4... than it is to rip --bulk. With bulk-ripping i rip one cd in about 2 minutes.

macemoneta) About PIDs. Since a run icedax with the --bulk parameter there is no sence in waiting for that job to finish. It would be the same as to first rip and then encode. My idea was to encode WAV-files on the fly while the ripping was still in progress.

theNbomr) Yes, ripping in parallell is no god idea. But encoding is and that is what i am doing. I keep three instances of lame-encoders running i parallell. I find (on my machine) that this increases encoding-speed. If I would run, like ten instances of encoders it would encode the pool of WAV-files slower.

If there is no way to make sure icedax --bulk is finnished with, say audio_01.wav - i would have to do as anomie says: rip one track, start encoding it while i rip track2 (and so on).
Possibly I can use filesize from the info-files icedax produces to determine if a WAV-file is done but I would prefer a system-call like "hello file, are you beeing written to? No!? Ok, i will now encode you and then kill you!"

Last edited by marwal; 03-27-2007 at 04:00 PM.
 
Old 03-27-2007, 04:25 PM   #6
macemoneta
Senior Member
 
Registered: Jan 2005
Location: Manalapan, NJ
Distribution: Fedora x86 and x86_64, Debian PPC and ARM, Android
Posts: 4,593
Blog Entries: 2

Rep: Reputation: 344Reputation: 344Reputation: 344Reputation: 344
If you just want the status of a background process, you can use jobs and grep the the PID. For example:

Code:
somecommand &
somecommand_pid=$!
.
.
.
running=`jobs -l | grep $somecommand_pid`
if [ "$running" != "" ]
then
   echo "encode still in progress"
fi
If you just want to rip and encode music in parallel, you know you can just use a package like grip, right?
 
Old 03-27-2007, 04:55 PM   #7
marwal
LQ Newbie
 
Registered: Mar 2007
Posts: 5

Original Poster
Rep: Reputation: 0
Thank you macemoneta for your reply, although it indicates to me that you havent read the first, or even the second post i made in this thread.
 
Old 03-27-2007, 05:11 PM   #8
macemoneta
Senior Member
 
Registered: Jan 2005
Location: Manalapan, NJ
Distribution: Fedora x86 and x86_64, Debian PPC and ARM, Android
Posts: 4,593
Blog Entries: 2

Rep: Reputation: 344Reputation: 344Reputation: 344Reputation: 344
I read all your posts, as well as the posts of everyone else. I understand them all, but I suspect you do not. Either that, or you are not communicating what you want clearly.

Grip is simply scheduling and dispatching highly optimized standalone rippers and encoders (which you can configure as you please). The idea that you will somehow "beat" this makes the basic premise weak.

I chose to assume you want to learn how to schedule and dispatch processes in your own code; but according to you, that's not what you want. So I now have to assume that you don't really know what you want. Can you clarify?
 
Old 03-27-2007, 05:37 PM   #9
marwal
LQ Newbie
 
Registered: Mar 2007
Posts: 5

Original Poster
Rep: Reputation: 0
I like Grip. I use it. I'm aware of it (as i mention in my first posting).
It was the inspiration for me to try and optimize the rip-encoding process.

Even if i run my scripts rip- and encode parts in sequence i beat grip. That's because
1) i rip bulked
2) i have three encoders working (not 1 as grip).

The only thing missing now is to establish WHEN (in bulk ripping, running as ONE process) each WAV-file is completed so i can start encoding and NOT WAIT for the process to finish.

English is not my natural language it's challanging for me to express myself as well as i can in my native tongue. I'm sorry if this is making it hard for you (and others) to understand me.
I also realize my previous post might have sounded rude. I won't blame that on language-problems. It was more of a babelesque frustration-problem.
I know there is a solution for what im after and ill keep trying and report back here when i find it.
cheers.
 
Old 03-27-2007, 06:20 PM   #10
macemoneta
Senior Member
 
Registered: Jan 2005
Location: Manalapan, NJ
Distribution: Fedora x86 and x86_64, Debian PPC and ARM, Android
Posts: 4,593
Blog Entries: 2

Rep: Reputation: 344Reputation: 344Reputation: 344Reputation: 344
Grip is somewhat better than just bulk ripping, in that you can exclude tracks you don't want, and the tracks are automatically labeled from freedb.org (or your favorite track database site).

To run multiple encoders on grip:

Config->Encode->Options and increase the number of CPUs. From the grip documentation at the site I linked to above: "This value specifies the number of simultaneous encode processes to run." In your case, set number of CPUs to 3 for three concurrent encoders.
 
Old 03-27-2007, 06:51 PM   #11
marwal
LQ Newbie
 
Registered: Mar 2007
Posts: 5

Original Poster
Rep: Reputation: 0
macemoneta: I wasn't aware of that option in grip. That took away most of the entusiasm i had about his. And just as I realized the solution to my problem -> Since ripping is done in sequence, if audio_02.wav exists audio_01.wav must be done. So all i had to do was NOT to add the most recent WAV-file to the que until that file was the FINAL one.

Well... i think I'll program it anyway (you know... this was just a mind-exercise to begin with, like most of my small projects).
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
/var/log/messages no longer being written to Mehuge Fedora 8 02-04-2008 10:58 PM
moving a file while is being written omnio Programming 10 03-23-2007 09:25 AM
cannot open file to written venki Linux - Newbie 5 12-18-2006 06:57 AM
Bash scripting and trying to determine whether a directory exists? obelxi Programming 9 04-18-2005 11:22 PM
another dumb program written in bash. micxz Programming 0 10-13-2003 07:23 PM

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

All times are GMT -5. The time now is 07:28 PM.

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