Index: cae/cae_alsa.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/cae/cae_alsa.cpp,v
retrieving revision 1.41
diff -u -r1.41 cae_alsa.cpp
--- cae/cae_alsa.cpp	18 Jul 2008 20:06:10 -0000	1.41
+++ cae/cae_alsa.cpp	9 Nov 2008 11:13:36 -0000
@@ -32,6 +32,7 @@
 #include <rdmeteraverage.h>
 
 #include <cae.h>
+#include <rdcae.h>
 
 #ifdef ALSA
 //
@@ -796,8 +797,12 @@
     *stream=-1;
     return false;
   }
-  if((alsa_play_wave[card][*stream]->getFormatTag()!=WAVE_FORMAT_PCM)||
-     (alsa_play_wave[card][*stream]->getBitsPerSample()!=16)) {
+   switch(alsa_play_wave[card][*stream]->type()){
+ 	  case RDWaveFile::Wave:
+ 	  case RDWaveFile::Ogg:
+ 	  case RDWaveFile::Mpeg:
+ 		  break;
+ 	  default:
     LogLine(RDConfig::LogErr,QString().sprintf(
             "Error: alsaLoadPlayback(%s)   getFormatTag()%d || getBistsPerSample()%d failed",
             (const char *) wavename,
@@ -808,6 +813,7 @@
     FreeAlsaOutputStream(card,*stream);
     *stream=-1;
     return false;
+  	   break;
   }
   alsa_output_channels[card][*stream]=
     alsa_play_wave[card][*stream]->getChannels();
@@ -923,14 +929,22 @@
   alsa_record_wave[card][stream]->setChannels(chans);
   alsa_record_wave[card][stream]->setSamplesPerSec(samprate);
   alsa_record_wave[card][stream]->setBitsPerSample(16);
-  alsa_record_wave[card][stream]->setBextChunk(true);
   alsa_record_wave[card][stream]->setLevlChunk(true);
+  if(coding==RDCae::OggVorbis || coding==RDCae::MpegL3) {
+    alsa_record_wave[card][stream]->setEnergyTag(1);
+    }
+  else {
+    alsa_record_wave[card][stream]->setBextChunk(true);
+    } 
   if(!alsa_record_wave[card][stream]->createWave()) {
     delete alsa_record_wave[card][stream];
     alsa_record_wave[card][stream]=NULL;
     return false;
   }
   chown((const char *)wavename,rd_config->uid(),rd_config->gid());
+  if(coding==RDCae::OggVorbis || coding==RDCae::MpegL3) {
+    chown((const char *)(wavename+".energy"),rd_config->uid(),rd_config->gid());
+    }
   alsa_input_channels[card][stream]=chans;
   alsa_record_ring[card][stream]=new RDRingBuffer(RINGBUFFER_SIZE);
   alsa_record_ring[card][stream]->reset();
Index: cae/cae_jack.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/cae/cae_jack.cpp,v
retrieving revision 1.50
diff -u -r1.50 cae_jack.cpp
--- cae/cae_jack.cpp	18 Jul 2008 20:06:10 -0000	1.50
+++ cae/cae_jack.cpp	9 Nov 2008 11:13:36 -0000
@@ -32,6 +32,7 @@
 #include <rdmeteraverage.h>
 
 #include <cae.h>
+#include <rdcae.h>
 
 #ifdef JACK
 //
@@ -559,8 +560,12 @@
     *stream=-1;
     return false;
   }
-  if((jack_play_wave[*stream]->getFormatTag()!=WAVE_FORMAT_PCM)||
-     (jack_play_wave[*stream]->getBitsPerSample()!=16)) {
+  switch (jack_play_wave[*stream]->type()){
+      case RDWaveFile::Wave:
+      case RDWaveFile::Ogg:
+      case RDWaveFile::Mpeg:
+        break;
+     default:
     LogLine(RDConfig::LogNotice,QString().sprintf(
             "Error: jackLoadPlayback(%s)   getFormatTag()%d || getBistsPerSample()%d failed",
             (const char *) wavename,
@@ -571,6 +576,7 @@
     FreeJackOutputStream(*stream);
     *stream=-1;
     return false;
+    break;
   }
   jack_output_channels[*stream]=jack_play_wave[*stream]->getChannels();
   jack_output_sample_rate[*stream]=jack_play_wave[*stream]->getSamplesPerSec();
@@ -695,14 +701,22 @@
   jack_record_wave[stream]->setChannels(chans);
   jack_record_wave[stream]->setSamplesPerSec(samprate);
   jack_record_wave[stream]->setBitsPerSample(16);
-  jack_record_wave[stream]->setBextChunk(true);
   jack_record_wave[stream]->setLevlChunk(true);
+  if(coding==RDCae::OggVorbis || coding==RDCae::MpegL3) {
+    jack_record_wave[stream]->setEnergyTag(1);
+    }
+  else {
+    jack_record_wave[stream]->setBextChunk(true);
+    } 
   if(!jack_record_wave[stream]->createWave()) {
     delete jack_record_wave[stream];
     jack_record_wave[stream]=NULL;
     return false;
   }
   chown((const char *)wavename,rd_config->uid(),rd_config->gid());
+  if(coding==RDCae::OggVorbis || coding==RDCae::MpegL3) {
+    chown((const char *)(wavename+".energy"),rd_config->uid(),rd_config->gid());
+    }
   jack_input_channels[stream]=chans; 
   jack_record_ring[stream]=new RDRingBuffer(RINGBUFFER_SIZE);
   jack_record_ring[stream]->reset();
Index: lib/Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/Makefile.am,v
retrieving revision 1.110
diff -u -r1.110 Makefile.am
--- lib/Makefile.am	30 Sep 2008 18:19:39 -0000	1.110
+++ lib/Makefile.am	9 Nov 2008 11:13:36 -0000
@@ -216,7 +216,8 @@
                           moc_rdintegerdialog.cpp\
                           moc_rdoneshot.cpp
 
-librd_la_LDFLAGS = -release $(VERSION)
+librd_la_LDFLAGS =  -lmad -ltag -release $(VERSION)
+librd_la_CXXFLAGS =  -I/usr/include/taglib
 
 EXTRA_DIST = lib.pro rdwin32.h rdwin32.cpp rdttydevice_win32.cpp\
              gpl2.html html_gpl2_win32.cpp\
Index: lib/librd_de.ts
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/librd_de.ts,v
retrieving revision 1.4
diff -u -r1.4 librd_de.ts
--- lib/librd_de.ts	18 Sep 2008 19:02:07 -0000	1.4
+++ lib/librd_de.ts	9 Nov 2008 11:13:37 -0000
@@ -332,11 +332,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Send to
-&amp;Editor</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>&amp;OK</source>
         <translation type="unfinished"></translation>
     </message>
@@ -348,6 +343,32 @@
         <source>ALL</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>&amp;Edit
+Audio</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Updateing audio...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Starting External Editor...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update Audio?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Send to
+&amp;Editor</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>RDCutDialog</name>
@@ -856,6 +877,10 @@
         <source>144 kbps</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Copy File</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>RDGetAth</name>
@@ -1045,11 +1070,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>The importer encountered an error.
-Please check your importer configuration and try again.</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>File Exists</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1107,6 +1127,12 @@
 Please check your configuration and try again.</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>The importer encountered an error.
+Please check your importer configuration
+or the input file and try again.</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>RDIntegerDialog</name>
Index: lib/librd_es.ts
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/librd_es.ts,v
retrieving revision 1.36
diff -u -r1.36 librd_es.ts
--- lib/librd_es.ts	18 Sep 2008 19:02:07 -0000	1.36
+++ lib/librd_es.ts	9 Nov 2008 11:13:37 -0000
@@ -336,16 +336,37 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Send to
-&amp;Editor</source>
+        <source>&amp;Search</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>&amp;Search</source>
+        <source>Please Wait...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Please Wait...</source>
+        <source>&amp;Edit
+Audio</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Updateing audio...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Starting External Editor...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update Audio?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Send to
+&amp;Editor</source>
         <translation type="unfinished"></translation>
     </message>
 </context>
@@ -856,6 +877,10 @@
         <source>144 kbps</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Copy File</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>RDGetAth</name>
@@ -1015,11 +1040,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>The importer encountered an error.
-Please check your importer configuration and try again.</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>File Exists</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1107,6 +1127,12 @@
 Do you still want to proceed?</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>The importer encountered an error.
+Please check your importer configuration
+or the input file and try again.</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>RDIntegerDialog</name>
Index: lib/librd_fr.ts
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/librd_fr.ts,v
retrieving revision 1.4
diff -u -r1.4 librd_fr.ts
--- lib/librd_fr.ts	18 Sep 2008 19:02:07 -0000	1.4
+++ lib/librd_fr.ts	9 Nov 2008 11:13:37 -0000
@@ -332,11 +332,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Send to
-&amp;Editor</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>&amp;OK</source>
         <translation type="unfinished"></translation>
     </message>
@@ -348,6 +343,32 @@
         <source>ALL</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>&amp;Edit
+Audio</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Updateing audio...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Starting External Editor...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update Audio?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Send to
+&amp;Editor</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>RDCutDialog</name>
@@ -856,6 +877,10 @@
         <source>144 kbps</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Copy File</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>RDGetAth</name>
@@ -1045,11 +1070,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>The importer encountered an error.
-Please check your importer configuration and try again.</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>File Exists</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1107,6 +1127,12 @@
 Please check your configuration and try again.</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>The importer encountered an error.
+Please check your importer configuration
+or the input file and try again.</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>RDIntegerDialog</name>
Index: lib/rdcae.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdcae.h,v
retrieving revision 1.24
diff -u -r1.24 rdcae.h
--- lib/rdcae.h	14 Sep 2007 14:06:24 -0000	1.24
+++ lib/rdcae.h	9 Nov 2008 11:13:37 -0000
@@ -43,7 +43,7 @@
  public:
   enum ChannelMode {Normal=0,Swap=1,LeftOnly=2,RightOnly=3};
   enum SourceType {Analog=0,AesEbu=1};
-  enum AudioCoding {Pcm16=0,MpegL1=1,MpegL2=2,MpegL3=3};
+  enum AudioCoding {Pcm16=0,MpegL1=1,MpegL2=2,MpegL3=3,Flac=4,OggVorbis=5};
   RDCae(QObject *parent=0,const char *name=0);
   ~RDCae();
   void connectHost(QString hostname,Q_UINT16 hostport,QString password);
Index: lib/rdcart.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdcart.cpp,v
retrieving revision 1.61.2.1
diff -u -r1.61.2.1 rdcart.cpp
--- lib/rdcart.cpp	28 Oct 2008 19:24:20 -0000	1.61.2.1
+++ lib/rdcart.cpp	9 Nov 2008 11:13:37 -0000
@@ -899,6 +899,7 @@
 
   filename = RDCut::pathName(cutname); 
   unlink(filename);
+  unlink(filename+".energy");
   sql=QString().sprintf("delete from CUTS where CUT_NAME=\"%s\"",
 			(const char *)cutname);
   q=new RDSqlQuery(sql);
@@ -931,6 +932,7 @@
     q=new RDSqlQuery(sql);
     while(q->next()) {
       unlink(RDCut::pathName(QString(q->value(0).toString())).ascii()); 
+      unlink((RDCut::pathName(QString(q->value(0).toString()))+".energy").ascii()); 
     }
     delete q;
     sql=QString().sprintf("delete from CUTS where CART_NUMBER=%u",cart_number);
Index: lib/rdcart_dialog.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdcart_dialog.cpp,v
retrieving revision 1.40
diff -u -r1.40 rdcart_dialog.cpp
--- lib/rdcart_dialog.cpp	12 May 2008 13:39:43 -0000	1.40
+++ lib/rdcart_dialog.cpp	9 Nov 2008 11:13:38 -0000
@@ -26,12 +26,17 @@
 #include <qdatetime.h>
 #include <qapplication.h>
 #include <qeventloop.h>
+#include <qmessagebox.h>
 
 #include <rdconf.h>
+#include <rdlibrary_conf.h>
 #include <rdcart_dialog.h>
 #include <rdcart_search_text.h>
 #include <rdtextvalidator.h>
 #include <rddb.h>
+#include <rdwavefile.h>
+
+#include <unistd.h>
 
 //
 // Icons
@@ -218,8 +223,21 @@
   //
   // Send to Editor Button
   //
-  cart_editor_button=
-    new QPushButton(tr("Send to\n&Editor"),this,"cart_editor_button");
+  RDConfig *lib_config;
+  lib_config=new RDConfig();
+  lib_config->load();
+  RDLibraryConf *rdlibrary_conf;
+  rdlibrary_conf = new RDLibraryConf(lib_config->stationName(),0);
+  if(!rdlibrary_conf->enableEditor()) {
+    cart_editor_button=
+      new QPushButton(tr("Send to\n&Editor"),this,"cart_editor_button");
+  }
+  else {
+    cart_editor_button=
+      new QPushButton(tr("&Edit\nAudio"),this,"cart_editor_button");
+  }
+  delete lib_config;
+  delete rdlibrary_conf;
   cart_editor_button->setGeometry(235,sizeHint().height()-60,80,50);
   cart_editor_button->setFont(button_font);
   connect(cart_editor_button,SIGNAL(clicked()),this,SLOT(editorData()));
@@ -244,6 +262,17 @@
     setGeometry(sizeHint().width()-90,sizeHint().height()-60,80,50);
   cart_cancel_button->setFont(button_font);
   connect(cart_cancel_button,SIGNAL(clicked()),this,SLOT(cancelData()));
+
+  //
+  // Progress Dialog
+  //
+  update_progress_dialog=new QProgressDialog(this);
+  update_progress_dialog->setLabelText(tr("Updateing audio..."));
+  update_progress_dialog->setCancelButton(NULL);
+  update_progress_dialog->setTotalSteps(10);
+  update_progress_dialog->setMinimumDuration(1);
+  update_progress_dialog->setCaption("");
+
 }
 
 
@@ -409,6 +438,12 @@
 void RDCartDialog::editorData()
 {
 #ifndef WIN32
+RDConfig *lib_config;
+lib_config=new RDConfig();
+lib_config->load();
+RDLibraryConf *rdlibrary_conf;
+rdlibrary_conf = new RDLibraryConf(lib_config->stationName(),0);
+if(!rdlibrary_conf->enableEditor()) {
   RDListViewItem *item=(RDListViewItem *)cart_cart_list->currentItem();
   if(item==NULL) {
     return;
@@ -451,6 +486,172 @@
     system(cmd+" &");
     exit(0);
   }
+}
+else {
+  QString sql;
+  RDSqlQuery *q;
+  RDCut *temp_cut;
+  RDWaveFile *wavefile;
+  double level=1.0; 
+  QString extension="wav";
+  RDStation *rdstation_conf;
+
+
+  if(cart_cart_list->currentItem()==0) {
+    return;
+  }
+ 
+  sql=QString().sprintf("select CUT_NAME,START_POINT,END_POINT,PLAY_GAIN\
+                         from CUTS where (CART_NUMBER=%u)",
+			cart_cart_list->currentItem()->text(1).toUInt());
+  q=new RDSqlQuery(sql);
+  if(!q->first()) {
+    delete q;
+    return;
+  }
+  temp_cut=new RDCut(q->value(0).toString());
+  delete q;
+  
+  wavefile=new RDWaveFile(RDCut::pathName(temp_cut->cutName()));
+  if(wavefile->openWave()) {
+    level=wavefile->getNormalizeLevel();
+    switch(wavefile->getFormatTag()) {
+      case WAVE_FORMAT_PCM:
+        extension="wav";
+        break;
+        
+      case WAVE_FORMAT_MPEG:
+        if(wavefile->getHeadLayer()==3) {
+          extension="mp3";
+        }
+        else {
+          extension="mp2";
+	}
+        break;
+        
+      case WAVE_FORMAT_VORBIS:
+        extension="ogg";
+        break;
+    }
+    wavefile->closeWave();
+  }  
+  delete wavefile; 
+
+  rdstation_conf=new RDStation(lib_config->stationName());
+  QString cmd=rdstation_conf->editorPath();
+  delete rdstation_conf;
+
+  cmd.replace("%f","/tmp/"+temp_cut->cutName()+"."+extension);
+  // FIXME: other replace commands to match: lib/rdcart_dialog.cpp editorData()
+  //        These substitions should be documented (maybe a text file),
+  //            ex: %f = cart_cut filename
+  //        and possibly also add some tooltips with help advice
+
+  update_progress_dialog->setLabelText(tr("Starting External Editor..."));
+  update_progress_dialog->setProgress(1);
+  qApp->processEvents();
+
+ // if(fork()==0) {
+  system(QString().sprintf("cp %s /tmp/%s.%s",
+           RDCut::pathName(temp_cut->cutName()).ascii(),temp_cut->cutName().ascii(),
+           (const char *)extension));
+  system(cmd.ascii());
+ //   exit(0);
+ // }
+  
+  update_progress_dialog->setProgress(10);
+  
+  if(QMessageBox::question(this,tr("Update"),
+			    tr("Update Audio?"),
+			    QMessageBox::Yes,
+			    QMessageBox::No)==QMessageBox::No) {
+    delete temp_cut;
+    delete lib_config;
+    return;
+  }
+  
+  update_progress_dialog->setLabelText(tr("Updateing audio..."));
+  update_progress_dialog->setProgress(1);
+  qApp->processEvents();
+
+  //system(QString().sprintf("rd_edit_copy /tmp/%s.%s",temp_cut->cutName().ascii(),
+  //                           (const char *)extension));
+  
+  wavefile=new RDWaveFile("/tmp/"+temp_cut->cutName()+"."+extension);
+  if(!wavefile->openWave()) {
+    delete wavefile;
+    update_progress_dialog->setProgress(10);
+    delete temp_cut;
+    delete lib_config;
+    return;
+  }
+  
+  if(wavefile->getFormatTag()==WAVE_FORMAT_PCM) {
+    system(QString().sprintf("sox -v %f /tmp/%s.%s -t raw -s -w -c %d -r %d - |\
+                            rdfilewrite --channels=%d --sample-rate=%d %s",
+         level,
+         temp_cut->cutName().ascii(),
+         (const char *)extension,
+         wavefile->getChannels(),
+         wavefile->getSamplesPerSec(),
+         wavefile->getChannels(),
+         wavefile->getSamplesPerSec(),
+         RDCut::pathName(temp_cut->cutName()).ascii()));
+    
+    unlink("/tmp/"+temp_cut->cutName()+"."+extension);
+    unlink(RDCut::pathName(temp_cut->cutName())+".energy");
+  }
+  else {
+    system(QString().sprintf("mv /tmp/%s.%s %s",
+         temp_cut->cutName().ascii(),
+         (const char *)extension,
+         RDCut::pathName(temp_cut->cutName()).ascii()));
+    if(wavefile->getHeadLayer()==3) {
+      RDWaveFile *wavefile_mv=new RDWaveFile(RDCut::pathName(temp_cut->cutName()));
+      wavefile_mv->openWave();
+      wavefile_mv->setNormalizeLevel(level);
+      wavefile_mv->setEnergyTag(1);
+      wavefile_mv->recreateEnergy();
+      wavefile_mv->closeWave();
+      delete wavefile_mv;
+    }
+  }
+  
+  update_progress_dialog->setProgress(5);
+  qApp->processEvents();
+  
+  delete wavefile;
+  wavefile=new RDWaveFile(RDCut::pathName(temp_cut->cutName()));
+  wavefile->openWave();
+
+  sql=QString().sprintf("update CUTS set START_POINT=0,END_POINT=%d,\
+                         FADEUP_POINT=-1,FADEDOWN_POINT=-1,\
+                         SEGUE_START_POINT=-1,SEGUE_END_POINT=-1,\
+                         TALK_START_POINT=-1,TALK_END_POINT=-1,\
+                         HOOK_START_POINT=-1,HOOK_END_POINT=-1,\
+                         LENGTH=%d\
+                         where CUT_NAME=\"%s\"",
+			wavefile->getExtTimeLength(),
+			wavefile->getExtTimeLength(),
+			temp_cut->cutName().ascii());
+  q=new RDSqlQuery(sql);
+  delete q;
+  wavefile->closeWave();
+  delete wavefile;
+  chmod(RDCut::pathName(temp_cut->cutName()),S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
+  chown(RDCut::pathName(temp_cut->cutName()),lib_config->uid(),lib_config->gid());
+  chmod(RDCut::pathName(temp_cut->cutName())+".energy",S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
+  chown(RDCut::pathName(temp_cut->cutName())+".energy",lib_config->uid(),lib_config->gid());
+  update_progress_dialog->setProgress(10);  
+  qApp->processEvents();
+  RDCart *rdcart=new RDCart(cart_cart_list->currentItem()->text(1).toUInt());
+  rdcart->updateLength();
+  RefreshCarts();
+  delete temp_cut;
+  delete rdcart;
+}
+delete lib_config;
+delete rdlibrary_conf;
 #endif
 }
 
Index: lib/rdcart_dialog.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdcart_dialog.h,v
retrieving revision 1.16
diff -u -r1.16 rdcart_dialog.h
--- lib/rdcart_dialog.h	31 Dec 2007 18:49:08 -0000	1.16
+++ lib/rdcart_dialog.h	9 Nov 2008 11:13:38 -0000
@@ -92,6 +92,7 @@
   QString cart_edit_cmd;
   RDStation::FilterMode cart_filter_mode;
   QProgressDialog *cart_progress_dialog;
+  QProgressDialog *update_progress_dialog;
 #ifndef WIN32
   RDSimplePlayer *cart_player;
 #endif  // WIN32
Index: lib/rdcut.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdcut.cpp,v
retrieving revision 1.67
diff -u -r1.67 rdcut.cpp
--- lib/rdcut.cpp	10 Oct 2008 12:32:22 -0000	1.67
+++ lib/rdcut.cpp	9 Nov 2008 11:13:39 -0000
@@ -26,6 +26,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <math.h>
 
 #include <rd.h>
 #include <rdconf.h>
@@ -49,7 +50,7 @@
 
   cut_db=db;
   cut_name=name;
-
+  coding_format=0;
   cut_signal=new QSignal();
 
   if(create) {
@@ -69,6 +70,7 @@
 
   cut_db=db;
   cut_name=QString().sprintf("%06u_%03d",cartnum,cutnum);
+  coding_format=0;
 
   cut_signal=new QSignal();
 
@@ -457,9 +459,10 @@
 }
 
 
-void RDCut::setCodingFormat(unsigned format) const
+void RDCut::setCodingFormat(unsigned format) 
 {
   SetRow("CODING_FORMAT",format);
+  coding_format=format;
 }
 
 
@@ -483,9 +486,10 @@
 }
 
 
-void RDCut::setBitRate(unsigned rate) const
+void RDCut::setBitRate(unsigned rate) 
 {
   SetRow("BIT_RATE",rate);
+  bitrate=rate;
 }
 
 
@@ -856,6 +860,7 @@
   QString srcname=RDCut::pathName(cut_name); 
   QString destname=RDCut::pathName(cutname); 
   FileCopy(srcname,destname);
+  FileCopy(srcname+".energy",destname+".energy");
 
 #endif
   return true;
@@ -1041,6 +1046,34 @@
 			(const char *)cut_name);
   q=new RDSqlQuery(sql);
   delete q;
+  if(coding_format==3 || coding_format==5) {
+    if(fork()==0) {
+      system(QString().sprintf("nice rd_encode %s %d %d %d %d %s %s &",
+              RDCut::pathName(cut_name).ascii(),
+ 	      coding_format,
+ 	      wavefile->getSamplesPerSec(),
+ 	      wavefile->getChannels(),
+ 	      (bitrate*wavefile->getChannels())/1000,
+ 	      RDConfiguration()->audioOwner().ascii(),
+ 	      RDConfiguration()->audioGroup().ascii()));
+      exit(0);
+    } 	      
+  }
+  if(coding_format==2) {
+    if(wavefile->getFormatTag()==WAVE_FORMAT_PCM) {
+      if(fork()==0) {
+        system(QString().sprintf("nice rd_encode %s %d %d %d %d %s %s &",
+                RDCut::pathName(cut_name).ascii(),
+ 	        coding_format,
+ 	        wavefile->getSamplesPerSec(),
+ 	        wavefile->getChannels(),
+ 	        (bitrate*wavefile->getChannels())/1000,
+ 	        RDConfiguration()->audioOwner().ascii(),
+ 	        RDConfiguration()->audioGroup().ascii()));
+        exit(0);
+      } 	      
+    }
+  }
   wavefile->closeWave();
   delete wavefile;
   return true;
@@ -1138,11 +1171,39 @@
           }
        }
     }
+  wave->closeWave();
   delete wave;
 #endif  // WIN32
 }
 
 
+void RDCut::normalize(int level)
+{
+#ifndef WIN32
+  if(!exists()) {
+    return;
+  }
+  QString wavename=QString().sprintf("%s/%s.%s",(const char *)RD_AUDIO_ROOT,
+				     (const char *)cut_name,
+				     (const char *)RD_AUDIO_EXTENSION);
+  if(level==0) {
+    return;
+    }
+  RDWaveFile *wave=new RDWaveFile(wavename);
+  if(!wave->openWave()) {
+    delete wave;
+    return;
+  }
+  wave->normalize(pow(10.0,(double)level/2000.0));
+  wave->closeWave();
+  delete wave;
+#endif  // WIN32
+}
+
+
+
+
+
 void RDCut::reset() const
 {
 #ifndef WIN32
Index: lib/rdcut.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdcut.h,v
retrieving revision 1.38
diff -u -r1.38 rdcut.h
--- lib/rdcut.h	29 Dec 2007 18:16:10 -0000	1.38
+++ lib/rdcut.h	9 Nov 2008 11:13:39 -0000
@@ -82,11 +82,11 @@
   unsigned localCounter() const;
   void setLocalCounter(unsigned count) const;
   unsigned codingFormat() const;
-  void setCodingFormat(unsigned format) const;
+  void setCodingFormat(unsigned format);
   unsigned sampleRate() const;
   void setSampleRate(unsigned rate) const;
   unsigned bitRate() const;
-  void setBitRate(unsigned rate) const;
+  void setBitRate(unsigned rate);
   unsigned channels() const;
   void setChannels(unsigned chan) const;
   int playGain() const;
@@ -121,6 +121,7 @@
   void setMetadata(RDWaveData *data);
   bool checkInRecording(const QString &stationname) const;
   void autoTrim(RDCut::AudioEnd end,int level);
+  void normalize(int level);
   void autoSegue(int level,int length);
   void reset() const;
   void connect(QObject *receiver,const char *member) const;
@@ -141,6 +142,8 @@
   QSqlDatabase *cut_db;
   QString cut_name;
   unsigned cut_number;
+  unsigned coding_format;
+  unsigned bitrate;
 };
 
 
Index: lib/rdexport_settings_dialog.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdexport_settings_dialog.cpp,v
retrieving revision 1.10
diff -u -r1.10 rdexport_settings_dialog.cpp
--- lib/rdexport_settings_dialog.cpp	18 Sep 2008 19:02:07 -0000	1.10
+++ lib/rdexport_settings_dialog.cpp	9 Nov 2008 11:13:39 -0000
@@ -76,7 +76,7 @@
   //
   lib_channels_box=new QComboBox(this,"lib_channels_box");
   lib_channels_box->setGeometry(100,32,60,19);
-  QLabel *lib_channels_label=
+  lib_channels_label=
     new QLabel(lib_channels_box,tr("&Channels:"),this,
 	       "lib_channels_label");
   lib_channels_label->setGeometry(25,32,70,19);
@@ -89,7 +89,7 @@
   lib_samprate_box->setGeometry(100,54,100,19);
   connect(lib_samprate_box,SIGNAL(activated(const QString &)),
 	  this,SLOT(samprateData(const QString &)));
-  QLabel *lib_samprate_label=
+  lib_samprate_label=
     new QLabel(lib_samprate_box,tr("&Sample Rate:"),this,
 	       "lib_samprate_label");
   lib_samprate_label->setGeometry(25,54,75,19);
@@ -167,6 +167,10 @@
       lib_format_box->setCurrentItem(lib_format_box->count()-1);
     }
   }
+  lib_format_box->insertItem(tr("Copy File"));
+  if(settings->format()==RDSettings::Copy) {
+    lib_format_box->setCurrentItem(lib_format_box->count()-1);
+    }
   for(unsigned i=0;i<lib_encoders->encoderQuantity();i++) {
     lib_format_box->insertItem(lib_encoders->encoder(i)->name());
     if(settings->format()==lib_encoders->encoder(i)->id()) {
@@ -189,6 +193,18 @@
   }
   ShowBitRates(lib_settings->format(),lib_settings->sampleRate(),
 	       lib_settings->bitRate(),lib_settings->quality());
+  if(lib_settings->format()==RDSettings::Copy) {
+    lib_channels_box->setEnabled(false);
+    lib_samprate_box->setEnabled(false);
+    lib_channels_label->setEnabled(false);
+    lib_samprate_label->setEnabled(false);
+  }
+  else {
+    lib_channels_box->setEnabled(true);
+    lib_samprate_box->setEnabled(true);
+    lib_channels_label->setEnabled(true);
+    lib_samprate_label->setEnabled(true);
+  }
 }
 
 
@@ -225,6 +241,18 @@
   }
   ShowBitRates(fmt,lib_samprate_box->currentText().toInt(),
 	       bitrate,lib_quality_spin->value());
+  if(fmt==RDSettings::Copy) {
+    lib_channels_box->setEnabled(false);
+    lib_samprate_box->setEnabled(false);
+    lib_channels_label->setEnabled(false);
+    lib_samprate_label->setEnabled(false);
+  }
+  else {
+    lib_channels_box->setEnabled(true);
+    lib_samprate_box->setEnabled(true);
+    lib_channels_label->setEnabled(true);
+    lib_samprate_label->setEnabled(true);
+  }
 }
 
 
@@ -283,6 +311,11 @@
       lib_settings->setQuality(lib_quality_spin->value());
       break;
       
+      case RDSettings::Copy:
+	lib_settings->setBitRate(0);
+	lib_settings->setQuality(0);
+	break;
+
     default:   // Custom format
       for(unsigned i=0;i<lib_encoders->encoderQuantity();i++) {
 	if(lib_encoders->encoder(i)->id()==lib_settings->format()) {
@@ -851,6 +884,12 @@
 	lib_quality_spin->setValue(qual);
 	break;
 
+      case RDSettings::Copy: 
+	lib_bitrate_box->setDisabled(true);
+	lib_bitrate_label->setDisabled(true);
+	lib_quality_spin->setDisabled(true);
+	lib_quality_label->setDisabled(true);
+	break;
     default:   // Custom format
       lib_channels_box->clear();
       lib_samprate_box->clear();
@@ -926,6 +965,9 @@
   if(str==tr("OggVorbis")) {
     return RDSettings::OggVorbis;
   }
+  if(str==tr("Copy File")) {
+    return RDSettings::Copy;
+  }
   for(unsigned i=0;i<lib_encoders->encoderQuantity();i++) {
     if(str==lib_encoders->encoder(i)->name()) {
       return (RDSettings::Format)lib_encoders->encoder(i)->id();
Index: lib/rdexport_settings_dialog.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdexport_settings_dialog.h,v
retrieving revision 1.6
diff -u -r1.6 rdexport_settings_dialog.h
--- lib/rdexport_settings_dialog.h	18 Sep 2008 19:02:07 -0000	1.6
+++ lib/rdexport_settings_dialog.h	9 Nov 2008 11:13:39 -0000
@@ -60,8 +60,10 @@
    RDStation *lib_station;
    QComboBox *lib_format_box;
    QComboBox *lib_channels_box;
+   QLabel *lib_channels_label;
    QLabel *lib_bitrate_label;
    QComboBox *lib_bitrate_box;
+   QLabel *lib_samprate_label;
    QComboBox *lib_samprate_box;
    QLabel *lib_quality_label;
    QSpinBox *lib_quality_spin;
Index: lib/rdimport_audio.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdimport_audio.cpp,v
retrieving revision 1.22
diff -u -r1.22 rdimport_audio.cpp
--- lib/rdimport_audio.cpp	26 Sep 2008 17:52:22 -0000	1.22
+++ lib/rdimport_audio.cpp	9 Nov 2008 11:13:39 -0000
@@ -62,6 +62,7 @@
   import_station=station;
   import_running=running;
   import_file_filter=RD_AUDIO_FILE_FILTER;
+  open_failed=false;
 
   setCaption(tr("Import/Export Audio File"));
 
@@ -235,7 +236,7 @@
   //
   // Progress Bar
   //
-  import_bar=new QProgressBar(this,"import_bar");
+  import_bar=new QProgressBar(100,this,"import_bar");
   import_bar->setGeometry(10,230,sizeHint().width()-20,20);
 
   //
@@ -519,17 +520,27 @@
   }
   RDWaveFile *wave=new RDWaveFile(import_in_filename_edit->text());
   if(!wave->openWave(import_wavedata)) {
+    if(import_default_settings->format()!=0 && import_default_settings->format()!=3 && import_default_settings->format()!=5) {
     QMessageBox::warning(this,tr("Import Audio File"),tr("Cannot open file!"));
     delete wave;
     return;
   }
+    else {
+      open_failed=true;
+    }  
+  }
   if(wave->type()==RDWaveFile::Unknown) {
+    if(import_default_settings->format()!=5 && import_default_settings->format()!=3) {
     QMessageBox::warning(this,tr("Import Audio File"),
 			 tr("Unsupported file type!"));
     wave->closeWave();
     delete wave;
     return;
   }
+    else {
+      open_failed=true;
+    }  
+  }
   int samplerate=wave->getSamplesPerSec();
   switch(wave->getFormatTag()) {
       case WAVE_FORMAT_PCM:
@@ -547,6 +558,11 @@
 	format_in=0;
 	import_temp_length=wave->getSampleLength()*wave->getChannels()*2;
 	break;
+      
+      case WAVE_FORMAT_VORBIS:
+	format_in=5;
+	import_temp_length=wave->getSampleLength()*wave->getChannels()*2;
+	break;
   }
   delete wave;
 
@@ -603,12 +619,31 @@
 	break;
 
       case RDSettings::MpegL1:
+	break;
       case RDSettings::MpegL3:
+	import_finished_length=
+	  (int)((double)import_temp_length*
+		(double)(import_channels_box->currentItem()+1)*
+		(double)import_default_settings->bitRate()/1411200.0);
+	lib_fmt=RDSettings::MpegL3;
+	break;
       case RDSettings::Flac:
+	import_finished_length=
+	  (int)((double)import_temp_length*
+		(double)(import_channels_box->currentItem()+1)*
+		(double)import_default_settings->bitRate()/1411200.0);
+	lib_fmt=RDSettings::Flac;
+	break;
       case RDSettings::OggVorbis:
+	import_finished_length=
+	  (int)((double)import_temp_length*
+		(double)(import_channels_box->currentItem()+1)*
+		(double)import_default_settings->bitRate()/1411200.0);
+	lib_fmt=RDSettings::OggVorbis;
+	break;
+      case RDSettings::Copy:
 	break;
   }
-
   //
   // Generate Temporary Filenames
   //
@@ -621,6 +656,7 @@
   if(import_normalize_box->isChecked()) {
     normal=pow(10.0,(double)(import_normalize_spin->value())/20.0);
     import_multipass=true;
+    if (lib_fmt!=5 && lib_fmt!=3) {
     cmd=QString().
       sprintf("rd_import_file %6.4f %d %d %s %d %d %d %d %s %s %s",
 	      normal,
@@ -637,7 +673,34 @@
 	      (const char *)import_tempwav_name);
   }
   else {
+      if((format_in!=3 && format_in!=5) || open_failed || samplerate!=import_default_settings->sampleRate()) {
+        cmd=QString().
+          sprintf("rd_import_encode %s %s %d %d %d %d %f %s %s",
+	        (const char *)RDEscapeString(import_in_filename_edit->text()).utf8(),  
+	        RDCut::pathName(import_cutname).ascii(),  
+	        lib_fmt,
+	        import_default_settings->sampleRate(),
+	        import_channels_box->currentItem()+1,
+	        (import_channels_box->
+	         currentItem()+1)*import_default_settings->bitRate()/1000,
+	        normal,
+	        import_config->audioOwner().ascii(),
+	        import_config->audioGroup().ascii());
+      }
+      else {
+        cmd=QString().
+          sprintf("rd_import_copy %s %s %f %s %s",
+	        (const char *)RDEscapeString(import_in_filename_edit->text()).utf8(),  
+	        RDCut::pathName(import_cutname).ascii(),  
+	        normal,
+	        import_config->audioOwner().ascii(),
+	        import_config->audioGroup().ascii());
+      }  	      
+    }	      
+  }
+  else {
     import_multipass=false;
+    if (lib_fmt!=3 && lib_fmt!=5) {
     cmd=QString().
       sprintf("rd_import_file 0 %d %d %s %d %d %d %d %s %s %s",
 	      format_in,
@@ -652,7 +715,31 @@
 	      (const char *)import_tempdat_name,
 	      (const char *)import_tempwav_name);
   }
-  // printf("CMD: %s\n",(const char *)cmd);
+    else {
+      if((format_in!=3 && format_in!=5) || open_failed || samplerate!=import_default_settings->sampleRate()) {
+        cmd=QString().
+          sprintf("rd_import_encode %s %s %d %d %d %d 0 %s %s",
+	        (const char *)RDEscapeString(import_in_filename_edit->text()).utf8(),  
+	        RDCut::pathName(import_cutname).ascii(),  
+	        lib_fmt,
+	        import_default_settings->sampleRate(),
+	        import_channels_box->currentItem()+1,
+	        (import_channels_box->
+	         currentItem()+1)*import_default_settings->bitRate()/1000,
+	        import_config->audioOwner().ascii(),
+	        import_config->audioGroup().ascii());
+      }
+    else {
+        cmd=QString().
+          sprintf("rd_import_copy %s %s 0 %s %s",
+	        (const char *)RDEscapeString(import_in_filename_edit->text()).utf8(),  
+	        RDCut::pathName(import_cutname).ascii(),
+	        import_config->audioOwner().ascii(),
+	        import_config->audioGroup().ascii());
+      }  	      
+    }	      
+  }
+  //printf("CMD: %s\n",(const char *)cmd);
   *import_running=true;
   import_import_aborted=false;
   import_in_selector_button->setDisabled(true);
@@ -662,7 +749,7 @@
     bar_temp_file.setName(import_tempwav_name);
   }
   if((import_script_pid=fork())==0) {
-    if(system((const char *)cmd.utf8())==0) {
+    if(system(cmd.utf8())==0) {
       chown(RDCut::pathName(import_cutname),import_config->uid(),
 	    import_config->gid());
       chmod(RDCut::pathName(import_cutname),
@@ -675,7 +762,7 @@
   }
   else {
     import_bar->setProgress(0);
-    import_bar->setPercentageVisible(true);
+    import_bar->setPercentageVisible(false);
     import_bar_timer->start(IMPORT_BAR_INTERVAL,true);
   }
 }
@@ -686,7 +773,7 @@
   QString cuts_sql;
 
   if(*import_running) {
-    if(import_multipass) {
+/*    if(import_multipass) {
       import_bar->
 	setProgress((int)(50.0*((double)bar_temp_file.
 				size()/(double)import_temp_length+
@@ -696,7 +783,14 @@
     else {
       import_bar->setProgress((int)(100.0*(double)GetFileSize(import_dest_filename)/
 				    (double)import_finished_length));
+    }*/
+    if(import_bar->progress()==100) {
+      import_bar->setProgress(0);
     }
+    else {
+      import_bar->setProgress(import_bar->progress()+10);
+    }
+    
     import_bar_timer->start(IMPORT_BAR_INTERVAL,true);
   }
   else {
@@ -734,7 +828,8 @@
       else {
 	QMessageBox::warning(this,tr("Import Failed"),
 			     tr("The importer encountered an error.\n\
-Please check your importer configuration and try again."));
+Please check your importer configuration\n\
+or the input file and try again."));
       }
     }
     *import_import_metadata=import_in_metadata_box->isChecked();
@@ -788,6 +883,11 @@
 	format_in=wave->getHeadLayer();
 	import_temp_length=wave->getSampleLength()*wave->getChannels()*2;
 	break;
+
+      case WAVE_FORMAT_VORBIS:
+	format_in=5;
+	import_temp_length=wave->getSampleLength()*wave->getChannels()*2;
+	break;
   }
   import_import_aborted=false;
 
@@ -837,6 +937,9 @@
 	      176400.0);
       break;
       
+      case RDSettings::Copy:
+	break;
+
     default:  // Custom format
       import_finished_length=0;
       custom_cmd=import_settings->
@@ -854,11 +957,12 @@
 
   QString cmd;
   float normal=0.0;
-  if(import_normalize_box->isChecked()) {
-    normal=pow(10.0,(double)(import_normalize_spin->value())/20.0);
-    import_multipass=true;
-    cmd=QString().
-      sprintf("rd_export_file %6.4f %d %d %s %d %d %d %d %d %s %s %s",
+  if(import_settings->format()<99) {
+    if(import_normalize_box->isChecked()) {
+      normal=pow(10.0,(double)(import_normalize_spin->value())/20.0);
+      import_multipass=true;
+      cmd=QString().
+        sprintf("rd_export_file %6.4f %d %d %s %d %d %d %d %d %s %s %s",
 	      normal,
 	      format_in,
 	      samplerate,
@@ -871,11 +975,11 @@
 	      (const char *)RDEscapeString(import_out_filename_edit->text()).utf8(),
 	      (const char *)import_tempdat_name,
 	      (const char *)import_tempwav_name);
-  }
-  else {
-    import_multipass=false;
-    cmd=QString().
-      sprintf("rd_export_file 0 %d %d %s %d %d %d %d %d %s %s %s",
+    }
+    else {
+      import_multipass=false;
+      cmd=QString().
+        sprintf("rd_export_file 0 %d %d %s %d %d %d %d %d %s %s %s",
 	      format_in,
 	      samplerate,
 	      RDCut::pathName(import_cutname).ascii(),  
@@ -887,6 +991,12 @@
 	      (const char *)RDEscapeString(import_out_filename_edit->text()).utf8(),  
 	      (const char *)import_tempdat_name,
 	      (const char *)import_tempwav_name);
+    }
+  }
+  else { 
+    cmd=QString().
+      sprintf("cp %s %s",RDCut::pathName(import_cutname).ascii(),
+	      (const char *)(const char *)RDEscapeString(import_out_filename_edit->text()).utf8());
   }
   if(!custom_cmd.isEmpty()) {
     cmd+=" \""+custom_cmd+"\"";
Index: lib/rdimport_audio.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdimport_audio.h,v
retrieving revision 1.8
diff -u -r1.8 rdimport_audio.h
--- lib/rdimport_audio.h	14 Sep 2007 14:06:24 -0000	1.8
+++ lib/rdimport_audio.h	9 Nov 2008 11:13:39 -0000
@@ -143,6 +143,7 @@
   RDWaveData *import_wavedata;
   QString import_tempwav_name;
   QString import_tempdat_name;
+  bool open_failed;
 };
 
 
Index: lib/rdlibrary_conf.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdlibrary_conf.cpp,v
retrieving revision 1.22
diff -u -r1.22 rdlibrary_conf.cpp
--- lib/rdlibrary_conf.cpp	4 Aug 2008 19:05:33 -0000	1.22
+++ lib/rdlibrary_conf.cpp	9 Nov 2008 11:13:39 -0000
@@ -329,13 +329,24 @@
     s->setChannels(q->value(0).toUInt());
     s->setSampleRate(q->value(1).toUInt());
     switch(q->value(2).toInt()) {
-	case 0:
+	case RDSettings::Pcm16:
 	  s->setFormat(RDSettings::Pcm16);
 	  break;
-
-	case 1:
+	case RDSettings::MpegL1:
+	  s->setFormat(RDSettings::MpegL1);
+	  break;
+	case RDSettings::MpegL2:
 	  s->setFormat(RDSettings::MpegL2);
 	  break;
+	case RDSettings::MpegL3:
+	  s->setFormat(RDSettings::MpegL3);
+	  break;
+	case RDSettings::OggVorbis:
+	  s->setFormat(RDSettings::OggVorbis);
+	  break;
+	case RDSettings::Flac:
+	  s->setFormat(RDSettings::Flac);
+	  break;
     }
     s->setBitRate(q->value(3).toUInt());
     s->setNormalizationLevel(q->value(4).toUInt());
Index: lib/rdlogedit_conf.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdlogedit_conf.cpp,v
retrieving revision 1.11
diff -u -r1.11 rdlogedit_conf.cpp
--- lib/rdlogedit_conf.cpp	4 Aug 2008 19:05:33 -0000	1.11
+++ lib/rdlogedit_conf.cpp	9 Nov 2008 11:13:39 -0000
@@ -292,13 +292,24 @@
     s->setChannels(q->value(0).toUInt());
     s->setSampleRate(q->value(1).toUInt());
     switch(q->value(2).toInt()) {
-	case 0:
+	case RDSettings::Pcm16:
 	  s->setFormat(RDSettings::Pcm16);
 	  break;
-
-	case 1:
+	case RDSettings::MpegL1:
+	  s->setFormat(RDSettings::MpegL1);
+	  break;
+	case RDSettings::MpegL2:
 	  s->setFormat(RDSettings::MpegL2);
 	  break;
+	case RDSettings::MpegL3:
+	  s->setFormat(RDSettings::MpegL3);
+	  break;
+	case RDSettings::OggVorbis:
+	  s->setFormat(RDSettings::OggVorbis);
+	  break;
+	case RDSettings::Flac:
+	  s->setFormat(RDSettings::Flac);
+	  break;
     }
     s->setBitRate(q->value(3).toUInt());
     s->setNormalizationLevel(q->value(4).toUInt());
Index: lib/rdsettings.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdsettings.cpp,v
retrieving revision 1.9
diff -u -r1.9 rdsettings.cpp
--- lib/rdsettings.cpp	18 Sep 2008 19:02:09 -0000	1.9
+++ lib/rdsettings.cpp	9 Nov 2008 11:13:39 -0000
@@ -187,6 +187,10 @@
       desc=QString().sprintf("OggVorbis, Qual %d, ",set_quality);
       break;
       
+      case RDSettings::Copy:
+	desc=QString().sprintf("Copy File ");
+	break;
+
     default:  // Custom format
       if(set_format_name.isEmpty()) {
 	sql=QString().sprintf("select NAME from ENCODERS where ID=%d",
@@ -208,18 +212,21 @@
   if(set_sample_rate>0) {
     desc+=QString().sprintf("%d samp/sec, ",set_sample_rate);
   }
-  switch(set_channels) {
-      case 1:
-	desc+="Mono";
-	break;
-
-      case 2:
-	desc+="Stereo";
-	break;
-
-      default:
-	desc+=QString().sprintf("%d chans",set_channels);
-	break;
+    if(set_format!=RDSettings::Copy) {
+      desc+=QString().sprintf("%d samp/sec, ",set_sample_rate);
+      switch(set_channels) {
+        case 1:
+	  desc+="Mono";
+	  break;
+
+        case 2:
+	  desc+="Stereo";
+	  break;
+
+        default:
+	  desc+=QString().sprintf("%d chans",set_channels);
+	  break;
+    }
   }
   return desc;
 }
@@ -265,6 +272,9 @@
 			     RDSettings::Format fmt)
 {
   QString ext;
+  if(fmt==RDSettings::Copy) {
+    return pathname;
+  }
   int index=pathname.findRev(".");
   if(index<0) {
     return pathname+"."+defaultExtension(stationname,fmt);
Index: lib/rdsettings.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdsettings.h,v
retrieving revision 1.8
diff -u -r1.8 rdsettings.h
--- lib/rdsettings.h	18 Sep 2008 19:02:09 -0000	1.8
+++ lib/rdsettings.h	9 Nov 2008 11:13:39 -0000
@@ -28,7 +28,7 @@
 class RDSettings
 {
  public:
-  enum Format {Pcm16=0,MpegL1=1,MpegL2=2,MpegL3=3,Flac=4,OggVorbis=5};
+  enum Format {Pcm16=0,MpegL1=1,MpegL2=2,MpegL3=3,Flac=4,OggVorbis=5,Copy=99};
   RDSettings();
   RDSettings::Format format() const;
   void setFormat(Format format);
Index: lib/rdwavefile.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdwavefile.cpp,v
retrieving revision 1.13
diff -u -r1.13 rdwavefile.cpp
--- lib/rdwavefile.cpp	16 Oct 2008 19:28:38 -0000	1.13
+++ lib/rdwavefile.cpp	9 Nov 2008 11:13:40 -0000
@@ -24,6 +24,8 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <unistd.h>
+#include <iostream>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <syslog.h>
@@ -31,8 +33,6 @@
 #include <fcntl.h>
 #include <arpa/inet.h>
 
-#include <id3/tag.h>
-#include <id3/misc_support.h>
 #include <FLAC/metadata.h>
 
 #include <qobject.h>
@@ -43,6 +43,1041 @@
 #include <rdwavefile.h>
 #include <rdconf.h>
 
+#include <id3/tag.h>
+#include <id3/misc_support.h>
+
+#include <mad.h> 
+#include <qfile.h>
+#include <map>
+
+
+// Taglib for reading OGG Metadata
+#include <taglib/taglib.h>
+#include <taglib/tag.h>
+#include <taglib/fileref.h>
+// 
+
+#ifndef _AFLIBMPGFILE_H
+#define _AFLIBMPGFILE_H
+
+#define INPUT_BUFFER_SIZE	(4*8192)
+#define OUTPUT_BUFFER_SIZE	8192 /* Must be an integer multiple of 4. */
+class Mpegtoraw;
+
+class RMpegFile  {
+
+   public:
+
+      RMpegFile();
+
+      ~RMpegFile();
+
+      bool 
+	 afopen(
+	       QFile& wave_file 
+	       );
+
+      void 
+	 afclose();
+
+      // Read len shorts from mpeg file into p_data.
+      // Return shorts read.
+      int 
+	 afread(
+	       signed short * p_data,
+	       int len
+	       );
+
+      int 
+	 afread(
+	       float * p_data,
+	       int len
+	       );
+
+      int
+	 afseek( int position, int whence);
+
+      bool IsMpeg(const char *);
+      // General
+      int  getVersion(void)   const {return _version;};
+      int  getLayer(void)     const {return _layer;};
+      // Frequency and bitrate
+      int  getFrequency(void) const {return _frequency;};
+      int  getBitrate(void)   const {return _bitrate;};
+      int getTotalSamples(void) const 
+      //{return _total_frames*_samples_per_frame;};
+      {return _total_samples;};
+      int getDataLength(void) const { return _data_length;};
+      int getDataStart(void) const { return _data_start;};
+      int getChannels(void) const { return _channels;};
+   private:
+
+      signed short MadFixedToSshort(mad_fixed_t Fixed);
+      float MadFixedToFloat(mad_fixed_t Fixed);
+      unsigned long seekFrame(unsigned long frame);
+      int MadDecodeFrame(signed short * buffer, unsigned long frame);
+      bool MadDecodeHeader(unsigned long frames);
+      size_t getOffset(unsigned long frame);
+
+      std::map<unsigned long,size_t> _frame_offsets;
+
+      struct mad_stream	Stream;
+      struct mad_frame	Frame;
+      struct mad_synth	Synth;
+      mad_timer_t			Timer;
+      int                 _version;
+      int                 _layer;
+      int                 _bitrate;
+      int                 _frequency;
+      int                 _length;
+      long 		_samples_per_frame;
+      long		_total_frames;
+      long		_total_samples;
+      int		_channels;
+      long 			    _buflen;
+      int 			    _bufpos;
+      unsigned long 		_frame_count;
+
+      unsigned char		InputBuffer[INPUT_BUFFER_SIZE+MAD_BUFFER_GUARD],
+				*GuardPtr;
+      int					Status;
+
+
+      //        signed short *          _buffer;
+      signed short		_buffer[OUTPUT_BUFFER_SIZE];
+      QFile               _fd;
+      size_t              _last_read_pos;
+
+
+      bool id3v1_tag;
+      bool id3v2_tag;
+      unsigned id3v2_offset;
+      int _data_length;
+      int _data_start;
+};
+
+
+#endif
+
+#if (MAD_VERSION_MAJOR>=1) || \
+			((MAD_VERSION_MAJOR==0) && \
+			 (((MAD_VERSION_MINOR==14) && \
+			   (MAD_VERSION_PATCH>=2)) || \
+			  (MAD_VERSION_MINOR>14)))
+#define MadErrorString(x) mad_stream_errorstr(x)
+#else
+static const char *MadErrorString(const struct mad_stream *Stream)
+{
+   switch(Stream->error)
+   {
+      /* Generic unrecoverable errors. */
+      case MAD_ERROR_BUFLEN:
+	 return("input buffer too small (or EOF)");
+      case MAD_ERROR_BUFPTR:
+	 return("invalid (null) buffer pointer");
+      case MAD_ERROR_NOMEM:
+	 return("not enough memory");
+
+	 /* Frame header related unrecoverable errors. */
+      case MAD_ERROR_LOSTSYNC:
+	 return("lost synchronization");
+      case MAD_ERROR_BADLAYER:
+	 return("reserved header layer value");
+      case MAD_ERROR_BADBITRATE:
+	 return("forbidden bitrate value");
+      case MAD_ERROR_BADSAMPLERATE:
+	 return("reserved sample frequency value");
+      case MAD_ERROR_BADEMPHASIS:
+	 return("reserved emphasis value");
+
+	 /* Recoverable errors */
+      case MAD_ERROR_BADCRC:
+	 return("CRC check failed");
+      case MAD_ERROR_BADBITALLOC:
+	 return("forbidden bit allocation value");
+      case MAD_ERROR_BADSCALEFACTOR:
+	 return("bad scalefactor index");
+      case MAD_ERROR_BADFRAMELEN:
+	 return("bad frame length");
+      case MAD_ERROR_BADBIGVALUES:
+	 return("bad big_values count");
+      case MAD_ERROR_BADBLOCKTYPE:
+	 return("reserved block_type");
+      case MAD_ERROR_BADSCFSI:
+	 return("bad scalefactor selection info");
+      case MAD_ERROR_BADDATAPTR:
+	 return("bad main_data_begin pointer");
+      case MAD_ERROR_BADPART3LEN:
+	 return("bad audio data length");
+      case MAD_ERROR_BADHUFFTABLE:
+	 return("bad Huffman table select");
+      case MAD_ERROR_BADHUFFDATA:
+	 return("Huffman data overrun");
+      case MAD_ERROR_BADSTEREO:
+	 return("incompatible block_type for JS");
+
+	 /* Unknown error. This switch may be out of sync with libmad's
+	  * defined error codes.
+	  */
+      default:
+	 return("Unknown error code");
+   }
+}
+#endif
+
+/****************************************************************************
+ * Converts a sample from libmad's fixed point number format to a signed	*
+ * short (16 bits).															*
+ ****************************************************************************/
+signed short RMpegFile::MadFixedToSshort(mad_fixed_t Fixed)
+{
+   /* A fixed point number is formed of the following bit pattern:
+    *
+    * SWWWFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+    * MSB                          LSB
+    * S ==> Sign (0 is positive, 1 is negative)
+    * W ==> Whole part bits
+    * F ==> Fractional part bits
+    *
+    * This pattern contains MAD_F_FRACBITS fractional bits, one
+    * should alway use this macro when working on the bits of a fixed
+    * point number. It is not guaranteed to be constant over the
+    * different platforms supported by libmad.
+    *
+    * The signed short value is formed, after clipping, by the least
+    * significant whole part bit, followed by the 15 most significant
+    * fractional part bits. Warning: this is a quick and dirty way to
+    * compute the 16-bit number, madplay includes much better
+    * algorithms.
+    */
+
+   /* Clipping */
+   if(Fixed>=MAD_F_ONE)
+      return(SHRT_MAX);
+   if(Fixed<=-MAD_F_ONE)
+      return(-SHRT_MAX);
+
+   /* Conversion. */
+   Fixed=Fixed>>(MAD_F_FRACBITS-15);
+   return((signed short)Fixed);
+}
+
+/****************************************************************************
+ * Converts a sample from libmad's fixed point number format to a signed	*
+ * short (16 bits).															*
+ ****************************************************************************/
+float RMpegFile::MadFixedToFloat(mad_fixed_t Fixed)
+{
+   /* A fixed point number is formed of the following bit pattern:
+    *
+    * SWWWFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+    * MSB                          LSB
+    * S ==> Sign (0 is positive, 1 is negative)
+    * W ==> Whole part bits
+    * F ==> Fractional part bits
+    *
+    * This pattern contains MAD_F_FRACBITS fractional bits, one
+    * should alway use this macro when working on the bits of a fixed
+    * point number. It is not guaranteed to be constant over the
+    * different platforms supported by libmad.
+    *
+    * The signed short value is formed, after clipping, by the least
+    * significant whole part bit, followed by the 15 most significant
+    * fractional part bits. Warning: this is a quick and dirty way to
+    * compute the 16-bit number, madplay includes much better
+    * algorithms.
+    */
+
+   float f;
+   if (Fixed & (1<<31)) {
+      // negative
+      Fixed = Fixed & ((1<<31)-1); // strip sign
+      f = -(float)Fixed / (1<<MAD_F_FRACBITS);
+   }
+   else {
+      f = (float)Fixed / (1<<MAD_F_FRACBITS);
+   }
+   return f;
+}
+
+size_t RMpegFile::getOffset(unsigned long frame){
+   //unsigned long frame_no=0;
+   size_t offset = 0;
+
+   std::map<unsigned long,size_t>::const_iterator it; 
+   /*
+      for(it = _frame_offsets.begin();it != _frame_offsets.end() && frame_no != frame;it++){
+      offset = it->second;
+      frame_no = it->first;
+      }
+      */
+
+   while(1){
+      it  = _frame_offsets.find(frame);
+      if(it == _frame_offsets.end())
+      {
+	 if(MadDecodeHeader(1)){
+	    offset = _data_start;
+	    break;
+	 }
+      }
+      else
+      {
+	 offset = it->second;
+	 break;
+      }
+   }
+   return offset;
+
+}
+
+   unsigned long
+RMpegFile::seekFrame(unsigned long frame)
+{
+
+   int offset = 0;
+
+   //bool dump_one = true;
+   unsigned long frame_no=0;
+   if(frame >=5){
+      frame_no = frame - 5;
+   } else {
+      frame_no = 0;      
+   }
+
+   offset = getOffset(frame_no);
+   mad_synth_finish(&Synth);
+   mad_frame_finish(&Frame);
+   mad_stream_finish(&Stream);
+
+   mad_stream_init(&Stream);
+   mad_frame_init(&Frame);
+   mad_synth_init(&Synth);
+   mad_timer_reset(&Timer);
+
+   _frame_count = frame_no;
+   GuardPtr = NULL;
+   if(_fd.at(offset)) _last_read_pos = offset;
+   while(frame_no != frame){
+      MadDecodeFrame(_buffer,1);
+      frame_no++;
+   }
+   return frame;
+
+}
+static int PrintFrameInfo(FILE *fp, struct mad_header *Header)
+{
+   const char	*Layer,
+	 *Mode,
+
+	 *Emphasis;
+
+   /* Convert the layer number to it's printed representation. */
+   switch(Header->layer)
+   {
+      case MAD_LAYER_I:
+	 Layer="I";
+	 break;
+      case MAD_LAYER_II:
+	 Layer="II";
+	 break;
+      case MAD_LAYER_III:
+	 Layer="III";
+	 break;
+      default:
+	 Layer="(unexpected layer value)";
+	 break;
+   }
+
+   /* Convert the audio mode to it's printed representation. */
+   switch(Header->mode)
+   {
+      case MAD_MODE_SINGLE_CHANNEL:
+	 Mode="single channel";
+	 break;
+      case MAD_MODE_DUAL_CHANNEL:
+	 Mode="dual channel";
+	 break;
+      case MAD_MODE_JOINT_STEREO:
+	 Mode="joint (MS/intensity) stereo";
+	 break;
+      case MAD_MODE_STEREO:
+	 Mode="normal LR stereo";
+	 break;
+      default:
+	 Mode="(unexpected mode value)";
+	 break;
+   }
+
+   /* Convert the emphasis to it's printed representation. Note that
+    * the MAD_EMPHASIS_RESERVED enumeration value appeared in libmad
+    * version 0.15.0b.
+    */
+   switch(Header->emphasis)
+   {
+      case MAD_EMPHASIS_NONE:
+	 Emphasis="no";
+	 break;
+      case MAD_EMPHASIS_50_15_US:
+	 Emphasis="50/15 us";
+	 break;
+      case MAD_EMPHASIS_CCITT_J_17:
+	 Emphasis="CCITT J.17";
+	 break;
+#if (MAD_VERSION_MAJOR>=1) || \
+	 ((MAD_VERSION_MAJOR==0) && (MAD_VERSION_MINOR>=15))
+      case MAD_EMPHASIS_RESERVED:
+	 Emphasis="reserved(!)";
+	 break;
+#endif
+      default:
+	 Emphasis="(unexpected emphasis value)";
+	 break;
+   }
+
+/*   fprintf(fp,"%lu kb/s audio MPEG layer %s stream %s CRC, "
+	 "%s with %s emphasis at %d Hz sample rate\n",
+	 Header->bitrate,Layer,
+	 Header->flags&MAD_FLAG_PROTECTION?"with":"without",
+	 Mode,Emphasis,Header->samplerate);*/
+   return(ferror(fp));
+}
+
+/****************************************************************************
+ * Main decoding loop. This is where mad is used.							*
+ ****************************************************************************/
+bool RMpegFile::MadDecodeHeader(unsigned long frames)
+{
+   struct mad_header Header;
+   mad_header_init(&Header);
+   Status = 0;
+   while(frames){
+      /* The input bucket must be filled if it becomes empty or if
+       * it's the first execution of the loop.
+       */
+      if(Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN)
+      {
+	 size_t			ReadSize,
+				Remaining;
+	 unsigned char	*ReadStart;
+
+	 /* {2} libmad may not consume all bytes of the input
+	  * buffer. If the last frame in the buffer is not wholly
+	  * contained by it, then that frame's start is pointed by
+	  * the next_frame member of the Stream structure. This
+	  * common situation occurs when mad_frame_decode() fails,
+	  * sets the stream error code to MAD_ERROR_BUFLEN, and
+	  * sets the next_frame pointer to a non NULL value. (See
+	  * also the comment marked {4} bellow.)
+	  *
+	  * When this occurs, the remaining unused bytes must be
+	  * put back at the beginning of the buffer and taken in
+	  * account before refilling the buffer. This means that
+	  * the input buffer must be large enough to hold a whole
+	  * frame at the highest observable bit-rate (currently 448
+	  * kb/s). XXX=XXX Is 2016 bytes the size of the largest
+	  * frame? (448000*(1152/32000))/8
+	  */
+	 _last_read_pos = _fd.at();
+	 if(Stream.next_frame!=NULL)
+	 {
+	    Remaining=Stream.bufend-Stream.next_frame;
+	    memmove(InputBuffer,Stream.next_frame,Remaining);
+	    ReadStart=InputBuffer+Remaining;
+	    ReadSize=INPUT_BUFFER_SIZE-Remaining;
+	    _last_read_pos -= Remaining;
+	 }
+	 else
+	    ReadSize=INPUT_BUFFER_SIZE,
+	       ReadStart=InputBuffer,
+	       Remaining=0;
+
+	 /* Fill-in the buffer. If an error occurs print a message
+	  * and leave the decoding loop. If the end of stream is
+	  * reached we also leave the loop but the return status is
+	  * left untouched.
+	  */
+	 ReadSize=_fd.readBlock((char*)ReadStart,ReadSize);
+	 if(ReadSize<=0)
+	 {
+	    if(ReadSize < 0)
+	       Status=1;
+	    break;
+	 }
+
+	 /* {3} When decoding the last frame of a file, it must be
+	  * followed by MAD_BUFFER_GUARD zero bytes if one wants to
+	  * decode that last frame. When the end of file is
+	  * detected we append that quantity of bytes at the end of
+	  * the available data. Note that the buffer can't overflow
+	  * as the guard size was allocated but not used the the
+	  * buffer management code. (See also the comment marked
+	  * {1}.)
+	  *
+	  * In a message to the mad-dev mailing list on May 29th,
+	  * 2001, Rob Leslie explains the guard zone as follows:
+	  *
+	  *    "The reason for MAD_BUFFER_GUARD has to do with the
+	  *    way decoding is performed. In Layer III, Huffman
+	  *    decoding may inadvertently read a few bytes beyond
+	  *    the end of the buffer in the case of certain invalid
+	  *    input. This is not detected until after the fact. To
+	  *    prevent this from causing problems, and also to
+	  *    ensure the next frame's main_data_begin pointer is
+	  *    always accessible, MAD requires MAD_BUFFER_GUARD
+	  *    (currently 8) bytes to be present in the buffer past
+	  *    the end of the current frame in order to decode the
+	  *    frame."
+	  */
+	 if(_fd.atEnd())
+	 {
+	    GuardPtr=ReadStart+ReadSize;
+	    memset(GuardPtr,0,MAD_BUFFER_GUARD);
+	    ReadSize+=MAD_BUFFER_GUARD;
+	 }
+
+	 /* Pipe the new buffer content to libmad's stream decoder
+	  * facility.
+	  */
+	 mad_stream_buffer(&Stream,(unsigned char*)InputBuffer,ReadSize+Remaining);
+	 Stream.error=MAD_ERROR_NONE;
+      }
+
+      /* Decode the next MPEG frame. The streams is read from the
+       * buffer, its constituents are break down and stored the the
+       * Frame structure, ready for examination/alteration or PCM
+       * synthesis. Decoding options are carried in the Frame
+       * structure from the Stream structure.
+       *
+       * Error handling: mad_frame_decode() returns a non zero value
+       * when an error occurs. The error condition can be checked in
+       * the error member of the Stream structure. A mad error is
+       * recoverable or fatal, the error status is checked with the
+       * MAD_RECOVERABLE macro.
+       *
+       * {4} When a fatal error is encountered all decoding
+       * activities shall be stopped, except when a MAD_ERROR_BUFLEN
+       * is signaled. This condition means that the
+       * mad_frame_decode() function needs more input to complete
+       * its work. One shall refill the buffer and repeat the
+       * mad_frame_decode() call. Some bytes may be left unused at
+       * the end of the buffer if those bytes forms an incomplete
+       * frame. Before refilling, the remaining bytes must be moved
+       * to the beginning of the buffer and used for input for the
+       * next mad_frame_decode() invocation. (See the comments
+       * marked {2} earlier for more details.)
+       *
+       * Recoverable errors are caused by malformed bit-streams, in
+       * this case one can call again mad_frame_decode() in order to
+       * skip the faulty part and re-sync to the next frame.
+       */
+      if(mad_header_decode(&Header,&Stream))
+      {
+	 //fprintf(stderr,"%s\n",MadErrorString(&Stream));
+	 if(MAD_RECOVERABLE(Stream.error))
+	 {
+	    /* Do not print a message if the error is a loss of
+	     * synchronization and this loss is due to the end of
+	     * stream guard bytes. (See the comments marked {3}
+	     * supra for more informations about guard bytes.)
+	     */
+	    if(Stream.error!=MAD_ERROR_LOSTSYNC ||
+		  Stream.this_frame!=(unsigned char*)GuardPtr)
+	    {
+	    }
+	    continue;
+	 }
+	 else
+	    if(Stream.error==MAD_ERROR_BUFLEN)
+	       continue;
+	    else
+	    {
+	       Status=1;
+	       break;
+	    }
+      }
+      frames--;
+
+      std::map<unsigned long,size_t>::const_iterator it; 
+      it  = _frame_offsets.find(_frame_count);
+      if(it == _frame_offsets.end())
+      {
+	 size_t this_frame_at = _last_read_pos + Stream.this_frame - Stream.buffer;
+
+	 std::pair<unsigned long,size_t> offset(_frame_count,this_frame_at);
+	 _frame_offsets.insert(offset);
+      }
+
+      /* Accounting. The computed frame duration is in the frame
+       * header structure. It is expressed as a fixed point number
+       * whole data type is mad_timer_t. It is different from the
+       * samples fixed point format and unlike it, it can't directly
+       * be added or subtracted. The timer module provides several
+       * functions to operate on such numbers. Be careful there, as
+       * some functions of libmad's timer module receive some of
+       * their mad_timer_t arguments by value!
+       */
+      _frame_count++;
+   }
+   return Status;
+}
+
+/****************************************************************************
+ * Main decoding loop. This is where mad is used.							*
+ ****************************************************************************/
+int RMpegFile::MadDecodeFrame(signed short * buffer, unsigned long frames)
+{
+   // unsigned char * c_buffer = buffer;
+   signed short * head = buffer;
+
+   while(frames){
+      /* The input bucket must be filled if it becomes empty or if
+       * it's the first execution of the loop.
+       */
+      if(Stream.buffer==NULL || Stream.error==MAD_ERROR_BUFLEN)
+      {
+	 size_t			ReadSize,
+				Remaining;
+	 unsigned char	*ReadStart;
+
+	 /* {2} libmad may not consume all bytes of the input
+	  * buffer. If the last frame in the buffer is not wholly
+	  * contained by it, then that frame's start is pointed by
+	  * the next_frame member of the Stream structure. This
+	  * common situation occurs when mad_frame_decode() fails,
+	  * sets the stream error code to MAD_ERROR_BUFLEN, and
+	  * sets the next_frame pointer to a non NULL value. (See
+	  * also the comment marked {4} bellow.)
+	  *
+	  * When this occurs, the remaining unused bytes must be
+	  * PUT back at the beginning of the buffer and taken in
+	  * account before refilling the buffer. This means that
+	  * the input buffer must be large enough to hold a whole
+	  * frame at the highest observable bit-rate (currently 448
+	  * kb/s). XXX=XXX Is 2016 bytes the size of the largest
+	  * frame? (448000*(1152/32000))/8
+	  */
+	 _last_read_pos = _fd.at();
+	 if(Stream.next_frame!=NULL)
+	 {
+	    Remaining=Stream.bufend-Stream.next_frame;
+	    memmove(InputBuffer,Stream.next_frame,Remaining);
+	    ReadStart=InputBuffer+Remaining;
+	    ReadSize=INPUT_BUFFER_SIZE-Remaining;
+	    _last_read_pos -= Remaining;
+	 }
+	 else
+	    ReadSize=INPUT_BUFFER_SIZE,
+	       ReadStart=InputBuffer,
+	       Remaining=0;
+
+	 /* Fill-in the buffer. If an error occurs print a message
+	  * and leave the decoding loop. If the end of stream is
+	  * reached we also leave the loop but the return status is
+	  * left untouched.
+	  */
+	 ReadSize=_fd.readBlock((char*)ReadStart,ReadSize);
+	 if(ReadSize<=0)
+	 {
+	    if(ReadSize < 0)
+	       Status=1;
+	    break;
+	 }
+
+	 /* {3} When decoding the last frame of a file, it must be
+	  * followed by MAD_BUFFER_GUARD zero bytes if one wants to
+	  * decode that last frame. When the end of file is
+	  * detected we append that quantity of bytes at the end of
+	  * the available data. Note that the buffer can't overflow
+	  * as the guard size was allocated but not used the the
+	  * buffer management code. (See also the comment marked
+	  * {1}.)
+	  *
+	  * In a message to the mad-dev mailing list on May 29th,
+	  * 2001, Rob Leslie explains the guard zone as follows:
+	  *
+	  *    "The reason for MAD_BUFFER_GUARD has to do with the
+	  *    way decoding is performed. In Layer III, Huffman
+	  *    decoding may inadvertently read a few bytes beyond
+	  *    the end of the buffer in the case of certain invalid
+	  *    input. This is not detected until after the fact. To
+	  *    prevent this from causing problems, and also to
+	  *    ensure the next frame's main_data_begin pointer is
+	  *    always accessible, MAD requires MAD_BUFFER_GUARD
+	  *    (currently 8) bytes to be present in the buffer past
+	  *    the end of the current frame in order to decode the
+	  *    frame."
+	  */
+	 if(_fd.atEnd())
+	 {
+	    GuardPtr=ReadStart+ReadSize;
+	    memset(GuardPtr,0,MAD_BUFFER_GUARD);
+	    ReadSize+=MAD_BUFFER_GUARD;
+	 }
+
+	 /* Pipe the new buffer content to libmad's stream decoder
+	  * facility.
+	  */
+	 mad_stream_buffer(&Stream,(unsigned char*)InputBuffer,ReadSize+Remaining);
+	 Stream.error=MAD_ERROR_NONE;
+      }
+
+      /* Decode the next MPEG frame. The streams is read from the
+       * buffer, its constituents are break down and stored the the
+       * Frame structure, ready for examination/alteration or PCM
+       * synthesis. Decoding options are carried in the Frame
+       * structure from the Stream structure.
+       *
+       * Error handling: mad_frame_decode() returns a non zero value
+       * when an error occurs. The error condition can be checked in
+       * the error member of the Stream structure. A mad error is
+       * recoverable or fatal, the error status is checked with the
+       * MAD_RECOVERABLE macro.
+       *
+       * {4} When a fatal error is encountered all decoding
+       * activities shall be stopped, except when a MAD_ERROR_BUFLEN
+       * is signaled. This condition means that the
+       * mad_frame_decode() function needs more input to complete
+       * its work. One shall refill the buffer and repeat the
+       * mad_frame_decode() call. Some bytes may be left unused at
+       * the end of the buffer if those bytes forms an incomplete
+       * frame. Before refilling, the remaining bytes must be moved
+       * to the beginning of the buffer and used for input for the
+       * next mad_frame_decode() invocation. (See the comments
+       * marked {2} earlier for more details.)
+       *
+       * Recoverable errors are caused by malformed bit-streams, in
+       * this case one can call again mad_frame_decode() in order to
+       * skip the faulty part and re-sync to the next frame.
+       */
+      if(mad_frame_decode(&Frame,&Stream))
+      {
+	 //fprintf(stderr,"%s\n",MadErrorString(&Stream));
+	 if(MAD_RECOVERABLE(Stream.error))
+	 {
+	    /* Do not print a message if the error is a loss of
+	     * synchronization and this loss is due to the end of
+	     * stream guard bytes. (See the comments marked {3}
+	     * supra for more informations about guard bytes.)
+	     */
+	    if(Stream.error!=MAD_ERROR_LOSTSYNC ||
+		  Stream.this_frame!=(unsigned char*)GuardPtr)
+	    {
+	    }
+	    continue;
+	 }
+	 else
+	    if(Stream.error==MAD_ERROR_BUFLEN)
+	       continue;
+	    else
+	    {
+	       Status=1;
+	       break;
+	    }
+      }
+      frames--;
+
+      std::map<unsigned long,size_t>::const_iterator it; 
+      it  = _frame_offsets.find(_frame_count);
+      if(it == _frame_offsets.end())
+      {
+	 size_t this_frame_at = _last_read_pos + Stream.this_frame - Stream.buffer;
+
+	 std::pair<unsigned long,size_t> offset(_frame_count,this_frame_at);
+	 _frame_offsets.insert(offset);
+      }
+
+      /* The characteristics of the stream's first frame is printed
+       * on stderr. The first frame is representative of the entire
+       * stream.
+       */
+      if(_frame_count==0)
+	 if(PrintFrameInfo(stderr,&Frame.header))
+	 {
+	    Status=1;
+	    break;
+	 }
+
+      /* Accounting. The computed frame duration is in the frame
+       * header structure. It is expressed as a fixed point number
+       * whole data type is mad_timer_t. It is different from the
+       * samples fixed point format and unlike it, it can't directly
+       * be added or subtracted. The timer module provides several
+       * functions to operate on such numbers. Be careful there, as
+       * some functions of libmad's timer module receive some of
+       * their mad_timer_t arguments by value!
+       */
+      _frame_count++;
+      mad_timer_add(&Timer,Frame.header.duration);
+
+      /* Once decoded the frame is synthesized to PCM samples. No errors
+       * are reported by mad_synth_frame();
+       */
+      mad_synth_frame(&Synth,&Frame);
+
+      /* Synthesized samples must be converted from libmad's fixed
+       * point number to the consumer format. Here we use unsigned
+       * 16 bit big endian integers on two channels. Integer samples
+       * are temporarily stored in a buffer that is flushed when
+       * full.
+       */
+      for(int i=0;i<Synth.pcm.length;i++)
+      {
+	 signed short	Sample;
+
+	 /* Left channel */
+	 Sample=MadFixedToSshort(Synth.pcm.samples[0][i]);
+	 *(buffer++)=Sample;
+	 /*
+	  *(c_buffer++)=Sample>>8;
+	  *(c_buffer++)=Sample&0xff;
+	  */
+
+	 /* Right channel. If the decoded stream is monophonic then
+	  * the right output channel is the same as the left one.
+	  */
+	 if(MAD_NCHANNELS(&Frame.header)==2)
+	 {
+	    Sample=MadFixedToSshort(Synth.pcm.samples[1][i]);
+	 }
+	 *(buffer++)=Sample;
+	    /*
+	     *(c_buffer++)=Sample>>8;
+	     *(c_buffer++)=Sample&0xff;
+	     */
+
+
+      }
+   }
+   return buffer - head;
+}
+
+//#define RMPEGFILE_SHOW_SLOTS 1
+RMpegFile::RMpegFile() 
+{
+   /* First the structures used by libmad must be initialized. */
+   mad_stream_init(&Stream);
+   mad_frame_init(&Frame);
+   mad_synth_init(&Synth);
+   mad_timer_reset(&Timer);
+}
+
+RMpegFile::~RMpegFile()
+{
+   mad_synth_finish(&Synth);
+   mad_frame_finish(&Frame);
+   mad_stream_finish(&Stream);
+   _fd.close();
+}
+
+void 
+RMpegFile::afclose()
+{
+   _fd.close();
+}
+
+bool
+RMpegFile::afopen(
+      QFile& wave_file
+      )
+{
+   id3v1_tag = false;
+   id3v2_tag = false;
+   id3v2_offset = 0;
+   _bufpos = _buflen = _frame_count = 0;
+   // This function needs to be redone to find the header info correctly
+   // This function will open an existing MP3 file.
+   ID3_Tag id3_tag(QCString().sprintf("%s",(const char *)wave_file.name().utf8()));
+   const Mp3_Headerinfo* mp3info;
+   mp3info = id3_tag.GetMp3HeaderInfo();
+        
+   if(mp3info){
+      switch(mp3info->version){
+	 case MPEGVERSION_1:
+	    _version = 0;
+	    _samples_per_frame = 1152; 
+	    break;
+	 case MPEGVERSION_2:
+	    _version = 1;
+	    _samples_per_frame = 576; 
+	    break;
+	 case MPEGVERSION_2_5:
+	    _version = 2;
+	    _samples_per_frame = 576; 
+	    break;
+	 default:
+	    return false;
+	    break;
+      }
+      switch (mp3info->layer)
+      {
+         case MPEGLAYER_III:
+            _layer = 3;
+            break;
+         case MPEGLAYER_II:
+            _layer = 2;
+            break;
+         case MPEGLAYER_I:
+            _layer = 1;
+            break;
+         default:
+  	    return false;
+            break;
+      }
+      switch (mp3info->channelmode)
+      {
+         case MP3CHANNELMODE_STEREO:
+         case MP3CHANNELMODE_JOINT_STEREO:
+         case MP3CHANNELMODE_DUAL_CHANNEL:
+         case MP3CHANNELMODE_SINGLE_CHANNEL:
+         case MP3CHANNELMODE_FALSE:
+            break;
+      }
+      _channels = 2;
+
+      _bitrate = mp3info->bitrate;
+      _frequency = mp3info->frequency;
+      _total_samples = ((mp3info->time)+1)*_frequency;
+      _total_frames = _total_samples / _samples_per_frame;
+//      _total_frames = mp3info->frames;
+//      _total_samples = _total_frames * _samples_per_frame;
+   } else { return false; }
+   
+   _fd.setName(wave_file.name());
+   if(!_fd.open(IO_ReadOnly)) {
+	   return false;
+   }
+   _fd.at(0);
+
+
+   _data_length=wave_file.size();
+   if(id3v1_tag) {
+      _data_length-=128;
+   }
+   if(id3v2_tag) {
+      _data_length-=id3v2_offset;
+   }
+   _data_start=id3v2_offset;
+
+   short buf;
+   if(!afread(&buf,1)){
+      _fd.close();
+      return false;
+   }
+   afseek(0, SEEK_SET);
+
+   return (true);
+}
+
+int
+RMpegFile::afread(
+      signed short * p_data,
+      int len
+      )
+{
+   if(_fd.handle() == -1) return 0;
+   long   new_length = 0;
+
+   while(new_length < len){
+      if (_bufpos == _buflen){
+	 _buflen = MadDecodeFrame(_buffer,1);
+	 _bufpos = 0;
+	 if(_buflen == 0 )
+	    break;
+      }
+      *(p_data + new_length++) = _buffer[_bufpos++];
+   }
+
+   if (new_length != len)
+      _total_frames = _frame_count;
+
+#ifdef RMPEGFILE_SHOW_SLOTS
+   fprintf(stderr,"length requested = %d returned %d\n",len, _current_position);
+#endif
+
+   return(new_length);
+}
+
+int
+RMpegFile::afread(
+      float * p_data,
+      int len
+      )
+{
+   if(_fd.handle() == -1) return 0;
+   long   new_length = 0;
+
+   while(new_length < len){
+      if (_bufpos == _buflen){
+	 _buflen = MadDecodeFrame(_buffer,1);
+	 _bufpos = 0;
+	 if(_buflen == 0 )
+	    break;
+      }
+      *(p_data + new_length++) = MadFixedToFloat(_buffer[_bufpos++]);
+   }
+
+   if (new_length != len)
+      _total_frames = _frame_count;
+
+#ifdef RMPEGFILE_SHOW_SLOTS
+   fprintf(stderr,"length requested = %d returned %d\n",len, _current_position);
+#endif
+
+   return(new_length);
+}
+
+int
+RMpegFile::afseek( int position, int whence)
+{
+   if(_fd.handle() == -1) return 0;
+   position /= 4;
+   switch(whence) {
+      case SEEK_SET:
+	 break;
+      case SEEK_CUR:
+	 position += _frame_count*_samples_per_frame + _bufpos;
+	 break;
+      case SEEK_END:
+	 position = _total_frames * _samples_per_frame - position;
+	 if(position < 0)
+	    position = 0;
+	 break;
+   }
+   // get remainder
+   _bufpos = (position) % _samples_per_frame;
+   int frame_no = (position - _bufpos)/_samples_per_frame;
+
+   // IF we are beyond last frame then we are done
+   if (frame_no > _total_frames)
+   {
+      return (_frame_count*_samples_per_frame + _bufpos) * 2;
+   }
+   else if(_frame_count != frame_no)
+   {
+      _frame_count = seekFrame(frame_no);
+      _buflen = MadDecodeFrame(_buffer,1); 
+   }
+   if(_buflen < _bufpos){
+      _bufpos = _buflen;
+      position = _frame_count*_samples_per_frame + _bufpos;
+   }
+#ifdef RMPEGFILE_SHOW_SLOTS
+   fprintf(stderr,"requested seek to: %d\n _frame_count: %d of %d total frames.\n _last_read_pos: %d\n _buflen: %d _bufpos: %d\n",position, _frame_count, _total_frames, _last_read_pos,_buflen,_bufpos);
+#endif
+   return position*4;
+}
+
+bool RMpegFile::IsMpeg(const char * file_name)
+{
+   QFile file(file_name);
+   if(!afopen(file))
+      return false;
+   _fd.close();
+   return true;
+  // using namespace TagLib;
+
+}
 
 RDWaveFile::RDWaveFile(QString file_name)
 {
@@ -51,9 +1086,12 @@
   //
   wave_file.setName(file_name);
   wave_data=NULL;
+  mpeg_file=NULL;
   recordable=false;
   format_chunk=false;
   format_tag=0;
+  energy_tag=0;
+  normalize_level=1.0;
   channels=0;
   samples_per_sec=0;
   avg_bytes_per_sec=0;
@@ -218,8 +1256,32 @@
 	}
 	data_chunk=true;
 	data_start=lseek(wave_file.handle(),0,SEEK_CUR);
+	if(format_tag==WAVE_FORMAT_MPEG) {
+              mpeg_file = new RMpegFile();
+              if(!mpeg_file->afopen(wave_file)) {
+                 delete mpeg_file;
+                 mpeg_file=NULL;
+                 return false;
+              }
+  
+              data_length=mpeg_file->getDataLength();
+              data_start=mpeg_file->getDataStart();
+   
+              bits_per_sample=16;
+              sample_length=mpeg_file->getTotalSamples();
+              ext_time_length=
+                 (unsigned)(1000.0*(double)sample_length/(double)samples_per_sec);
+              time_length=ext_time_length/1000;
+              data_chunk=true;
+              lseek(wave_file.handle(),data_start,SEEK_SET);
+              format_chunk=true;
+   	      ReadNormalizeLevel(wave_file.name());
+              wave_type=RDWaveFile::Mpeg;
+              block_align=2*channels;
+              ReadId3Metadata();
+        }
 	if((!GetFact(wave_file.handle()))||(sample_length==0)) {
-	  if((format_tag!=WAVE_FORMAT_PCM)&&format_chunk) {
+	  if((format_tag!=WAVE_FORMAT_PCM) && format_chunk) {
 #ifdef MPEG_FACT_FUDGE
 	    // Guesstimate the overall sample size
 	    time_length=data_length/avg_bytes_per_sec;
@@ -280,23 +1342,28 @@
 	  wave_file.close();
 	  return false;
 	}
-	data_length=wave_file.size();
-	if(id3v1_tag) {
-	  data_length-=128;
-	}
-	if(id3v2_tag[1]) {
-	  data_length-=id3v2_offset[1];
-	}
-	data_start=id3v2_offset[0];
-	sample_length=1152*(data_length/mpeg_frame_size);
-	ext_time_length=
-	  (unsigned)(1000.0*(double)sample_length/(double)samples_per_sec);
-	time_length=ext_time_length/1000;
-	data_chunk=true;
-	lseek(wave_file.handle(),data_start,SEEK_SET);
-	format_chunk=true;
-	wave_type=RDWaveFile::Mpeg;
-	ReadId3Metadata();
+        mpeg_file = new RMpegFile();
+        if(mpeg_file->afopen(wave_file) == false) {
+            delete mpeg_file;
+            mpeg_file=NULL;
+            return false;
+        } 
+    
+        data_length=mpeg_file->getDataLength();
+        data_start=mpeg_file->getDataStart();
+   
+        bits_per_sample=16;
+        sample_length=mpeg_file->getTotalSamples();
+     	ext_time_length=
+   	       (unsigned)(1000.0*(double)sample_length/(double)samples_per_sec);
+   	time_length=ext_time_length/1000;
+   	data_chunk=true;
+   	lseek(wave_file.handle(),data_start,SEEK_SET);
+   	format_chunk=true;
+      	ReadNormalizeLevel(wave_file.name());
+   	wave_type=RDWaveFile::Mpeg;
+        block_align=2*channels;
+   	ReadId3Metadata();
     	break;
 
       case RDWaveFile::Ogg:
@@ -316,8 +1383,9 @@
 	time_length=(unsigned)ov_time_total(&vorbis_file,-1);
 	data_chunk=true;
 	format_chunk=true;
+        ReadNormalizeLevel(wave_file.name());
 	wave_type=RDWaveFile::Ogg;
-	ValidateMetadata();
+	ReadOggMetadata();
 	return true;
 #else
 	return false;
@@ -392,9 +1460,12 @@
 
 bool RDWaveFile::createWave(RDWaveData *data)
 {
+  QFile energy_file;
+  QString str;
   mode_t prev_mask;
   bool rc;
   wave_data=data;
+  unlink((wave_file.name()+".energy").ascii());
   if(wave_data!=NULL) {
     cart_title=wave_data->title();
     cart_artist=wave_data->artist();
@@ -463,6 +1534,10 @@
 
       case WAVE_FORMAT_VORBIS:
 #ifdef HAVE_VORBIS
+	energy_data.clear();
+	for(int i=0;i<channels;i++) {
+	  energy_data.push_back(0);
+	}
 	avg_bytes_per_sec=2*channels*samples_per_sec;
 	vorbis_info_init(&vorbis_inf);
 	if(vorbis_encode_init_vbr(&vorbis_inf,channels,samples_per_sec,
@@ -512,9 +1587,25 @@
   }
   levl_timestamp=QDateTime(QDate::currentDate(),QTime::currentTime());
   data_length=0;
+  if(energy_tag==1)
+    {
+     energy_file.setName(wave_file.name()+".energy");
+     prev_mask = umask(0113);      // Set umask so files are user and group writable.
+     rc=energy_file.open(IO_ReadWrite|IO_Truncate);
+     umask(prev_mask);
+     energy_file.close();
+    }
   return true;
 }
 
+bool RDWaveFile::recreateEnergy()
+{
+has_energy=false;
+energy_loaded=false;
+unlink(wave_file.name()+".energy");
+GetEnergy();
+return has_energy;
+}
 
 void RDWaveFile::closeWave(int samples)
 {
@@ -522,6 +1613,23 @@
   unsigned csize;
   unsigned lsize=0;
   unsigned cptr;
+  QFile energy_file;
+  QString str;
+  mode_t prev_mask;
+  bool rc;
+
+  if(energy_tag==1) {
+      str=str.sprintf("%f\n",normalize_level);
+      energy_file.setName(wave_file.name()+".energy");
+      prev_mask = umask(0113);      // Set umask so files are user and group writable.
+      rc=energy_file.open(IO_ReadWrite|IO_Truncate);
+      umask(prev_mask);
+      if(rc) {
+         write(energy_file.handle(),(const char*)str,strlen(str));
+         write(energy_file.handle(),&(energy_data[0]),2*energy_data.size());
+         energy_file.close();
+      }
+   }
 
   if(recordable) {
     switch(wave_type) {
@@ -529,7 +1637,7 @@
 	  //
 	  // Write levl chunk
 	  //
-	  if(levl_chunk&&((format_tag==WAVE_FORMAT_PCM)||
+	  if(energy_tag==0&&levl_chunk&&((format_tag==WAVE_FORMAT_PCM)||
 			  ((format_tag==WAVE_FORMAT_MPEG)&&(head_layer==2)))) {
 	    levl_version=0;
 	    levl_format=2;
@@ -549,13 +1657,7 @@
 	    size_buf[3]=(lsize>>24)&0xff;
 	    write(wave_file.handle(),size_buf,4);
 	    write(wave_file.handle(),levl_chunk_data,LEVL_CHUNK_SIZE-4);
-	    // Fixup the endianness
-	    unsigned char * sbuf = new unsigned char [2 * energy_data.size()];
-	    for (unsigned int i=0; i < energy_data.size(); i++){
-	      WriteSword (sbuf,2*i,(unsigned short) energy_data[i]);
-	    }
-	    write(wave_file.handle(),sbuf,2*energy_data.size());
-	    delete [] sbuf;
+	    write(wave_file.handle(),&(energy_data[0]),2*energy_data.size());
 	    ftruncate(wave_file.handle(),lseek(wave_file.handle(),0,SEEK_CUR));
 	  }
 
@@ -669,6 +1771,8 @@
   time_length=0;
   format_chunk=false;
   format_tag=0;
+  energy_tag=0;
+  normalize_level=1.0;
   channels=0;
   samples_per_sec=0;
   avg_bytes_per_sec=0;
@@ -772,6 +1876,10 @@
   encode_quality=5.0f;
   serial_number=-1;
   atx_offset=0;
+  if(mpeg_file!=NULL) {
+    delete mpeg_file;
+  }
+  mpeg_file = NULL;
   av10_chunk=false;
 }
 
@@ -782,6 +1890,10 @@
     lseek(wave_file.handle(),data_start,SEEK_SET);
     ftruncate(wave_file.handle(),data_start);
   }
+  if(mpeg_file!=NULL) {
+    delete mpeg_file;
+  }
+  mpeg_file = NULL;
 }
 
 
@@ -852,19 +1964,32 @@
 int RDWaveFile::readWave(void *buf,int count)
 {
   int stream;
-  int n;
+  int n=0;
   unsigned int pos;
-  int c = 0;
+  int16_t *sample;
 
   switch(wave_type) {
       case RDWaveFile::Ogg:
 #ifdef HAVE_VORBIS
-	n=ov_read(&vorbis_file,(char *)buf,count,0,2,1,&stream);
+	      n = 0;
+	      while(n!=count){
+		    int ret = ov_read(&vorbis_file,(char *)buf+n,count-n,0,2,1,&stream);
+		    if (!ret) break;
+		    n+=ret;
+	      }
+           if(normalize_level != 1.0f){
+	      for (int i=0;i<n/2;i++) {
+             sample=(int16_t *)buf+i;
+            *sample=(int16_t)(normalize_level*(double)*sample);
+	      }
+           }
 	return n;
 #endif  // HAVE_VORBIS
 	return 0;
 
       case RDWaveFile::Wave:
+        switch(format_tag){
+           case WAVE_FORMAT_PCM:
 	pos = lseek(wave_file.handle(),0,SEEK_CUR);
 	//
 	// FIXME: how fix comparing singed (data_start, count) vs. 
@@ -875,20 +2000,49 @@
         if (((pos+count)>(data_start+data_length))&&(data_length>0)) {
           count=count - ( (pos+count) - (data_start+data_length) );
         }
-	c = read(wave_file.handle(),buf,count);
+	if(normalize_level != 1.0f) {
+           n=read(wave_file.handle(),buf,count); 
+           for (int i=0;i<n/2;i++) {
+              sample=(int16_t *)buf+i;
+              *sample=(int16_t)(normalize_level*(double)*sample);
+  	      }
+	  return n;
+          }
+        else {
+	  return read(wave_file.handle(),buf,count);
+          }
+               break;
+            case WAVE_FORMAT_MPEG:
+               {
+                  int16_t *sample;
+                  n = mpeg_file->afread((short*)buf,count/2);
+                  if(normalize_level != 1.0f){
+                     for (int i=0;i<n;i++) {
+                        sample=(int16_t *)buf+i;
+                        *sample=(int16_t)(normalize_level*(double)*sample);
+                     }
+                  }
+               }
+               return n*2;
 	break;
-      default:
-	c = read(wave_file.handle(),buf,count);
   }
-  if ( c <0 ) return 0; // read error
-  // Fixup the buffer for big endian hosts (Wav is defined as LE).
-  if (htonl (1l) == 1){ // Big endian host
-    for (unsigned int i = 0; i < c/2; i++){
-      ((short*)buf)[i] = ReadSword((unsigned char *)buf,2*i);
+  
+       case RDWaveFile::Mpeg:
+         {
+            n = mpeg_file->afread((short*)buf,count/2);
+            if(normalize_level != 1.0f){
+               for (int i=0;i<n;i++) {
+                  sample=(int16_t *)buf+i;
+                  *sample=(int16_t)(normalize_level*(double)*sample);
+               }
     }
   }
+         return n*2;
 
-  return c;
+      default:
+	return read(wave_file.handle(),buf,count);
+  }
+  return 0;
 }
 
 
@@ -952,13 +2106,6 @@
 	}
 	lseek(wave_file.handle(),0,SEEK_END);
 	data_length+=count;
-	// Fixup the buffer for big endian hosts (Wav is defined as LE).
-	if (htonl (1l) == 1l){ // Big endian host
-	  for (unsigned int i = 0; i < count/2; i++){
-	    unsigned short s = ((unsigned short*)buf)[i];
-	    WriteSword((unsigned char *)buf,2*i,s);
-	  }
-	}
 	return write(wave_file.handle(),buf,count);
 
       case WAVE_FORMAT_MPEG:
@@ -1005,6 +2152,55 @@
 	return write(wave_file.handle(),buf,count);
 
       case WAVE_FORMAT_VORBIS:
+	  for(int i=0;i<count;i++) {
+	    switch(levl_istate) {
+		case 0:   // Left Channel, LSB
+		  levl_accum=((char *)buf)[i]&0xff;
+		  levl_istate=1;
+		  break;
+
+		case 1:   // Left Channel, MSB
+		  levl_accum|=((((char *)buf)[i]&0xff)<<8);
+		  switch(channels) {
+		      case 1:
+			if(levl_accum>energy_data[energy_data.size()-1]) {
+			  energy_data[energy_data.size()-1]=levl_accum;
+			}
+			if(++levl_block_ptr==1152) {
+			  energy_data.push_back(0);
+			  levl_block_ptr=0;
+			}
+			levl_istate=0;
+			break;
+
+		      case 2:
+			if(levl_accum>energy_data[energy_data.size()-2]) {
+			  energy_data[energy_data.size()-2]=levl_accum;
+			}
+			levl_istate=2;
+			break;
+		  }
+		  break;
+
+		case 2:   // Right Channel, LSB
+		  levl_accum=((char *)buf)[i]&0xff;
+		  levl_istate=3;
+		  break;
+
+		case 3:   // Right Channel, MSB
+		  levl_accum|=((((char *)buf)[i]&0xff)<<8);
+		  if(levl_accum>energy_data[energy_data.size()-1]) {
+		    energy_data[energy_data.size()-1]=levl_accum;
+		  }
+		  if(++levl_block_ptr==1152) {
+		    energy_data.push_back(0);
+		    energy_data.push_back(0);
+		    levl_block_ptr=0;
+		  }
+		  levl_istate=0;
+		  break;
+	    }
+	  }
 	WriteOggBuffer((char *)buf,count);
 	break;
   }
@@ -1031,20 +2227,20 @@
 
 unsigned short RDWaveFile::energy(unsigned frame)
 {
+  GetEnergy();
   if(!has_energy) {
     return 0;
   }
-  GetEnergy();
   return energy_data[frame];
 }
 
 
 int RDWaveFile::readEnergy(unsigned short buf[],int count)
 {
+  GetEnergy();
   if(!has_energy) {
     return 0;
   }
-  GetEnergy();
   for(int i=0;i<count;i++) {
     if((i+energy_ptr)<energy_data.size()) {
       buf[i]=energy_data[i+energy_ptr];
@@ -1084,6 +2280,43 @@
 }
 
 
+void RDWaveFile::normalize(double level)
+{
+  GetEnergy();
+        //
+        // The way sox does this:
+        // - Find the sample with the highest value.  
+        // Should be looking at minimum values too and take the absolute value.
+        double peak_level = 0;
+        for(unsigned i=0;i<energy_data.size();i++) {
+           if(energy_data[i] > peak_level) {
+               peak_level = energy_data[i]; 
+           }
+        }
+        peak_level=peak_level/normalize_level;
+        // - Then we need a ratio to multiple all our samples by.  i.e.
+        // vol_scale * sample will never be greater then SIGNED_SHORT_MAX.
+        double vol_scale = 32768.0f/peak_level; 
+        // - Then we want to allow for adjusting the volume so it's not so full on loud.  
+        // Like set it 13db below the max.  This is where the user selectable level comes in.
+        double scale_level=(level*vol_scale)/normalize_level;
+        normalize_level = level*vol_scale;
+        if( normalize_level==0){
+           normalize_level=1.0f;
+           scale_level=1.0f;
+        }else{
+           for(unsigned i=0;i<energy_data.size();i++) {
+              energy_data[i] *= scale_level;
+           }
+        }
+
+        // I Propose the normalize_level here is the same as sent to rd_import_file.
+        // i.e. normal=pow(10.0,(double)(library_conf->ripperLevel())/20.0);
+        // failing that change it to a int and set the normalize_level to ripperLevel() and 
+        // keep the gory details of converting that to double within this library.
+        energy_tag=1;
+}
+
 int RDWaveFile::seekWave(int offset,int whence)
 {
   int pos;
@@ -1094,10 +2327,10 @@
 	switch(whence) {
 	    case SEEK_SET:
 	      if(ov_pcm_seek(&vorbis_file,offset/(2*channels))==0) {
-	      printf("RDWaveFile::seekWave() = %d\n",offset);
+	      //printf("RDWaveFile::seekWave() = %d\n",offset);
 		return offset;
 	      }
-	      printf("RDWaveFile::seekWave() = -1\n");
+	      //printf("RDWaveFile::seekWave() = -1\n");
 	      return -1;
 	      break;
 
@@ -1115,6 +2348,11 @@
 #endif  // HAVE_VORBIS
 	return -1;
 	break;
+      case RDWaveFile::Mpeg:
+         if(mpeg_file) 
+            return mpeg_file->afseek(offset,whence);
+         return -1;
+         break;
 
       case RDWaveFile::Wave:// FIXME: how fix comparing singed (data_start, offset, pos) vs. unsigned (data_length) ... WAVE standard is 32 bit, but not sure if signed or not... grauf@rfa.org Tue, 04 Apr 2006 21:02:51 -0400
         switch(whence) {
@@ -1184,6 +2422,30 @@
 }
 
 
+void RDWaveFile::setEnergyTag(int format)
+{
+  energy_tag=format;
+}
+
+
+int RDWaveFile::getEnergyTag() const
+{
+  return energy_tag;
+}
+
+
+double RDWaveFile::getNormalizeLevel() const
+{
+  return normalize_level;
+}
+
+
+void RDWaveFile::setNormalizeLevel(double level)
+{
+  normalize_level=level;
+}
+
+
 unsigned short RDWaveFile::getChannels() const
 {
   return channels;
@@ -1958,60 +3220,12 @@
 
 bool RDWaveFile::IsMpeg(int fd)
 {
-  int i;
-  unsigned char buffer[11];
-
-  id3v1_tag=false;
-  id3v2_tag[0]=false;
-  id3v2_tag[1]=false;
-  id3v2_offset[0]=0;
-  id3v2_offset[1]=0;
-
-  lseek(fd,0,SEEK_SET);
-  if((i=read(fd,buffer,10))!=10) {
-    printf("HERE1\n");
-    return false;
-  }
-  buffer[3]=0;
-  if(!strcasecmp((char *)buffer,"ID3")) {
-    id3v2_tag[0]=true;
-    id3v2_offset[0]=
-      (buffer[9]|(buffer[8]<<7)|(buffer[7]<<14)|(buffer[6]<<21))+10;
-  }  
-  lseek(fd,id3v2_offset[0],SEEK_SET);
-  if((i=read(fd,buffer,2))!=2) {
-    printf("HERE2\n");
-    return false;
-  }
-//  if((buffer[0]==0xFF)&&((buffer[1]&0xF0)==0xF0)) {
-  if((buffer[0]==0xFF)&&((buffer[1]&0xE0)==0xE0)) {
-    return true;
-/*
-    lseek(fd,-128,SEEK_END);
-    i=read(fd,buffer,3);
-    buffer[3]=0;
-    if(!strcasecmp("TAG",(char *)buffer)) {
-      id3v1_tag=true;
-    }
-    return true;
-*/
-  }
-  if(buffer[0]==0) {   // Possibly a broken null-padded ID3 tag -- see if
-                       // we can find the start of the MPEG data
-    while(read(fd,buffer,1)==1) {
-      if(buffer[0]==0xFF) {  // Could be it -- check the next byte
-	if(read(fd,buffer,1)==1) {
-	  if((buffer[0]&0xF0)==0xF0) {  // Got it -- fix things up
-	    id3v2_tag[0]=true;
-	    id3v2_offset[0]=lseek(fd,0,SEEK_CUR)-2;
-	    return true;
-	  }
-	}
-      }
-    }
-  }
-    printf("HERE3\n");
-  return false;
+   RMpegFile mpegfile;
+   if(mpegfile.afopen(wave_file)) {
+     mpegfile.afclose();
+     return true;
+   }
+   return false;
 }
 
 
@@ -2413,6 +3627,56 @@
 }
 
 
+
+bool RDWaveFile::ReadEnergyFile(QString wave_file_name)
+{
+  if(has_energy && energy_loaded) return true;
+
+  QFile energy_file;
+  QString str;
+  unsigned char frame[50];
+
+  energy_file.setName(wave_file_name+".energy");
+  if(!energy_file.open(IO_ReadOnly)) 
+    return false;
+  if(energy_file.readLine(str,20) <= 0)
+     return false;
+  normalize_level=str.toDouble();
+  energy_file.close();
+  if(!energy_file.open(IO_ReadOnly)) 
+    return false;
+  read(energy_file.handle(),frame,str.length());
+  while(read(energy_file.handle(),frame,2)>0) {
+      energy_data.push_back(frame[0]+256*frame[1]);
+  }
+/*  for(unsigned i=1;i<((getSampleLength()*getChannels()/1152));i++) {
+    if(read(energy_file.handle(),frame,2)>0) {
+      energy_data.push_back(frame[0]+256*frame[1]);
+    }
+  }*/
+  energy_file.close();
+  energy_loaded=true;
+  has_energy=true;
+  return true;
+}
+
+
+bool RDWaveFile::ReadNormalizeLevel(QString wave_file_name)
+{
+  QFile energy_file;
+  QString str;
+
+  energy_file.setName(wave_file_name+".energy");
+  if(!energy_file.open(IO_ReadOnly)) 
+    return false;
+  if(energy_file.readLine(str,20) <= 0)
+     return false;
+  normalize_level=str.toDouble();
+  energy_file.close();
+  return true;
+}
+
+
 bool RDWaveFile::GetLevl(int fd)
 {
   unsigned size=LEVL_CHUNK_SIZE;
@@ -2425,7 +3689,14 @@
    * Load the chunk
    */
   if(!GetChunk(fd,"levl",&chunk_size,levl_chunk_data,LEVL_CHUNK_SIZE)) {
-    return false;
+  //  if(ReadEnergyFile(wave_file.name())) {
+   //   energy_loaded=true;
+   //   has_energy=true;
+   //   return true;
+   //   }
+  //  else {
+     return false;
+  //  }
   }
   levl_chunk=true;
 
@@ -2900,6 +4171,23 @@
 }
 
 
+void RDWaveFile::ReadOggMetadata()
+{
+ if(wave_data==NULL) {
+    return;
+  }
+  TagLib::FileRef f(QCString().sprintf("%s",(const char *)wave_file.name().utf8()));
+  if(!f.isNull() && f.tag()){
+    TagLib::Tag *tag=f.tag();
+    wave_data->setTitle(TStringToQString(tag->title()));
+    wave_data->setArtist(TStringToQString(tag->artist()));
+    wave_data->setAlbum(TStringToQString(tag->album()));
+    wave_data->setReleaseYear((int)tag->year());
+    wave_data->setMetadataFound(true);
+  } 
+}
+
+
 void RDWaveFile::ReadId3Metadata()
 {
   if(wave_data==NULL) {
@@ -2954,6 +4242,55 @@
 
 bool RDWaveFile::GetMpegHeader(int fd,int offset)
 {
+   if (format_tag == WAVE_FORMAT_MPEG){
+   RMpegFile mpegfile;
+   if(!mpegfile.afopen(wave_file)) return false;
+
+   switch(mpegfile.getVersion())
+   {
+      case 0:
+    mpeg_id=RDWaveFile::Mpeg1;
+	break;
+		  case 1:
+	 mpeg_id=RDWaveFile::Mpeg2;
+		    break;
+		  case 2:
+	 //mpeg_id=RDWaveFile::Mpeg25;
+		    break;
+		  default:
+	 mpeg_id=RDWaveFile::NonMpeg;
+	break;
+
+  }
+
+  //
+   // Layer
+  //
+   head_layer = mpegfile.getLayer();
+
+  //
+   // Bitrate
+  //
+   head_bit_rate = mpegfile.getBitrate();
+
+   //
+   // Sample Rate
+   //
+   samples_per_sec = mpegfile.getFrequency();
+
+  //
+   // Channels 
+  //
+   channels = mpegfile.getChannels();
+
+  //
+  // Frame Size (without padding)
+  //
+  mpeg_frame_size=144*head_bit_rate/samples_per_sec;
+  mpegfile.afclose();
+  return true;
+}
+
   unsigned char buffer[4];
   int n;
   
@@ -3892,6 +5229,7 @@
 {
   int file_ptr;
 
+  ReadEnergyFile(wave_file.name());
   if(energy_loaded) {
     return;
   }
@@ -3915,11 +5253,10 @@
   short max=0;
 
   energy_data.clear();
-
   energy_size=getSampleLength()*getChannels()/1152;
   seekWave(0,SEEK_SET);
   switch(format_tag) {
-      case WAVE_FORMAT_MPEG:
+/*      case WAVE_FORMAT_MPEG:
 	if((head_layer==2)&&(mext_left_energy||mext_right_energy)) {
 	  while(i<energy_size) {
 	    lseek(wave_file.handle(),block_align-5,SEEK_CUR);
@@ -3944,7 +5281,7 @@
 	  return 0;
 	}
 	break;
-
+*/
       case WAVE_FORMAT_PCM:
 	block_size=2304*channels;
 	while(i<energy_size) {
@@ -3968,6 +5305,30 @@
 	return i;
 	break;
 
+      case WAVE_FORMAT_MPEG:
+      case WAVE_FORMAT_VORBIS:
+	block_size=2304*channels;
+	while(i<energy_size) {
+	  if(readWave(pcm,block_size)!=block_size) {
+	    has_energy=true;
+	    return i;
+	  }
+	  for(int j=0;j<channels;j++) {
+	    max=0;
+	    energy_data.push_back(0);
+	    for(int k=0;k<1152;k++) {
+	      offset=2*k*channels+2*j;
+	      if((pcm[offset]+256*pcm[offset+1])>energy_data[i]) {
+		energy_data[i]=pcm[offset]+256*pcm[offset+1];
+	      }
+	    }
+	    i++;
+	  }
+	}
+	has_energy=true;
+	return i;
+	break;
+
       default:
 	has_energy=false;
 	return 0;
@@ -4033,9 +5394,13 @@
 	high=buffer[j][i];
       }
 */
+	    buffer[j][i] = ((buf[i*2*channels + 2*j + 1]<<8) |
+			    (buf[i*2*channels + 2*j] & 0xff))/32768.0f;
+            /* My compilier doesn't like these casts.
       buffer[j][i]=
 	((float)(buf[2*channels*i+2*j]&0xff)+
 	 (256.0f*(float)(buf[2*channels*i+2*j+1]&0xff)))/32768.0f;
+         */
     }
 //    printf("HIGH: %5.3f\n",high);
   }
Index: lib/rdwavefile.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/lib/rdwavefile.h,v
retrieving revision 1.5
diff -u -r1.5 rdwavefile.h
--- lib/rdwavefile.h	16 Oct 2008 19:28:39 -0000	1.5
+++ lib/rdwavefile.h	9 Nov 2008 11:13:41 -0000
@@ -95,6 +95,7 @@
 #define DEFAULT_LEVL_BLOCK_SIZE 1152
 
 
+class RMpegFile;
 /**
  * @short A class for handling Microsoft WAV files.
  * @author Fred Gleason <fredg@wava.com>
@@ -153,6 +154,7 @@
    * Returns true if WAV file was created successfully, otherwise false.
    **/
    bool createWave(RDWaveData *data=NULL);
+   bool recreateEnergy();
 
   /**
    * Open the WAV file for playback.  A WAV file name must first have 
@@ -294,6 +296,8 @@
    **/
    int endTrim(int level);
 
+   void normalize(double level);
+
   /**
    * Returns the filename of the WAV file.
    **/
@@ -316,6 +320,18 @@
    **/
    void setFormatTag(unsigned short format);
 
+   void setEnergyTag(int format);
+   int getEnergyTag() const;
+
+   /**
+    * <level> = Normalization level, expressed as linear ratio (0 = No normalization)
+    */
+   double getNormalizeLevel() const;
+
+
+   void setNormalizeLevel(double level);
+
+
   /**
    * Returns the number of audio channels recorded in the WAV file, as 
    * represented by the 'FMT chunk.
@@ -1042,6 +1058,8 @@
    bool GetBext(int);
    bool GetMext(int);
    bool GetLevl(int);
+   bool ReadEnergyFile (QString);
+   bool ReadNormalizeLevel (QString);
    bool GetList(int);
    bool GetScot(int);
    bool GetAv10(int);
@@ -1050,6 +1068,7 @@
    void ReadTmcTag(const QString tag,const QString value);
    bool GetLine(int fd,char *buffer,int max_len);
    void ReadId3Metadata();
+   void ReadOggMetadata();
    bool GetMpegHeader(int fd,int offset);
    int GetAtxOffset(int fd);
    bool GetFlacStreamInfo();
@@ -1078,6 +1097,7 @@
    unsigned ext_time_length;       // Audio length in msec
    bool format_chunk;              // Does 'fmt ' chunk exist?
    unsigned short format_tag;      // Encoding Format
+   int energy_tag;	           // 0: Include Energy Data 1: Extra File
    unsigned short channels;        // Number of channels
    unsigned samples_per_sec;       // Samples/sec/channel
    unsigned avg_bytes_per_sec;     // Average bytes/sec overall
@@ -1171,6 +1191,7 @@
    unsigned short levl_block_ptr;
    unsigned levl_istate;
    short levl_accum;
+   double normalize_level;
 
    QString cutString(char *,unsigned,unsigned);
    QDate cutDate(char *,unsigned);
@@ -1213,6 +1234,7 @@
    ogg_page ogg_pg;
    ogg_packet ogg_pack;
 #endif  // HAVE_VORBIS
+   RMpegFile * mpeg_file;
 };
 
 
Index: rdadmin/edit_decks.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdadmin/edit_decks.cpp,v
retrieving revision 1.31
diff -u -r1.31 edit_decks.cpp
--- rdadmin/edit_decks.cpp	3 Apr 2008 16:50:06 -0000	1.31
+++ rdadmin/edit_decks.cpp	9 Nov 2008 11:13:41 -0000
@@ -334,6 +334,9 @@
   edit_play_channel=edit_play_deck_box->currentItem()+129;
   edit_format_box->insertItem(tr("PCM16"));
   edit_format_box->insertItem(tr("MPEG Layer 2"));
+  edit_format_box->insertItem(tr("Ogg Vorbis"));
+  edit_format_box->insertItem(tr("MPEG Layer 3"));
+  //edit_format_box->insertItem(tr("Flac"));
   edit_channels_box->insertItem("1");
   edit_channels_box->insertItem("2");
   edit_samprate_box->insertItem("32000");
@@ -588,9 +591,18 @@
 	  break;
 
 	case RDSettings::MpegL1:
+         break;
 	case RDSettings::MpegL3:
+	  edit_format_box->setCurrentItem(3);
+	  edit_bitrate_box->setEnabled(true);
+	  break;
 	case RDSettings::Flac:
+	  edit_format_box->setCurrentItem(4);
+	  edit_bitrate_box->setEnabled(true);
+	  break;
 	case RDSettings::OggVorbis:
+	  edit_format_box->setCurrentItem(2);
+	  edit_bitrate_box->setEnabled(true);
 	  break;
     }
     edit_channels_box->setCurrentItem(edit_record_deck->defaultChannels()-1);
@@ -711,6 +723,15 @@
 	case 1:
 	  edit_record_deck->setDefaultFormat(RDSettings::MpegL2);
 	  break;
+	case 2:
+	  edit_record_deck->setDefaultFormat(RDSettings::OggVorbis);
+	  break;
+	case 3:
+	  edit_record_deck->setDefaultFormat(RDSettings::MpegL3);
+	  break;
+	case 4:
+	  edit_record_deck->setDefaultFormat(RDSettings::Flac);
+	  break;
     }
     edit_record_deck->setDefaultChannels(edit_channels_box->currentItem()+1);
     sscanf((const char *)edit_samprate_box->currentText(),"%d",&temp);
Index: rdadmin/edit_rdlibrary.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdadmin/edit_rdlibrary.cpp,v
retrieving revision 1.30
diff -u -r1.30 edit_rdlibrary.cpp
--- rdadmin/edit_rdlibrary.cpp	29 Dec 2007 21:05:35 -0000	1.30
+++ rdadmin/edit_rdlibrary.cpp	9 Nov 2008 11:13:41 -0000
@@ -342,7 +342,30 @@
   lib_riplevel_spin->setValue(lib_lib->ripperLevel()/100);
   lib_format_box->insertItem(tr("PCM16"));
   lib_format_box->insertItem(tr("MPEG Layer 2"));
-  lib_format_box->setCurrentItem(lib_lib->defaultFormat());
+  lib_format_box->insertItem(tr("Ogg Vorbis"));
+  lib_format_box->insertItem(tr("Mpeg Layer 3"));
+  //lib_format_box->insertItem(tr("Flac"));
+    switch(lib_lib->defaultFormat()) {
+	case RDSettings::Pcm16:
+	  lib_format_box->setCurrentItem(0);
+	  break;
+
+	case RDSettings::MpegL2:
+	  lib_format_box->setCurrentItem(1);
+	  break;
+
+	case RDSettings::MpegL1:
+         break;
+	case RDSettings::MpegL3:
+	  lib_format_box->setCurrentItem(3);
+	  break;
+	case RDSettings::OggVorbis:
+	  lib_format_box->setCurrentItem(2);
+	  break;
+	case RDSettings::Flac:
+	  //lib_format_box->setCurrentItem(4);
+	  break;
+    }
   lib_channels_box->insertItem("1");
   lib_channels_box->insertItem("2");
   lib_channels_box->setCurrentItem(lib_lib->defaultChannels()-1);
@@ -432,7 +455,24 @@
   lib_lib->setRipperDevice(lib_ripdev_edit->text());
   lib_lib->setParanoiaLevel(lib_paranoia_box->currentItem());
   lib_lib->setRipperLevel(lib_riplevel_spin->value()*100);
-  lib_lib->setDefaultFormat(lib_format_box->currentItem());
+  switch(lib_format_box->currentItem())
+  {
+	case 0:
+	  lib_lib->setDefaultFormat(RDSettings::Pcm16);
+	  break;
+	case 1:
+	  lib_lib->setDefaultFormat(RDSettings::MpegL2);
+	  break;
+	case 2:
+	  lib_lib->setDefaultFormat(RDSettings::OggVorbis);
+	  break;
+	case 3:
+	  lib_lib->setDefaultFormat(RDSettings::MpegL3);
+	  break;
+	case 4:
+	  lib_lib->setDefaultFormat(RDSettings::Flac);
+	  break;
+  }
   lib_lib->setDefaultChannels(lib_channels_box->currentItem()+1);
   sscanf(lib_samprate_box->currentText(),"%d",&rate);
   lib_lib->setDefaultSampleRate(rate);
@@ -539,6 +579,9 @@
 	break;
 
       case 2:  // MPEG-1 Layer 3
+      case 3:
+      case RDSettings::Flac:
+      case RDSettings::OggVorbis:
 	lib_bitrate_box->setEnabled(true);
 	lib_bitrate_box->insertItem(tr("32 kbps/chan"));
 	lib_bitrate_box->insertItem(tr("40 kbps/chan"));
@@ -554,7 +597,7 @@
 	lib_bitrate_box->insertItem(tr("224 kbps/chan"));
 	lib_bitrate_box->insertItem(tr("256 kbps/chan"));
 	lib_bitrate_box->insertItem(tr("320 kbps/chan"));
-	switch(lib_lib->defaultLayer()) {
+	switch(lib_lib->defaultBitrate()) {
 	    case 32000:
 	      lib_bitrate_box->setCurrentItem(0);
 	      break;
Index: rdadmin/edit_rdlogedit.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdadmin/edit_rdlogedit.cpp,v
retrieving revision 1.13.2.1
diff -u -r1.13.2.1 edit_rdlogedit.cpp
--- rdadmin/edit_rdlogedit.cpp	28 Oct 2008 21:51:33 -0000	1.13.2.1
+++ rdadmin/edit_rdlogedit.cpp	9 Nov 2008 11:13:41 -0000
@@ -342,7 +342,31 @@
   lib_preroll_spin->setValue(lib_lib->tailPreroll());
   lib_format_box->insertItem(tr("PCM16"));
   lib_format_box->insertItem(tr("MPEG Layer 2"));
-  lib_format_box->setCurrentItem(lib_lib->format());
+  lib_format_box->insertItem(tr("Ogg Vorbis"));
+  lib_format_box->insertItem(tr("Mpeg Layer 3"));
+  //lib_format_box->insertItem(tr("Flac"));
+  switch(lib_lib->format()) {
+        case RDSettings::Pcm16:
+ 	  lib_format_box->setCurrentItem(0);
+ 	  break;
+ 
+ 	case RDSettings::MpegL2:
+ 	  lib_format_box->setCurrentItem(1);
+ 	  break;
+ 
+ 	case RDSettings::MpegL1:
+ 	  break;
+ 	case RDSettings::MpegL3:
+ 	  lib_format_box->setCurrentItem(3);
+ 	  break;
+ 	case RDSettings::OggVorbis:
+ 	  lib_format_box->setCurrentItem(2);
+ 	  break;
+ 	case RDSettings::Flac:
+ 	  //lib_format_box->setCurrentItem(4);
+ 	  break;
+  }
+
   lib_channels_box->insertItem("1");
   lib_channels_box->insertItem("2");
   lib_channels_box->setCurrentItem(lib_lib->defaultChannels()-1);
@@ -470,7 +494,25 @@
   else {
     lib_lib->setRecEndCart(lib_recendcart_edit->text().toUInt());
   }
-  lib_lib->setFormat(lib_format_box->currentItem());
+  switch(lib_format_box->currentItem())
+   {
+ 	case 0:
+ 	  lib_lib->setFormat(RDSettings::Pcm16);
+ 	  break;
+ 	case 1:
+ 	  lib_lib->setFormat(RDSettings::MpegL2);
+ 	  break;
+ 	case 2:
+ 	  lib_lib->setFormat(RDSettings::OggVorbis);
+ 	  break;
+ 	case 3:
+ 	  lib_lib->setFormat(RDSettings::MpegL3);
+ 	  break;
+ 	case 4:
+ 	  lib_lib->setFormat(RDSettings::Flac);
+ 	  break;
+  }
+
   lib_lib->setDefaultChannels(lib_channels_box->currentItem()+1);
   sscanf(lib_samprate_box->currentText(),"%d",&rate);
   lib_lib->setSampleRate(rate);
@@ -559,6 +601,10 @@
 	break;
 
       case 2:  // MPEG-1 Layer 3
+      case 3:
+      case RDSettings::Flac:
+      case RDSettings::OggVorbis:
+
 	lib_bitrate_box->setEnabled(true);
 	lib_bitrate_box->insertItem(tr("32 kbps/chan"));
 	lib_bitrate_box->insertItem(tr("40 kbps/chan"));
@@ -574,7 +620,7 @@
 	lib_bitrate_box->insertItem(tr("224 kbps/chan"));
 	lib_bitrate_box->insertItem(tr("256 kbps/chan"));
 	lib_bitrate_box->insertItem(tr("320 kbps/chan"));
-	switch(lib_lib->layer()) {
+	switch(lib_lib->bitrate()) {
 	    case 32000:
 	      lib_bitrate_box->setCurrentItem(0);
 	      break;
Index: rdadmin/rdadmin_de.ts
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdadmin/rdadmin_de.ts,v
retrieving revision 1.8.2.1
diff -u -r1.8.2.1 rdadmin_de.ts
--- rdadmin/rdadmin_de.ts	4 Nov 2008 19:38:09 -0000	1.8.2.1
+++ rdadmin/rdadmin_de.ts	9 Nov 2008 11:13:42 -0000
@@ -712,6 +712,14 @@
         <source>[none]</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Ogg Vorbis</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>MPEG Layer 3</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>EditEncoder</name>
@@ -1673,6 +1681,14 @@
         <source>320 kbps/chan</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Ogg Vorbis</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mpeg Layer 3</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>EditReport</name>
Index: rdadmin/rdadmin_es.ts
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdadmin/rdadmin_es.ts,v
retrieving revision 1.76.2.1
diff -u -r1.76.2.1 rdadmin_es.ts
--- rdadmin/rdadmin_es.ts	4 Nov 2008 19:38:09 -0000	1.76.2.1
+++ rdadmin/rdadmin_es.ts	9 Nov 2008 11:13:44 -0000
@@ -712,6 +712,14 @@
 in order to populate the audio resources database.</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Ogg Vorbis</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>MPEG Layer 3</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>EditEncoder</name>
@@ -1673,6 +1681,14 @@
         <source>Allow E&amp;xternal Editing:</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Ogg Vorbis</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mpeg Layer 3</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>EditReport</name>
Index: rdadmin/rdadmin_fr.ts
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdadmin/rdadmin_fr.ts,v
retrieving revision 1.8.2.1
diff -u -r1.8.2.1 rdadmin_fr.ts
--- rdadmin/rdadmin_fr.ts	4 Nov 2008 19:38:09 -0000	1.8.2.1
+++ rdadmin/rdadmin_fr.ts	9 Nov 2008 11:13:44 -0000
@@ -712,6 +712,14 @@
         <source>[none]</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Ogg Vorbis</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>MPEG Layer 3</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>EditEncoder</name>
@@ -1673,6 +1681,14 @@
         <source>320 kbps/chan</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Ogg Vorbis</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Mpeg Layer 3</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>EditReport</name>
Index: rdcatch/edit_upload.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdcatch/edit_upload.cpp,v
retrieving revision 1.15
diff -u -r1.15 edit_upload.cpp
--- rdcatch/edit_upload.cpp	18 Sep 2008 19:02:15 -0000	1.15
+++ rdcatch/edit_upload.cpp	9 Nov 2008 11:13:44 -0000
@@ -634,6 +634,10 @@
 	  res=true;
 	}
 	break;
+
+      case RDSettings::Copy:
+        res=true;
+	break;
   }
   delete station;
 
Index: rdcatchd/rdcatchd.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdcatchd/rdcatchd.cpp,v
retrieving revision 1.130
diff -u -r1.130 rdcatchd.cpp
--- rdcatchd/rdcatchd.cpp	2 Oct 2008 18:52:13 -0000	1.130
+++ rdcatchd/rdcatchd.cpp	9 Nov 2008 11:13:45 -0000
@@ -892,8 +892,26 @@
     return;
   }
 
-  if(catch_events[event].normalizeLevel()==0) {
-    CheckInRecording(catch_record_name[deck-1],catch_record_threshold[deck-1]);
+  RDCut *cut=new RDCut(catch_record_name[deck-1]);
+  if(catch_events[event].normalizeLevel()==0 || catch_events[event].format()==5 || catch_events[event].format()==3) {
+    CheckInRecording(catch_record_name[deck-1],catch_record_threshold[deck-1],catch_events[event].normalizeLevel());
+    if(catch_events[event].format()==5 || catch_events[event].format()==3) {
+      QString cmd;
+      cmd=QString().
+      sprintf("nice rd_encode %s %d %d %d %d %s %s",
+ 	      cut->pathName(catch_record_name[deck-1]).ascii(),
+ 	      catch_events[event].format(),
+	      catch_events[event].sampleRate(),
+	      catch_events[event].channels(),
+	      catch_events[event].bitrate()/1000,
+	      catch_config->audioOwner().ascii(),
+	      catch_config->audioGroup().ascii());
+      //system(cmd);
+      if(fork()==0) {
+        system(cmd+" &");
+        exit(0);
+      } 	  
+    }  
   }
   else {
     if(fork()==0) {
@@ -906,6 +924,7 @@
       exit(0);
     }
   }
+  delete cut;
   if(catch_record_aborting[deck-1]) {
     LogLine(RDConfig::LogNotice,QString().
 	    sprintf("record aborted: cut %s",
@@ -1241,7 +1260,7 @@
   //
   RDCae::AudioCoding format=catch_events[event].format();
   QString cut_name;
-  if(catch_events[event].normalizeLevel()==0) {
+  if(catch_events[event].normalizeLevel()==0 || catch_events[event].format()==5 || catch_events[event].format()==3) {
     cut_name=catch_events[event].cutName();
   }
   else {
@@ -1299,6 +1318,18 @@
 	cut->setCodingFormat(1);
 	break;
 
+      case RDSettings::MpegL3:
+	cut->setCodingFormat(RDSettings::MpegL3);
+	break;
+
+      case RDSettings::OggVorbis:
+	cut->setCodingFormat(RDSettings::OggVorbis);
+	break;
+
+      case RDSettings::Flac:
+	cut->setCodingFormat(RDSettings::Flac);
+	break;
+
       default:
 	cut->setCodingFormat(0);
 	break;
@@ -1473,36 +1504,36 @@
       if(!catch_events[event].urlUsername().isEmpty()) {
 	xload_cmd+=QString().sprintf("--http-user %s ",
 				     (const char *)
-				     catch_events[event].urlUsername());
+				     catch_events[event].urlUsername().utf8());
 	if(!catch_events[event].urlPassword().isEmpty()) {
 	  xload_cmd+=QString().sprintf("--http-passwd \"%s\" ",
 				       (const char *)
-				       catch_events[event].urlPassword());
+				       catch_events[event].urlPassword().utf8());
 	}
       }
       xload_cmd+=QString().
-	sprintf("-O %s \"%s\"",(const char *)catch_events[event].tempName(),
+	sprintf("-O %s \"%s\"",(const char *)catch_events[event].tempName().utf8(),
 		(const char *)catch_events[event].resolvedUrl());
     }
     if(protocol=="ftp") {
       catch_events[event].setTempName(BuildTempName(event,"download"));
       catch_events[event].setDeleteTempFile(true);
       xload_cmd=QString().sprintf("lftp -e \"get -O %s %s -o %s;bye\"",
-		  (const char *)RDGetPathPart(catch_events[event].tempName()),
+		  (const char *)RDGetPathPart(catch_events[event].tempName().utf8()),
 		  (const char *)url.path().right(url.path().length()-1),
-		  (const char *)RDGetBasePart(catch_events[event].tempName()));
+		  (const char *)RDGetBasePart(catch_events[event].tempName().utf8()));
       if(!catch_events[event].urlUsername().isEmpty()) {
 	xload_cmd+=QString().sprintf(" -u \"%s",
-			  (const char *)catch_events[event].urlUsername());
+			  (const char *)catch_events[event].urlUsername().utf8());
 	if(catch_events[event].urlPassword().isEmpty()) {
 	  xload_cmd+="\"";
 	}
 	else {
 	  xload_cmd+=QString().sprintf(",%s\"",
-			  (const char *)catch_events[event].urlPassword());
+			  (const char *)catch_events[event].urlPassword().utf8());
 	}
       }
-      xload_cmd+=QString().sprintf(" %s",(const char *)url.host());
+      xload_cmd+=QString().sprintf(" %s",(const char *)url.host().utf8());
     }
     if(protocol=="smb") {
       if(!url.validSmbShare()) {
@@ -1516,14 +1547,14 @@
       catch_events[event].setTempName(BuildTempName(event,"download"));
       catch_events[event].setDeleteTempFile(true);
       xload_cmd=QString().sprintf("smbclient \"%s\" ",
-				  (const char *)url.smbShare());
+				  (const char *)url.smbShare().utf8());
       if(!catch_events[event].urlPassword().isEmpty()) {
 	xload_cmd+=QString().sprintf("\"%s\" ",(const char *)
-				     catch_events[event].urlPassword());
+				     catch_events[event].urlPassword().utf8());
       }
       if(!catch_events[event].urlUsername().isEmpty()) {
 	xload_cmd+=QString().sprintf("-U %s ",(const char *)
-				     catch_events[event].urlUsername());
+				     catch_events[event].urlUsername().utf8());
       }
       xload_cmd+=QString().
 	sprintf("-c \"get %s %s\"",(const char *)url.smbPath(),
@@ -1538,10 +1569,10 @@
       LogLine(RDConfig::LogInfo,QString().
 	      sprintf("started download of %s to %s, id=%d, cmdline=\"%s\"",
 		      (const char *)catch_events[event].resolvedUrl(),
-		      (const char *)catch_events[event].tempName(),
+		      (const char *)catch_events[event].tempName().utf8(),
 		      catch_events[event].id(),
 		      (const char *)xload_cmd));
-      if(system(xload_cmd)!=0) {
+      if(system((const char *)xload_cmd.utf8())!=0) {
 	WriteExitCode(event,RDRecording::ServerError);
 	printf("download of %s returned an error, id=%d, xload_cmd: %s\n",
 			    (const char *)catch_events[event].resolvedUrl(),
@@ -1607,27 +1638,27 @@
       }
       if(dir.right(dir.length()-1)=="/") {
 	xload_cmd=QString().sprintf("lftp -e \"put %s -o %s;bye\"",
-			     (const char *)catch_events[event].tempName(),
-			     (const char *)RDGetBasePart(url.path()));
+			     (const char *)catch_events[event].tempName().utf8(),
+			     (const char *)RDGetBasePart(url.path().utf8()));
       }
       else {
 	xload_cmd=QString().sprintf("lftp -e \"put -O %s %s -o %s;bye\"",
 			     (const char *)dir.right(dir.length()-1),
-			     (const char *)catch_events[event].tempName(),
-			     (const char *)RDGetBasePart(url.path()));
+			     (const char *)catch_events[event].tempName().utf8(),
+			     (const char *)RDGetBasePart(url.path().utf8()));
       }
       if(!catch_events[event].urlUsername().isEmpty()) {
 	xload_cmd+=QString().sprintf(" -u \"%s",
-			  (const char *)catch_events[event].urlUsername());
+			  (const char *)catch_events[event].urlUsername().utf8());
 	if(catch_events[event].urlPassword().isEmpty()) {
 	  xload_cmd+="\"";
 	}
 	else {
 	  xload_cmd+=QString().sprintf(",%s\"",
-			  (const char *)catch_events[event].urlPassword());
+			  (const char *)catch_events[event].urlPassword().utf8());
 	}
       }
-      xload_cmd+=QString().sprintf(" %s",(const char *)url.host());
+      xload_cmd+=QString().sprintf(" %s",(const char *)url.host().utf8());
     }
     if(protocol=="smb") {
       if(!url.validSmbShare()) {
@@ -1644,19 +1675,19 @@
       catch_events[event].setDeleteTempFile(true);
       QString path=RDGetPathPart(url.path());
       xload_cmd=QString().sprintf("smbclient \"%s\" ",
-				  (const char *)url.smbShare());
+				  (const char *)url.smbShare().utf8());
       if(!catch_events[event].urlPassword().isEmpty()) {
 	xload_cmd+=QString().sprintf("\"%s\" ",(const char *)
-				     catch_events[event].urlPassword());
+				     catch_events[event].urlPassword().utf8());
       }
       if(!catch_events[event].urlUsername().isEmpty()) {
 	xload_cmd+=QString().sprintf("-U %s ",(const char *)
-				     catch_events[event].urlUsername());
+				     catch_events[event].urlUsername().utf8());
       }
       xload_cmd+=QString().
 	sprintf("-c \"put %s %s\"",(const char *)catch_events[event].
 		tempName(),
-		(const char *)url.smbPath());
+		(const char *)url.smbPath().utf8());
     }
 
     //
@@ -1701,12 +1732,12 @@
     if(!xload_cmd.isEmpty()) {
       LogLine(RDConfig::LogInfo,QString().
 	      sprintf("started upload of %s to %s, id=%d, cmdline=\"%s\"",
-		      (const char *)catch_events[event].tempName(),
+		      (const char *)catch_events[event].tempName().utf8(),
 		      (const char *)catch_events[event].
-		      resolvedUrl(),
+		      resolvedUrl().utf8(),
 		      catch_events[event].id(),
 		      (const char *)xload_cmd));
-      if(system(xload_cmd)==256) {
+      if(system((const char *)xload_cmd.utf8())==256) {
 	unlink(catch_events[event].tempName());
 	LogLine(RDConfig::LogDebug,QString().sprintf("deleted file %s",
 			      (const char *)catch_events[event].tempName()));
@@ -1727,7 +1758,7 @@
 	      sprintf("finished upload of %s to %s, id=%d",
 				(const char *)catch_events[event].tempName(),
 				(const char *)catch_events[event].
-				resolvedUrl(),
+				resolvedUrl().utf8(),
 				catch_events[event].id()));
     }
     
@@ -2541,7 +2572,7 @@
 {
   QString temp_exportname;
   QString export_cmd=GetExportCmd(event,&temp_exportname);
-  if(system(export_cmd)!=0) {
+  if(system((const char *)export_cmd.utf8())!=0) {
     unlink(QString().sprintf("%s.%s",(const char *)temp_exportname,
 			     RDConfiguration()->audioExtension().ascii()));
     unlink(temp_exportname+".dat");
@@ -2592,16 +2623,23 @@
 	  setTempLength(wave->getSampleLength()*wave->getChannels()*2);
 	break;
 
+      case WAVE_FORMAT_VORBIS:
+	format_in=5;
+	catch_events[event].
+	  setTempLength(wave->getSampleLength()*wave->getChannels()*2);
+	break;
+
   }
   wave->closeWave();
   delete wave;
 
   QString cmd;
   float normal=0.0;
-  if(catch_events[event].normalizeLevel()<=0) {
-    normal=pow(10.0,(double)(catch_events[event].normalizeLevel()/2000.0));
-    cmd=QString().
-      sprintf("rd_export_file %6.4f %d %d %s %d %d %d %d %d %s %s.dat %s.%s",
+  if(catch_events[event].format()<99) {
+    if(catch_events[event].normalizeLevel()<=0) {
+      normal=pow(10.0,(double)(catch_events[event].normalizeLevel()/2000.0));
+      cmd=QString().
+        sprintf("rd_export_file %6.4f %d %d %s %d %d %d %d %d %s %s.dat %s.%s",
 	      normal,
 	      format_in,
 	      samplerate,
@@ -2611,14 +2649,14 @@
 	      catch_events[event].sampleRate(),
 	      catch_events[event].bitrate()/1000,
 	      catch_events[event].quality(),
-	      (const char *)RDEscapeString(catch_events[event].tempName()),
+	      (const char *)RDEscapeString(catch_events[event].tempName().utf8()),
 	      (const char *)(*tempname),
 	      (const char *)(*tempname),
 	      RDConfiguration()->audioExtension().ascii());
-  }
-  else {
-    cmd=QString().
-      sprintf("rd_export_file 0 %d %d %s %d %d %d %d %d %s %s.dat %s.%s",
+    }
+    else {
+      cmd=QString().
+        sprintf("rd_export_file 0 %d %d %s %d %d %d %d %d %s %s.dat %s.%s",
 	      format_in,
 	      samplerate,
 	      (const char *)local_filename,
@@ -2627,11 +2665,19 @@
 	      catch_events[event].sampleRate(),
 	      catch_events[event].bitrate()/1000,
 	      catch_events[event].quality(),
-	      (const char *)RDEscapeString(catch_events[event].tempName()),
+	      (const char *)RDEscapeString(catch_events[event].tempName().utf8()),
 	      (const char *)(*tempname),
 	      (const char *)(*tempname),
 	      RDConfiguration()->audioExtension().ascii());
+    }
   }
+  else { 
+    cmd=QString().
+      sprintf("cp %s %s",(const char *)local_filename,
+	      (const char *)RDEscapeString(catch_events[event].tempName().utf8()));
+  }
+
+   //LogLine(QString().sprintf("CMD: %s",(const char *)cmd));
   switch(catch_events[event].format()) {  // Custom format?
     case RDSettings::Pcm16:
     case RDSettings::MpegL1:
@@ -2639,6 +2685,7 @@
     case RDSettings::MpegL3:
     case RDSettings::Flac:
     case RDSettings::OggVorbis:
+    case RDSettings::Copy:
       break;
 
     default:
@@ -2678,7 +2725,7 @@
 		  (const char *)catch_events[event].tempName(),
 		  (const char *)catch_events[event].cutName(),
 		  catch_events[event].id()));
-  if(system(import_cmd)!=0) {
+  if(system((const char *)import_cmd.utf8())!=0) {
     WriteExitCode(event,RDRecording::ServerError);
     LogLine(RDConfig::LogWarning,QString().
 	    sprintf("import of %s returned an error, id=%d",
@@ -2697,7 +2744,8 @@
   chmod(RDCut::pathName(catch_events[event].cutName()),
 	S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
   CheckInRecording(catch_events[event].cutName(),
-		   catch_events[event].trimThreshold());
+		   catch_events[event].trimThreshold(),
+                   catch_events[event].normalizeLevel());
   if(catch_events[event].deleteTempFile()) {
     unlink(catch_events[event].tempName());
     LogLine(RDConfig::LogDebug,QString().
@@ -2710,7 +2758,6 @@
 		  (const char *)catch_events[event].tempName(),
 		  (const char *)catch_events[event].cutName(),
 		  catch_events[event].id()));
-  
   return true;
 }
 
@@ -2719,7 +2766,13 @@
 {
   int format_in=0;
   int format_out=0;
+  bool open_failed=false;
 
+  if(catch_events[event].type()==RDRecording::Download) {
+    catch_events[event].setFormat((RDCae::AudioCoding)catch_default_format);
+    catch_events[event].setSampleRate(catch_default_samplerate);
+    catch_events[event].setBitrate(catch_default_bitrate*catch_events[event].channels());
+  }   
   //
   // Calculate Temporary Filenames
   //
@@ -2733,6 +2786,10 @@
   }
   RDWaveFile *wave=new RDWaveFile(catch_events[event].tempName());
   if(!wave->openWave()) {
+    if(catch_events[event].format()==3 || catch_events[event].format()==5) {
+      open_failed=true;
+    }
+    else {
     delete wave;
     LogLine(RDConfig::LogWarning,QString().
 	    sprintf("unable to open temporary file %s for importing, id=%d",
@@ -2740,7 +2797,12 @@
 		    catch_events[event].id()));
     return QString();
   }
+  }
   if(wave->type()==RDWaveFile::Unknown) {
+    if(catch_events[event].format()==3 || catch_events[event].format()==5 ) {
+      open_failed=true;
+    }
+    else {
     wave->closeWave();
     delete wave;
     LogLine(RDConfig::LogWarning,QString().
@@ -2749,6 +2811,8 @@
 		    catch_events[event].id()));
     return QString();
   }
+  }
+  
   int samplerate=wave->getSamplesPerSec();
   switch(wave->getFormatTag()) {
       case WAVE_FORMAT_PCM:
@@ -2758,6 +2822,14 @@
       case WAVE_FORMAT_MPEG:
 	format_in=wave->getHeadLayer();
 	break;
+      
+      case WAVE_FORMAT_FLAC:
+	format_in=4;
+	break;
+      
+      case WAVE_FORMAT_VORBIS:
+	format_in=5;
+	break;
   }
   delete wave;
 
@@ -2770,6 +2842,9 @@
 	break;
       case 1:  // MPEG-1 Layer 2
       case 2:  // MPEG-1 Layer 3
+      case 3:
+      case 4:
+      case 5:
 	catch_events[event].
 	  setFinalLength((int)((double)catch_events[event].tempLength()*
 			       (double)catch_default_channels*
@@ -2786,6 +2861,15 @@
 	format_out=1;
 	break;
 
+      case 4:  
+	format_out=4;
+	break;
+
+      case 5:  
+	format_out=5;
+	break;
+
+
       default:
 	LogLine(RDConfig::LogWarning,QString().
 		sprintf("unknown output format %d, id=%d",
@@ -2798,12 +2882,13 @@
   float normal=0.0;
   if(catch_events[event].normalizeLevel()!=0) {
     normal=pow(10.0,(double)(catch_events[event].normalizeLevel()/2000.0));
+    if(format_out!=3 && format_out!=5) {
     cmd=QString().
       sprintf("rd_import_file %6.4f %d %d %s %d %d %d %d %s %s.dat %s.%s",
 	      normal,
 	      format_in,
 	      samplerate,
-	      (const char *)RDEscapeString(catch_events[event].tempName()),  
+	      (const char *)RDEscapeString(catch_events[event].tempName().utf8()),  
 	      format_out,
 	      catch_events[event].channels(),
 	      catch_events[event].sampleRate(),
@@ -2814,11 +2899,37 @@
 	      RDConfiguration()->audioExtension().ascii());
   }
   else {
+      if((format_in!=3 && format_in!=5) || open_failed || samplerate!=catch_events[event].sampleRate()) {
+        cmd=QString().
+          sprintf("rd_import_encode %s %s %d %d %d %d %f %s %s",
+	        (const char *)RDEscapeString(catch_events[event].tempName().utf8()),  
+	        RDCut::pathName(catch_events[event].cutName()).ascii(),  
+	        format_out,
+	        catch_events[event].sampleRate(),
+	        catch_events[event].channels(),
+	        catch_events[event].bitrate()/1000,
+	        normal,
+	        catch_config->audioOwner().ascii(),
+	        catch_config->audioGroup().ascii());
+      }
+      else {
+        cmd=QString().
+          sprintf("rd_import_copy %s %s %f %s %s",
+	        (const char *)RDEscapeString(catch_events[event].tempName().utf8()),  
+	        RDCut::pathName(catch_events[event].cutName()).ascii(),  
+	        normal,
+	        catch_config->audioOwner().ascii(),
+	        catch_config->audioGroup().ascii());
+      }  	      
+    }	      
+  }
+  else {
+    if(format_out!=3 && format_out!=5) {
     cmd=QString().
       sprintf("rd_import_file 0 %d %d %s %d %d %d %d %s %s.dat %s.%s",
 	      format_in,
 	      samplerate,
-	      (const char *)RDEscapeString(catch_events[event].tempName()),
+	      (const char *)RDEscapeString(catch_events[event].tempName().utf8()),
 	      format_out,
 	      catch_events[event].channels(),
 	      catch_events[event].sampleRate(),
@@ -2828,16 +2939,39 @@
 	      (const char *)*tempname,
 	      RDConfiguration()->audioExtension().ascii());
   }
-  // LogLine(QString().sprintf("CMD: %s",(const char *)cmd));
+      if((format_in!=3 && format_in!=5) || open_failed || samplerate!=catch_events[event].sampleRate()) {
+         cmd=QString().
+           sprintf("rd_import_encode %s %s %d %d %d %d 0 %s %s",
+ 	        (const char *)RDEscapeString(catch_events[event].tempName().utf8()),  
+ 	        RDCut::pathName(catch_events[event].cutName()).ascii(),  
+ 	        format_out,
+ 	        catch_events[event].sampleRate(),
+ 	        catch_events[event].channels(),
+ 	        catch_events[event].bitrate()/1000,
+ 	        catch_config->audioOwner().ascii(),
+ 	        catch_config->audioGroup().ascii());
+       }
+      else {
+        cmd=QString().
+          sprintf("rd_import_copy %s %s 0 %s %s",
+	        (const char *)RDEscapeString(catch_events[event].tempName().utf8()),  
+	        RDCut::pathName(catch_events[event].cutName()).ascii(),  
+	        catch_config->audioOwner().ascii(),
+	        catch_config->audioGroup().ascii());
+      }  	      
+  }
   return cmd;
 }
 
 
-void MainObject::CheckInRecording(QString cutname,unsigned threshold)
+void MainObject::CheckInRecording(QString cutname,unsigned threshold,int normalize_level)
 {
   RDCut *cut=new RDCut(cutname);
   cut->checkInRecording(catch_rdstation->name());
   cut->autoTrim(RDCut::AudioBoth,-threshold);
+  if(normalize_level!=0) {
+    cut->normalize(normalize_level);
+  }  
   RDCart *cart=new RDCart(cut->cartNumber());
   cart->updateLength();
   delete cart;
@@ -3132,7 +3266,7 @@
 	    sprintf("launching dropbox configuration: \"%s\"",
 		    (const char *)cmd));
     if(fork()==0) {
-      system(cmd);
+      system((const char *)cmd.utf8());
       exit(0);
     }
   }
Index: rdcatchd/rdcatchd.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdcatchd/rdcatchd.h,v
retrieving revision 1.51
diff -u -r1.51 rdcatchd.h
--- rdcatchd/rdcatchd.h	2 Oct 2008 18:52:14 -0000	1.51
+++ rdcatchd/rdcatchd.h	9 Nov 2008 11:13:45 -0000
@@ -141,7 +141,7 @@
   QString GetExportCmd(int event,QString *tempname);
   bool Import(int event);
   QString GetImportCmd(int event,QString *tempname);
-  void CheckInRecording(QString cutname,unsigned threshold);
+  void CheckInRecording(QString cutname,unsigned threshold,int normalize_level=0);
   void CheckInPodcast(CatchEvent *e);
   RDRecording::ExitCode ReadExitCode(int event);
   void WriteExitCode(int event,RDRecording::ExitCode code);
Index: rdlibrary/audio_cart.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlibrary/audio_cart.cpp,v
retrieving revision 1.50
diff -u -r1.50 audio_cart.cpp
--- rdlibrary/audio_cart.cpp	29 Dec 2007 21:05:36 -0000	1.50
+++ rdlibrary/audio_cart.cpp	9 Nov 2008 11:13:45 -0000
@@ -77,7 +77,7 @@
   line_edit_font.setPixelSize(12);
 
   //
-  // Progress Dialog
+  // Progress Dialogs
   //
   rdcart_progress_dialog=new QProgressDialog(this);
   rdcart_progress_dialog->setLabelText(tr("Copying audio..."));
@@ -85,6 +85,14 @@
   rdcart_progress_dialog->setTotalSteps(10);
   rdcart_progress_dialog->setMinimumDuration(1000);
 
+  update_progress_dialog=new QProgressDialog(this);
+  update_progress_dialog->setLabelText(tr("Updateing audio..."));
+  update_progress_dialog->setCancelButton(NULL);
+  update_progress_dialog->setTotalSteps(10);
+  update_progress_dialog->setMinimumDuration(1);
+  update_progress_dialog->setCaption("");
+  
+
   //
   // Add Cut Button
   //
@@ -373,23 +381,153 @@
   paste_cut_button->setEnabled(rdcart_modification_allowed);
 }
 
+
 void AudioCart::extEditorCutData()
 {
+  QString sql;
+  RDSqlQuery *q;
+  RDCut *temp_cut;
+  RDWaveFile *wavefile;
+  double level=1.0; 
+  QString extension="wav";
+  
   if(rdcart_cut_list->currentItem()==0) {
     return;
   }
 
+  temp_cut=new RDCut(rdcart_cut_list->currentItem()->text(11));
+  
+  wavefile=new RDWaveFile(RDCut::pathName(temp_cut->cutName()));
+  if(wavefile->openWave()) {
+    level=wavefile->getNormalizeLevel();
+    switch(wavefile->getFormatTag()) {
+      case WAVE_FORMAT_PCM:
+        extension="wav";
+        break;
+        
+      case WAVE_FORMAT_MPEG:
+        if(wavefile->getHeadLayer()==3) {
+          extension="mp3";
+        }
+        else {
+          extension="mp2";
+	}
+        break;
+        
+      case WAVE_FORMAT_VORBIS:
+        extension="ogg";
+        break;
+    }
+    wavefile->closeWave();
+  }  
+  delete wavefile; 
+
   QString cmd=rdstation_conf->editorPath();
-  cmd.replace("%f",RDCut::pathName(rdcart_cut_list->currentItem()->text(11)));
+  cmd.replace("%f","/tmp/"+temp_cut->cutName()+"."+extension);
   // FIXME: other replace commands to match: lib/rdcart_dialog.cpp editorData()
   //        These substitions should be documented (maybe a text file),
   //            ex: %f = cart_cut filename
   //        and possibly also add some tooltips with help advice
 
-  if(fork()==0) {
-    system(cmd+" &");
-    exit(0);
+  update_progress_dialog->setLabelText(tr("Starting External Editor..."));
+  update_progress_dialog->setProgress(1);
+  qApp->processEvents();
+
+ // if(fork()==0) {
+  system(QString().sprintf("cp %s /tmp/%s.%s",
+           RDCut::pathName(temp_cut->cutName()).ascii(),temp_cut->cutName().ascii(),
+           (const char *)extension));
+  system(cmd.ascii());
+ //   exit(0);
+ // }
+  
+  update_progress_dialog->setProgress(10);
+  
+  if(QMessageBox::question(this,tr("Update"),
+			    tr("Update Audio?"),
+			    QMessageBox::Yes,
+			    QMessageBox::No)==QMessageBox::No) {
+    delete temp_cut;
+    return;
+  }
+  
+  update_progress_dialog->setLabelText(tr("Updateing audio..."));
+  update_progress_dialog->setProgress(1);
+  qApp->processEvents();
+
+  //system(QString().sprintf("rd_edit_copy /tmp/%s.%s",temp_cut->cutName().ascii(),
+  //                           (const char *)extension));
+  
+  wavefile=new RDWaveFile("/tmp/"+temp_cut->cutName()+"."+extension);
+  if(!wavefile->openWave()) {
+    delete wavefile;
+    update_progress_dialog->setProgress(10);
+    delete temp_cut;
+    return;
+  }
+  
+  if(wavefile->getFormatTag()==WAVE_FORMAT_PCM) {
+    system(QString().sprintf("sox -v %f /tmp/%s.%s -t raw -s -w -c %d -r %d - |\
+                            rdfilewrite --channels=%d --sample-rate=%d %s",
+         level,
+         temp_cut->cutName().ascii(),
+         (const char *)extension,
+         wavefile->getChannels(),
+         wavefile->getSamplesPerSec(),
+         wavefile->getChannels(),
+         wavefile->getSamplesPerSec(),
+         RDCut::pathName(temp_cut->cutName()).ascii()));
+    
+    unlink("/tmp/"+temp_cut->cutName()+"."+extension);
+    unlink(RDCut::pathName(temp_cut->cutName())+".energy");
+  }
+  else {
+    system(QString().sprintf("mv /tmp/%s.%s %s",
+         temp_cut->cutName().ascii(),
+         (const char *)extension,
+         RDCut::pathName(temp_cut->cutName()).ascii()));
+    if(wavefile->getHeadLayer()==3) {
+      RDWaveFile *wavefile_mv=new RDWaveFile(RDCut::pathName(temp_cut->cutName()));
+      wavefile_mv->openWave();
+      wavefile_mv->setNormalizeLevel(level);
+      wavefile_mv->setEnergyTag(1);
+      wavefile_mv->recreateEnergy();
+      wavefile_mv->closeWave();
+      delete wavefile_mv;
+    }
   }
+  
+  update_progress_dialog->setProgress(5);
+  qApp->processEvents();
+  
+  delete wavefile;
+  wavefile=new RDWaveFile(RDCut::pathName(temp_cut->cutName()));
+  wavefile->openWave();
+
+  sql=QString().sprintf("update CUTS set START_POINT=0,END_POINT=%d,\
+                         FADEUP_POINT=-1,FADEDOWN_POINT=-1,\
+                         SEGUE_START_POINT=-1,SEGUE_END_POINT=-1,\
+                         TALK_START_POINT=-1,TALK_END_POINT=-1,\
+                         HOOK_START_POINT=-1,HOOK_END_POINT=-1,\
+                         LENGTH=%d\
+                         where CUT_NAME=\"%s\"",
+			wavefile->getExtTimeLength(),
+			wavefile->getExtTimeLength(),
+			temp_cut->cutName().ascii());
+  q=new RDSqlQuery(sql);
+  delete q;
+  wavefile->closeWave();
+  delete wavefile;
+  chmod(RDCut::pathName(temp_cut->cutName()),S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
+  chown(RDCut::pathName(temp_cut->cutName()),lib_config->uid(),lib_config->gid());
+  chmod(RDCut::pathName(temp_cut->cutName())+".energy",S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
+  chown(RDCut::pathName(temp_cut->cutName())+".energy",lib_config->uid(),lib_config->gid());
+  update_progress_dialog->setProgress(10);  
+  qApp->processEvents();
+  delete temp_cut;
+  RDListViewItem *item=(RDListViewItem *)rdcart_cut_list->selectedItem();
+  RefreshLine(item);
+  emit cartDataChanged();
 }
 
 void AudioCart::pasteCutData()
Index: rdlibrary/audio_cart.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlibrary/audio_cart.h,v
retrieving revision 1.17
diff -u -r1.17 audio_cart.h
--- rdlibrary/audio_cart.h	26 Dec 2007 21:45:43 -0000	1.17
+++ rdlibrary/audio_cart.h	9 Nov 2008 11:13:45 -0000
@@ -91,6 +91,7 @@
   AudioControls *rdcart_controls;
   QPushButton *paste_cut_button;
   QProgressDialog *rdcart_progress_dialog;
+  QProgressDialog *update_progress_dialog;
   bool rdcart_modification_allowed;
   bool rdcart_import_metadata;
 };
Index: rdlibrary/cdripper.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlibrary/cdripper.cpp,v
retrieving revision 1.36
diff -u -r1.36 cdripper.cpp
--- rdlibrary/cdripper.cpp	18 Aug 2008 15:57:42 -0000	1.36
+++ rdlibrary/cdripper.cpp	9 Nov 2008 11:13:45 -0000
@@ -168,7 +168,7 @@
   //
   // Progress Bar
   //
-  rip_bar=new QProgressBar(this,"rip_bar");
+  rip_bar=new QProgressBar(100,this,"rip_bar");
   rip_bar->setGeometry(10,480,sizeHint().width()-110,20);
 
   //
@@ -427,13 +427,20 @@
 	  break;
     }
     rip_track=rip_track_list->currentItem()->text(0).toInt()-1;
+    int rip_format=rip_conf->defaultFormat();
+    if(rip_format==5 || rip_format==3) {
+      rip_format=0;
+    }
+    if(rip_format==2) {
+      rip_format=1;
+    }
     if(rip_normalize_box->isChecked()) {
      cmd=QString().sprintf("rd_rip_cd %d %s %d %6.4lf %d %d %d %d %s %s/%s %s/%s",
 	  rip_track_list->currentItem()->text(0).toInt(),
 	  (const char *)rip_conf->ripperDevice(),
 	  rip_conf->paranoiaLevel(),
 	  pow(10.0,(double)(rip_normalize_spin->value())/20.0),
-	  rip_conf->defaultFormat(),
+	  rip_format,
 	  rip_channels_box->currentItem()+1,
 	  rip_conf->defaultSampleRate(),
 	  (rip_channels_box->currentItem()+1)*rip_conf->defaultBitrate()/1000, 
@@ -449,7 +456,7 @@
 	  rip_track_list->currentItem()->text(0).toInt(),
 	  (const char *)rip_conf->ripperDevice(),
 	  rip_conf->paranoiaLevel(),
-	  rip_conf->defaultFormat(),
+	  rip_format,
 	  rip_channels_box->currentItem()+1,
 	  rip_conf->defaultSampleRate(),
 	  (rip_channels_box->currentItem()+1)*rip_conf->defaultBitrate()/1000,
@@ -467,10 +474,25 @@
       if(system(cmd)!=0) {
 	bar_file->remove();
       }
+      else {
+        if(rip_conf->defaultFormat()==5 || rip_conf->defaultFormat()==3) {
+          system(QString().sprintf("rdfilewrite --add-mode --normalize=0 %s",(const char *)rip_wavefile).ascii());
+          chmod(rip_wavefile+".energy",S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
+          chown(rip_wavefile+".energy",RDConfiguration()->uid(),RDConfiguration()->gid());
+          system(QString().sprintf("rd_encode %s %d %d %d %d %s %s",
+                 rip_wavefile.ascii(),
+                 rip_conf->defaultFormat(),
+                 rip_conf->defaultSampleRate(),
+                 rip_channels_box->currentItem()+1,
+                 (rip_channels_box->currentItem()+1)*rip_conf->defaultBitrate()/1000,
+                 RDConfiguration()->audioOwner().ascii(),
+                 RDConfiguration()->audioGroup().ascii()));
+        } 
+      }
       exit(0);
     }
     rip_bar->setProgress(0);
-    rip_bar->setPercentageVisible(true);
+    rip_bar->setPercentageVisible(false);
     rip_bar_timer->start(RIPPER_BAR_INTERVAL,true);
   }
   else {
@@ -589,7 +611,7 @@
 void CdRipper::barTimerData()
 {
   if(ripper_running) {
-    if(rip_multipass) {
+    /*if(rip_multipass) {
       rip_bar->
 	setProgress((int)(50.0*((double)bar_temp_file->
 				size()/(double)rip_temp_length+
@@ -599,6 +621,12 @@
     else {
       rip_bar->setProgress((int)(100.0*(double)bar_file->size()/
 				 (double)rip_finished_length));
+    }*/
+    if(rip_bar->progress()==100) {
+      rip_bar->setProgress(0);
+    }
+    else {
+      rip_bar->setProgress(rip_bar->progress()+10);
     }
     rip_bar_timer->start(RIPPER_BAR_INTERVAL,true);
   }
Index: rdlibrary/disk_ripper.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlibrary/disk_ripper.cpp,v
retrieving revision 1.23
diff -u -r1.23 disk_ripper.cpp
--- rdlibrary/disk_ripper.cpp	18 Aug 2008 15:57:42 -0000	1.23
+++ rdlibrary/disk_ripper.cpp	9 Nov 2008 11:13:46 -0000
@@ -161,14 +161,16 @@
   //
   // Progress Bars
   //
-  rip_disk_bar=new QProgressBar(this,"rip_diskbar_label");
-  rip_diskbar_label=new QLabel(tr("Disk Progress"),this,"rip_diskbar_label");
-  rip_diskbar_label->setFont(label_font);
-  rip_diskbar_label->setAlignment(AlignLeft|AlignVCenter);
-  rip_diskbar_label->setDisabled(true);
-  rip_track_bar=new QProgressBar(this,"rip_track_bar");
-  rip_trackbar_label=new QLabel(tr("Track Progress"),
+//  rip_disk_bar=new QProgressBar(this,"rip_diskbar_label");
+//  rip_diskbar_label=new QLabel(tr("Disk Progress"),this,"rip_diskbar_label");
+//  rip_diskbar_label->setFont(label_font);
+//  rip_diskbar_label->setAlignment(AlignLeft|AlignVCenter);
+//  rip_diskbar_label->setDisabled(true);
+  rip_track_bar=new QProgressBar(100,this,"rip_track_bar");
+  rip_trackbar_label=new QLabel(tr("Ripping Track"),
 				this,"rip_trackbar_label");
+//  rip_trackbar_label=new QLabel(tr("Track Progress"),
+//				this,"rip_trackbar_label");
   rip_trackbar_label->setFont(label_font);
   rip_trackbar_label->setAlignment(AlignLeft|AlignVCenter);
   rip_trackbar_label->setDisabled(true);
@@ -375,8 +377,8 @@
       rip_autotrim_box->setDisabled(true);
       rip_autotrim_spin->setDisabled(true);
       rip_base_length=0;
-      rip_disk_bar->setProgress(0,GetTotalLength());
-      rip_disk_bar->setPercentageVisible(true);
+//      rip_disk_bar->setProgress(0,GetTotalLength());
+//      rip_disk_bar->setPercentageVisible(true);
       RipTrack(item->text(0).toInt(),rip_cutnames[item->text(0).toInt()-1],
 	       item->text(2));
       return;
@@ -593,7 +595,7 @@
 void DiskRipper::barTimerData()
 {
   if(ripper_running) {
-    if(rip_multipass) {
+/*    if(rip_multipass) {
       rip_track_bar->
 	setProgress((int)(50.0*((double)bar_temp_file->
 				size()/(double)rip_temp_length+
@@ -603,9 +605,15 @@
     else {
       rip_track_bar->setProgress((int)(100.0*(double)bar_file->size()/
 				 (double)rip_finished_length));
+    }*/
+    if(rip_track_bar->progress()==100) {
+      rip_track_bar->setProgress(0);
     }
-    rip_disk_bar->setProgress(rip_base_length+bar_temp_file->size()+
-			      bar_file->size());
+    else {
+      rip_track_bar->setProgress(rip_track_bar->progress()+10);
+    }
+//    rip_disk_bar->setProgress(rip_base_length+bar_temp_file->size()+
+//			      bar_file->size());
     rip_bar_timer->start(RIPPER_BAR_INTERVAL,true);
   }
   else {
@@ -615,7 +623,7 @@
       rip_done=true;
       QListViewItem *item=rip_track_list->firstChild();
       rip_base_length+=(rip_temp_length+rip_finished_length);
-      rip_disk_bar->setProgress(rip_base_length);
+//      rip_disk_bar->setProgress(rip_base_length);
       RDCut *cut=new RDCut(rip_cutname);
       cut->reset();
       cut->setOriginName(rdstation_conf->name());
@@ -669,12 +677,13 @@
     rip_channels_box->setEnabled(true);
     rip_autotrim_box->setEnabled(true);
     rip_autotrim_spin->setEnabled(true);
-    rip_disk_bar->setPercentageVisible(false);
-    rip_disk_bar->reset();
-    rip_diskbar_label->setDisabled(true);
+    //rip_disk_bar->setPercentageVisible(false);
+//    rip_disk_bar->reset();
+//    rip_diskbar_label->setDisabled(true);
     rip_trackbar_label->setDisabled(true);
-    rip_diskbar_label->setText(tr("Total Progress"));
-    rip_trackbar_label->setText(tr("Track Progress"));
+//    rip_diskbar_label->setText(tr("Total Progress"));
+    rip_trackbar_label->setText(tr("Ripping Track"));
+//    rip_trackbar_label->setText(tr("Track Progress"));
     QListViewItem *item=rip_track_list->firstChild();
     while(item!=NULL) {
       item->setText(5,"");
@@ -696,8 +705,8 @@
   rip_apply_box->setGeometry(65,118,15,15);
   rip_apply_label->setGeometry(85,118,250,20);
   rip_track_list->setGeometry(10,156,size().width()-112,size().height()-342);
-  rip_diskbar_label->setGeometry(10,size().height()-174,size().width()-110,20);
-  rip_disk_bar->setGeometry(10,size().height()-154,size().width()-110,20); 
+//  rip_diskbar_label->setGeometry(10,size().height()-174,size().width()-110,20);
+//  rip_disk_bar->setGeometry(10,size().height()-154,size().width()-110,20); 
   rip_trackbar_label->setGeometry(10,size().height()-126,size().width()-110,
 				  20);
   rip_track_bar->setGeometry(10,size().height()-106,size().width()-110,20);
@@ -795,17 +804,24 @@
   bar_file->close();
 
   if(title.isEmpty()) {
+//    rip_trackbar_label->
+//      setText(QString().sprintf("%s - Track %d",
+//				(const char *)tr("Track Progress"),track));
     rip_trackbar_label->
       setText(QString().sprintf("%s - Track %d",
-				(const char *)tr("Track Progress"),track));
+				(const char *)tr("Ripping Track"),track));
   }
   else {
+//    rip_trackbar_label->
+//      setText(QString().sprintf("%s - %s",
+//				(const char *)tr("Track Progress"),
+//				(const char *)title));
     rip_trackbar_label->
       setText(QString().sprintf("%s - %s",
-				(const char *)tr("Track Progress"),
+				(const char *)tr("Ripping Track"),
 				(const char *)title));
   }
-  rip_diskbar_label->setEnabled(true);
+//  rip_diskbar_label->setEnabled(true);
   rip_trackbar_label->setEnabled(true);
 
   rip_temp_length=(int)((double)rip_cdrom->trackLength(track)*176.4);
@@ -824,13 +840,20 @@
 		(double)rdlibrary_conf->defaultBitrate()/1411200.0);
 	break;
   }
+  int rip_format=rdlibrary_conf->defaultFormat();
+  if(rip_format==5 || rip_format==3) {
+    rip_format=0;
+  }
+  if(rip_format==2) {
+    rip_format=1;
+  }
   if(rip_normalize_box->isChecked()) {
     cmd=QString().sprintf("rd_rip_cd %d %s %d %6.4lf %d %d %d %d %s %s/%s %s/%s",
 			  rip_track_number,
 			  (const char *)rdlibrary_conf->ripperDevice(),
 			  rdlibrary_conf->paranoiaLevel(),
 			  pow(10.0,(double)(rip_normalize_spin->value())/20.0),
-			  rdlibrary_conf->defaultFormat(),
+			  rip_format,
 			  rip_channels_box->currentItem()+1,
 			  rdlibrary_conf->defaultSampleRate(),
 			  (rip_channels_box->currentItem()+1)*rdlibrary_conf->defaultBitrate()/1000, 
@@ -846,7 +869,7 @@
 			  rip_track_number,
 			  (const char *)rdlibrary_conf->ripperDevice(),
 			  rdlibrary_conf->paranoiaLevel(),
-			  rdlibrary_conf->defaultFormat(),
+			  rip_format,
 			  rip_channels_box->currentItem()+1,
 			  rdlibrary_conf->defaultSampleRate(),
 			  (rip_channels_box->currentItem()+1)*rdlibrary_conf->defaultBitrate()/1000,
@@ -864,10 +887,25 @@
     if(system(cmd)!=0) {
       bar_file->remove();
     }
+    else {
+      if(rdlibrary_conf->defaultFormat()==5 || rdlibrary_conf->defaultFormat()==3) {
+        system(QString().sprintf("rdfilewrite --add-mode --normalize=0 %s",(const char *)rip_wavefile).ascii());
+        chmod(rip_wavefile+".energy",S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
+        chown(rip_wavefile+".energy",RDConfiguration()->uid(),RDConfiguration()->gid());
+        system(QString().sprintf("rd_encode %s %d %d %d %d %s %s",
+               rip_wavefile.ascii(),
+               rdlibrary_conf->defaultFormat(),
+               rdlibrary_conf->defaultSampleRate(),
+               rip_channels_box->currentItem()+1,
+               (rip_channels_box->currentItem()+1)*rdlibrary_conf->defaultBitrate()/1000,
+               RDConfiguration()->audioOwner().ascii(),
+               RDConfiguration()->audioGroup().ascii()));
+      }
+    }
     exit(0);
   }
   rip_track_bar->setProgress(0);
-  rip_track_bar->setPercentageVisible(true);
+  rip_track_bar->setPercentageVisible(false);
   rip_bar_timer->start(RIPPER_BAR_INTERVAL,true);
 }
 
Index: rdlibrary/edit_cart.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlibrary/edit_cart.cpp,v
retrieving revision 1.69
diff -u -r1.69 edit_cart.cpp
--- rdlibrary/edit_cart.cpp	4 Aug 2008 19:05:35 -0000	1.69
+++ rdlibrary/edit_cart.cpp	9 Nov 2008 11:13:46 -0000
@@ -61,21 +61,21 @@
   setMinimumWidth(sizeHint().width());
   setMaximumWidth(sizeHint().width());
   if(lib_cart_list_edit==NULL) {
-  setMinimumHeight(sizeHint().height());
-  setMaximumHeight(sizeHint().height());
-    }
+    setMinimumHeight(sizeHint().height());
+    setMaximumHeight(sizeHint().height());
+  }
   else {
     setMinimumHeight(sizeHint().height()-270);
     setMaximumHeight(sizeHint().height()-270);
-    }
+  }
 
   if(lib_cart_list_edit==NULL) {
-  rdcart_cart=new RDCart(number);
-  rdcart_import_path=path;
-  setCaption(QString().sprintf("%06u",rdcart_cart->number())+" - "+
+    rdcart_cart=new RDCart(number);
+    rdcart_import_path=path;
+    setCaption(QString().sprintf("%06u",rdcart_cart->number())+" - "+
     rdcart_cart->title());
     modification_allowed=
-    lib_user->modifyCarts()&&rdcart_cart->owner().isEmpty();
+     lib_user->modifyCarts()&&rdcart_cart->owner().isEmpty();
   }
   else {
     setCaption("Edit Carts");
@@ -85,11 +85,13 @@
   //
   // Create Default Cut
   //
-  if(new_cart&&(rdcart_cart->type()==RDCart::Audio)) {
-    rdcart_cart->addCut(rdlibrary_conf->defaultFormat(),
+  if(lib_cart_list_edit==NULL) {
+    if(new_cart&&(rdcart_cart->type()==RDCart::Audio)) {
+      rdcart_cart->addCut(rdlibrary_conf->defaultFormat(),
 			rdlibrary_conf->defaultSampleRate(),
 			rdlibrary_conf->defaultBitrate(),
 			rdlibrary_conf->defaultChannels());
+    }
   }
 
   //
@@ -701,7 +703,7 @@
 
 QSize EditCart::sizeHint() const
 {
-  return QSize(640,750);
+  return QSize(640,720);
 } 
 
 
Index: rdlibrary/rdlibrary_de.ts
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlibrary/rdlibrary_de.ts,v
retrieving revision 1.1
diff -u -r1.1 rdlibrary_de.ts
--- rdlibrary/rdlibrary_de.ts	1 Apr 2008 18:27:31 -0000	1.1
+++ rdlibrary/rdlibrary_de.ts	9 Nov 2008 11:13:46 -0000
@@ -162,6 +162,22 @@
         <source>1 Cut</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Updateing audio...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update Audio?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Starting External Editor...</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>CdRipper</name>
@@ -345,14 +361,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Disk Progress</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <source>Track Progress</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>Set
 &amp;Cut</source>
         <translation type="unfinished"></translation>
@@ -459,10 +467,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Total Progress</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>No Access</source>
         <translation type="unfinished"></translation>
     </message>
@@ -474,6 +478,10 @@
         <source>OK</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Ripping Track</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>EditCart</name>
Index: rdlibrary/rdlibrary_es.ts
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlibrary/rdlibrary_es.ts,v
retrieving revision 1.34
diff -u -r1.34 rdlibrary_es.ts
--- rdlibrary/rdlibrary_es.ts	29 Dec 2007 21:05:37 -0000	1.34
+++ rdlibrary/rdlibrary_es.ts	9 Nov 2008 11:13:46 -0000
@@ -162,6 +162,22 @@
 Audio</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Updateing audio...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update Audio?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Starting External Editor...</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>CdRipper</name>
@@ -341,14 +357,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Disk Progress</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <source>Track Progress</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>Set
 &amp;Cut</source>
         <translation type="unfinished"></translation>
@@ -442,10 +450,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Total Progress</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>No Access</source>
         <translation type="unfinished"></translation>
     </message>
@@ -474,6 +478,10 @@
 &amp;New Carts</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Ripping Track</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>EditCart</name>
Index: rdlibrary/rdlibrary_fr.ts
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlibrary/rdlibrary_fr.ts,v
retrieving revision 1.1
diff -u -r1.1 rdlibrary_fr.ts
--- rdlibrary/rdlibrary_fr.ts	1 Apr 2008 18:27:31 -0000	1.1
+++ rdlibrary/rdlibrary_fr.ts	9 Nov 2008 11:13:47 -0000
@@ -162,6 +162,22 @@
         <source>1 Cut</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Updateing audio...</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Update Audio?</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <source>Starting External Editor...</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>CdRipper</name>
@@ -345,14 +361,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Disk Progress</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
-        <source>Track Progress</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>Set
 &amp;Cut</source>
         <translation type="unfinished"></translation>
@@ -459,10 +467,6 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <source>Total Progress</source>
-        <translation type="unfinished"></translation>
-    </message>
-    <message>
         <source>No Access</source>
         <translation type="unfinished"></translation>
     </message>
@@ -474,6 +478,10 @@
         <source>OK</source>
         <translation type="unfinished"></translation>
     </message>
+    <message>
+        <source>Ripping Track</source>
+        <translation type="unfinished"></translation>
+    </message>
 </context>
 <context>
     <name>EditCart</name>
Index: rdlibrary/record_cut.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlibrary/record_cut.cpp,v
retrieving revision 1.86
diff -u -r1.86 record_cut.cpp
--- rdlibrary/record_cut.cpp	4 Aug 2008 19:05:35 -0000	1.86
+++ rdlibrary/record_cut.cpp	9 Nov 2008 11:13:47 -0000
@@ -711,15 +711,28 @@
     QFile(filename).remove();
     switch(rdlibrary_conf->defaultFormat()) {
 	case 0:
-	  rec_cut->setCodingFormat(0);
+          rec_cut->setCodingFormat(rdlibrary_conf->defaultFormat());
 	  rec_format=RDCae::Pcm16;
 	  break;
 
 	case 1:
-	  rec_cut->setCodingFormat(1);
+	case 2:
+          rec_cut->setCodingFormat(rdlibrary_conf->defaultFormat());
 	  rec_format=RDCae::MpegL2;
 	  break;
 
+  	case RDSettings::OggVorbis:
+  	  rec_cut->setCodingFormat(rdlibrary_conf->defaultFormat());
+  	  rec_cut->setBitRate(rdlibrary_conf->defaultBitrate());
+  	  rec_format=RDCae::OggVorbis;
+  	  break;
+  
+  	case RDSettings::MpegL3:
+  	  rec_cut->setCodingFormat(rdlibrary_conf->defaultFormat());
+  	  rec_cut->setBitRate(rdlibrary_conf->defaultBitrate());
+  	  rec_format=RDCae::MpegL3;
+  	  break;
+  
 	default:
 	  rec_cut->setCodingFormat(0);
 	  rec_format=RDCae::Pcm16;
@@ -862,6 +875,10 @@
 
   rec_meter->setLeftSolidBar(-100000);
   rec_meter->setRightSolidBar(-100000);
+  //
+  //if(rec_cut->codingFormat()==5 || rec_cut->codingFormat()==3)
+  //  rec_cut->normalize(rdlibrary_conf->ripperLevel());
+  //
   rec_cut->checkInRecording(rdstation_conf->name());
   if(rec_trim_box->currentItem()==0) {
     rec_cut->autoTrim(RDCut::AudioBoth,rdlibrary_conf->trimThreshold());
Index: rdlogedit/voice_tracker.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlogedit/voice_tracker.cpp,v
retrieving revision 1.77
diff -u -r1.77 voice_tracker.cpp
--- rdlogedit/voice_tracker.cpp	18 Jul 2008 20:06:11 -0000	1.77
+++ rdlogedit/voice_tracker.cpp	9 Nov 2008 11:13:48 -0000
@@ -40,6 +40,7 @@
 #include <rdedit_audio.h>
 #include <rdimport_audio.h>
 #include <rdwavedata.h>
+#include <rdwavefile.h>
 
 #include <globals.h>
 #include <voice_tracker.h>
@@ -494,6 +495,19 @@
   track_close_button->setText(tr("&Close"));
   connect(track_close_button,SIGNAL(clicked()),this,SLOT(closeData()));
 
+
+  //
+  // Progress Dialog
+  //
+  update_progress_dialog=new QProgressDialog(this);
+  update_progress_dialog->setLabelText(tr("Updateing audio..."));
+  update_progress_dialog->setCancelButton(NULL);
+  update_progress_dialog->setTotalSteps(10);
+  update_progress_dialog->setMinimumDuration(1);
+  update_progress_dialog->setCaption("");
+  
+
+
   for(int i=0;i<track_log_event->size();i++) {
     if(track_log_event->logLine(i)->type()==RDLogLine::Track) {
       track_line=i;
@@ -829,6 +843,10 @@
       UpdateControls();
       return;
     }
+    if(track_record_button->text()==tr("Edit")) {
+      extEditor();
+      return;
+    }
     if(!InitTrack()) {
       QMessageBox::warning(this,tr("Cart Creation Failure"),
 			   tr("Unable to create new cart for voice track!"));
@@ -1950,6 +1968,38 @@
     stateChangedData(2,RDPlayDeck::Finished);
   }
   UpdateControls();
+  if(edit_coding==RDCae::OggVorbis || edit_coding==RDCae::MpegL3) {
+    if(fork()==0) {
+      system(QString().sprintf("nice rd_encode %s %d %d %d %d %s %s &",
+              RDCut::pathName(edit_track_cut->cutName()).ascii(),
+ 	      edit_coding,
+ 	      edit_samprate,
+ 	      edit_chans,
+ 	      (edit_chans*edit_bitrate)/1000,
+ 	      RDConfiguration()->audioOwner().ascii(),
+ 	      RDConfiguration()->audioGroup().ascii()));
+      exit(0);
+    } 	      
+  }
+  if(edit_coding==2) {
+    RDWaveFile *wavefile=new RDWaveFile(RDCut::pathName(edit_track_cut->cutName()));
+    wavefile->openWave();
+    if(wavefile->getFormatTag()==WAVE_FORMAT_PCM) {
+      if(fork()==0) {
+      system(QString().sprintf("nice rd_encode %s %d %d %d %d %s %s &",
+              RDCut::pathName(edit_track_cut->cutName()).ascii(),
+ 	      edit_coding,
+ 	      edit_samprate,
+ 	      edit_chans,
+ 	      (edit_chans*edit_bitrate)/1000,
+ 	      RDConfiguration()->audioOwner().ascii(),
+ 	      RDConfiguration()->audioGroup().ascii()));
+        exit(0);
+      } 	      
+    }
+    wavefile->closeWave();
+  }
+
 }
 
 
@@ -2645,7 +2695,6 @@
   if((line<0)||(line>=track_log_event->size())) {
     return QString();
   }
-  QString wavname;
   QString pathname;
   RDLogLine *logline=track_log_event->logLine(line);
   if(line==(track_log_event->size()-1)) {
@@ -3825,8 +3874,17 @@
       track_track1_button->setDisabled(true);
       track_track1_button->setText(tr("Start"));
       track_track1_button->setPalette(track_start_palette);
-      track_record_button->setDisabled(true);
-      track_record_button->setText(tr("Record"));
+      RDLibraryConf *lconf=new RDLibraryConf(log_config->stationName(),0);
+      if((!lconf->enableEditor())||
+          rdstation_conf->editorPath().isEmpty()) {
+        track_record_button->setDisabled(true);
+        track_record_button->setText(tr("Record"));
+      }
+      else {
+        track_record_button->setDisabled(false);
+        track_record_button->setText(tr("Edit"));
+      }
+      delete lconf;
       track_track2_button->setDisabled(true);
       track_finished_button->setEnabled(track_changed);
       track_reset_button->setEnabled(transport_idle);
@@ -3948,9 +4006,18 @@
 	break;
 	
       case 1:
+      case 2:
 	edit_coding=RDCae::MpegL2;
 	break;
 	
+      case 3:
+	edit_coding=RDCae::MpegL3;
+	break;
+	
+      case 5:
+	edit_coding=RDCae::OggVorbis;
+	break;
+	
       default:
 	edit_coding=RDCae::Pcm16;
 	break;
@@ -4118,3 +4185,170 @@
     }
   }
 }
+
+
+void VoiceTracker::extEditor()
+{
+  QString sql;
+  QString edit_cut_name;
+  RDSqlQuery *q;
+  RDWaveFile *wavefile;
+  double level=1.0; 
+  QString extension="wav";
+  
+  if(edit_wave_name[1].isEmpty()) {
+    return;
+  }
+
+  RDLogLine *logline=track_log_event->logLine(edit_track_line[1]);
+  edit_cut_name=logline->cutName();
+ 
+  wavefile=new RDWaveFile(edit_wave_name[1]);
+  if(wavefile->openWave()) {
+    level=wavefile->getNormalizeLevel();
+    switch(wavefile->getFormatTag()) {
+      case WAVE_FORMAT_PCM:
+        extension="wav";
+        break;
+        
+      case WAVE_FORMAT_MPEG:
+        if(wavefile->getHeadLayer()==3) {
+          extension="mp3";
+        }
+        else {
+          extension="mp2";
+	}
+        break;
+        
+      case WAVE_FORMAT_VORBIS:
+        extension="ogg";
+        break;
+    }
+    wavefile->closeWave();
+  }  
+  delete wavefile; 
+
+  QString cmd=rdstation_conf->editorPath();
+  cmd.replace("%f","/tmp/"+edit_cut_name+"."+extension);
+  // FIXME: other replace commands to match: lib/rdcart_dialog.cpp editorData()
+  //        These substitions should be documented (maybe a text file),
+  //            ex: %f = cart_cut filename
+  //        and possibly also add some tooltips with help advice
+
+  update_progress_dialog->setLabelText(tr("Starting External Editor..."));
+  update_progress_dialog->setProgress(1);
+  qApp->processEvents();
+
+ // if(fork()==0) {
+  system(QString().sprintf("cp %s /tmp/%s.%s",
+           edit_wave_name[1].ascii(),edit_cut_name.ascii(),
+           (const char *)extension));
+  system(cmd.ascii());
+ //   exit(0);
+ // }
+
+  update_progress_dialog->setProgress(10);
+  
+  if(QMessageBox::question(this,tr("Update"),
+			    tr("Update Audio?"),
+			    QMessageBox::Yes,
+			    QMessageBox::No)==QMessageBox::No) {
+    return;
+  }
+  
+  update_progress_dialog->setLabelText(tr("Updateing audio..."));
+  update_progress_dialog->setProgress(1);
+  qApp->processEvents();
+
+  //system(QString().sprintf("rd_edit_copy /tmp/%s.%s",edit_cut_name.ascii(),
+  //                           (const char *)extension));
+  
+  wavefile=new RDWaveFile("/tmp/"+edit_cut_name+"."+extension);
+  if(!wavefile->openWave()) {
+    delete wavefile;
+    update_progress_dialog->setProgress(10);
+    return;
+  }
+  
+  if(wavefile->getFormatTag()==WAVE_FORMAT_PCM) {
+    system(QString().sprintf("sox -v %f /tmp/%s.%s -t raw -s -w -c %d -r %d - |\
+                            rdfilewrite --channels=%d --sample-rate=%d %s",
+         level,
+         edit_cut_name.ascii(),
+         (const char *)extension,
+         wavefile->getChannels(),
+         wavefile->getSamplesPerSec(),
+         wavefile->getChannels(),
+         wavefile->getSamplesPerSec(),
+         edit_wave_name[1].ascii()));
+    
+    unlink("/tmp/"+edit_cut_name+"."+extension);
+    unlink(edit_wave_name[1]+".energy");
+  }
+  else {
+    system(QString().sprintf("mv /tmp/%s.%s %s",
+         edit_cut_name.ascii(),
+         (const char *)extension,
+         edit_wave_name[1].ascii()));
+    if(wavefile->getHeadLayer()==3) {
+      RDWaveFile *wavefile_mv=new RDWaveFile(edit_wave_name[1]);
+      wavefile_mv->openWave();
+      wavefile_mv->setNormalizeLevel(level);
+      wavefile_mv->setEnergyTag(1);
+      wavefile_mv->recreateEnergy();
+      wavefile_mv->closeWave();
+      delete wavefile_mv;
+    }
+  }
+  
+  update_progress_dialog->setProgress(5);
+  qApp->processEvents();
+  
+  delete wavefile;
+  wavefile=new RDWaveFile(edit_wave_name[1]);
+  wavefile->openWave();
+
+  sql=QString().sprintf("update CUTS set START_POINT=0,END_POINT=%d,\
+                         FADEUP_POINT=-1,FADEDOWN_POINT=-1,\
+                         SEGUE_START_POINT=-1,SEGUE_END_POINT=-1,\
+                         TALK_START_POINT=-1,TALK_END_POINT=-1,\
+                         HOOK_START_POINT=-1,HOOK_END_POINT=-1,\
+                         LENGTH=%d\
+                         where CUT_NAME=\"%s\"",
+			wavefile->getExtTimeLength(),
+			wavefile->getExtTimeLength(),
+			edit_cut_name.ascii());
+  q=new RDSqlQuery(sql);
+  delete q;
+  RDConfig *lconf=new RDConfig();
+  chmod(edit_wave_name[1],S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
+  chown(edit_wave_name[1],lconf->uid(),lconf->gid());
+  chmod(edit_wave_name[1]+".energy",S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH);
+  chown(edit_wave_name[1]+".energy",lconf->uid(),lconf->gid());
+  delete lconf;
+  update_progress_dialog->setProgress(10);  
+  qApp->processEvents();
+
+  RDCart *rdcart=new RDCart(logline->cartNumber());
+  rdcart->updateLength();
+  delete rdcart;
+  logline->refreshPointers();
+  logline->setStartPoint(0,RDLogLine::LogPointer);
+  logline->setEndPoint(wavefile->getExtTimeLength(),RDLogLine::LogPointer);
+  logline->setFadedownPoint(wavefile->getExtTimeLength(),RDLogLine::LogPointer);
+  logline->setSegueEndPoint(wavefile->getExtTimeLength(),RDLogLine::LogPointer);
+  if(logline->segueStartPoint()>logline->endPoint()) {
+    logline->setSegueStartPoint(logline->endPoint(),RDLogLine::LogPointer);
+  }
+  wavefile->closeWave();
+  delete wavefile;
+  SaveTrack(track_line);
+  LoadTrack(track_line);
+  DrawTrackMap(1);
+  WriteTrackMap(1);
+  DrawTrackMap(2);
+  WriteTrackMap(2);
+  UpdateRemaining();
+  UpdateControls();
+}
+
Index: rdlogedit/voice_tracker.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/rdlogedit/voice_tracker.h,v
retrieving revision 1.46
diff -u -r1.46 voice_tracker.h
--- rdlogedit/voice_tracker.h	29 Dec 2007 18:16:11 -0000	1.46
+++ rdlogedit/voice_tracker.h	9 Nov 2008 11:13:48 -0000
@@ -35,6 +35,7 @@
 #include <qtimer.h>
 #include <qcursor.h>
 #include <qpopupmenu.h>
+#include <qprogressdialog.h>
 
 #include <rdtransportbutton.h>
 #include <rdstereometer.h>
@@ -168,6 +169,8 @@
   void CheckChanges();
   void PushSegues();
   void PopSegues();
+  void extEditor();
+
   RDStereoMeter *track_meter;
   QTimer *track_meter_timer;
   RDTransportButton *track_play_button;
@@ -183,6 +186,8 @@
   QPushButton *track_insert_button;
   QPushButton *track_delete_button;
   QPushButton *track_close_button;
+  QProgressDialog *update_progress_dialog;
+
   RDLog *track_log;
   RDLogEvent *track_log_event;
   RDEventPlayer *track_event_player;
Index: scripts/Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/scripts/Makefile.am,v
retrieving revision 1.13
diff -u -r1.13 Makefile.am
--- scripts/Makefile.am	25 Sep 2007 15:40:45 -0000	1.13
+++ scripts/Makefile.am	9 Nov 2008 11:13:48 -0000
@@ -23,11 +23,14 @@
 ## Use automake to process this into a Makefile.in
 
 bin_SCRIPTS = rd_rip_cd rd_import_file rd_audio_sync rd_config\
-              rd_export_file crc-unity4k.sh rd_backup
+              rd_export_file crc-unity4k.sh rd_backup\
+              rd_encode rd_import_encode rd_import_copy
 
 EXTRA_DIST = rd_rip_cd rd_import_file kill_rd rd_create_db start_rd\
              rd_audio_sync rd_config rd_export_file crc-unity4k.sh\
-             rd_backup
+             rd_backup\
+             rd_encode rd_import_encode rd_import_copy
+
 
 CLEANFILES = *~
 MAINTAINERCLEANFILES = *~ Makefile.in
Index: scripts/rd_export_file
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/scripts/rd_export_file,v
retrieving revision 1.8
diff -u -r1.8 rd_export_file
--- scripts/rd_export_file	18 Sep 2008 19:02:16 -0000	1.8
+++ scripts/rd_export_file	9 Nov 2008 11:13:48 -0000
@@ -115,11 +115,16 @@
 #
 # Convert to PCM (if necessary)
 #
-if [ $FORMAT_IN = 0 ] ; then
-  cp $FILE_IN $WORK
-else
-  mpg321 -q -w $WORK $FILE_IN
-fi
+case $FORMAT_IN in 
+   0)
+    cp $FILE_IN $WORK  ;;
+   2)
+    mpg321 -q -w $WORK $FILE_IN ;;
+   3)
+    mpg321 -q -w $WORK $FILE_IN ;;
+   5)
+    sox -t ogg $FILE_IN -t wav $WORK ;;
+esac
 
 #
 # Get Peak Level
@@ -148,7 +153,7 @@
   ;;
 
   3)  # MPEG Layer 3
-    sox $SOX_SCALE $WORK -r $SAMPRATE_OUT -c $CHANS_OUT -t raw - $RESAMPLE_FLAG | lame --silent -r -x -s $SAMPRATE_OUT -m $MPEG_MODE $LAME_RATE - "$FILE_OUT"
+    sox $SOX_SCALE $WORK -r $SAMPRATE_OUT -c $CHANS_OUT -t wav - $RESAMPLE_FLAG | lame --silent -x -s $SAMPRATE_OUT -m $MPEG_MODE $LAME_RATE - "$FILE_OUT"
   ;;
 
   4)  # FLAC
Index: utils/rdfilewrite/rdfilewrite.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/utils/rdfilewrite/rdfilewrite.cpp,v
retrieving revision 1.6
diff -u -r1.6 rdfilewrite.cpp
--- utils/rdfilewrite/rdfilewrite.cpp	26 Jul 2008 00:01:42 -0000	1.6
+++ utils/rdfilewrite/rdfilewrite.cpp	9 Nov 2008 11:13:48 -0000
@@ -39,9 +39,13 @@
 
 MainObject::MainObject(QObject *parent,const char *name)
 {
-  unsigned sample_rate=0;
-  unsigned channels=0;
+  unsigned sample_rate=44100;
+  unsigned channels=2;
   QString filename;
+  bool add_mode=false;
+  double normalize_level=1.0;
+  bool do_energy=false;
+  unsigned filename_pos=1;
   char buffer[RDFILEWRITE_BUFFER_SIZE];
   size_t n;
 
@@ -53,53 +57,95 @@
   for(unsigned i=0;i<cmd->keys();i++) {
     if(cmd->key(i)=="--channels") {
       channels=cmd->value(i).toUInt();
+      filename_pos++;
     }
     if(cmd->key(i)=="--sample-rate") {
       sample_rate=cmd->value(i).toUInt();
+      filename_pos++;
+    }
+    if(cmd->key(i)=="--add-mode") {
+      add_mode=true;
+      filename_pos++;
+    }
+    if(cmd->key(i)=="--normalize") {
+      normalize_level=cmd->value(i).toDouble();
+      if(normalize_level==0.0) {
+        normalize_level=1.0;
+        }
+      do_energy=true;
+      filename_pos++;
     }
   }
   if(channels==0) {
     fprintf(stderr,"rdfilewrite: missing/invalid --channels argument\n");
-    exit(256);
+    exit(1);
   }
   if(sample_rate==0) {
     fprintf(stderr,"rdfilewrite: missing/invalid --sample-rate argument\n");
-    exit(256);
+    exit(1);
   }
-  if(cmd->keys()!=3) {
+  if(cmd->keys()!=(filename_pos)) {
     fprintf(stderr,"rdfilewrite: missing filename argument\n");
-    exit(256);
+    exit(1);
   }
-  filename=cmd->key(2);
+  filename=cmd->key(filename_pos-1);
   delete cmd;
-
   //
   // Create Output File
   //
+  if(do_energy){
+    unlink(filename+".energy");
+  }
   RDWaveFile *wavefile=new RDWaveFile(filename);
+  if(!add_mode) {
   wavefile->nameWave(filename);
-  wavefile->setFormatTag(WAVE_FORMAT_PCM);
   wavefile->setBitsPerSample(16);
   wavefile->setChannels(channels);
   wavefile->setSamplesPerSec(sample_rate);
+    wavefile->setFormatTag(WAVE_FORMAT_PCM);
+  }  
   wavefile->setBextChunk(true);
   wavefile->setLevlChunk(true);
+  if(do_energy){
+    wavefile->setEnergyTag(1);
+  }
+  else {
+    wavefile->setEnergyTag(0);
+  }
+  if(!add_mode) {
   if(!wavefile->createWave()) {
     fprintf(stderr,"rdfilewrite: unable to open output file\n");
+    wavefile->closeWave();
     delete wavefile;
-    exit(256);
+      exit(1);
   }
 
   //
   // Transfer Data
   //
+  
   while((n=read(0,buffer,RDFILEWRITE_BUFFER_SIZE))>0) {
     wavefile->writeWave(buffer,n);
   }
+  }
+  else {
+    if(!wavefile->openWave()) {
+      fprintf(stderr,"rdfilewrite: unable to open output file\n");
+      delete wavefile;
+      exit(1);
+    }
+    wavefile->recreateEnergy();
+    if(wavefile->energySize()==0) {
+      printf("rdfilewrite: no energy created\n");
+      exit(1);
+    }  
+  }
 
   //
   // Clean Up and Exit
   //
+  if(normalize_level!=1.0f)
+    wavefile->normalize(normalize_level);
   wavefile->closeWave();
   delete wavefile;
   exit(0);
Index: utils/rdimport/rdimport.cpp
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/utils/rdimport/rdimport.cpp,v
retrieving revision 1.23
diff -u -r1.23 rdimport.cpp
--- utils/rdimport/rdimport.cpp	10 Oct 2008 12:32:23 -0000	1.23
+++ utils/rdimport/rdimport.cpp	9 Nov 2008 11:13:49 -0000
@@ -76,6 +76,7 @@
   import_drop_box=false;
   import_stdin_specified=false;
   import_fix_broken_formats=false;
+  open_failed=false;
 
 
   //
@@ -538,6 +539,7 @@
     effective_filename=filename;
   }
   else {
+    if(import_format!=3 && import_format!=5) { 
     if(import_fix_broken_formats) {
       if(import_verbose) {
 	PrintLogDateTime();
@@ -593,6 +595,11 @@
       return MainObject::FileBad;
     }
   }
+    else {
+      effective_filename=filename;
+      open_failed=true;
+    }
+  }  
 
   if(!import_metadata_pattern.isEmpty()) {
     QString groupname=effective_group->name();
@@ -681,6 +688,7 @@
   double normal=pow(10.0,(double)import_normalization_level/2000.0);
   QString cmd;
   if(import_normalization_level==0) {
+    if (import_format!=3 && import_format!=5) {
     cmd=QString().
       sprintf("rd_import_file 0 %d %d %s %d %d %d %d %s %s %s",
 	      format_in,
@@ -695,6 +703,31 @@
 	      (const char *)tempwav_name);
   }
   else {
+      if((import_format!=3 && import_format!=5) || open_failed ||
+        import_samprate!=wavefile->getSamplesPerSec()) {
+        cmd=QString().
+          sprintf("rd_import_encode %s %s %d %d %d %d 0 %s %s",
+	        (const char *)RDEscapeString(effective_filename).utf8(),  
+	        RDCut::pathName(cut->cutName()).ascii(),  
+	        import_format,
+	        import_samprate,
+	        import_channels,
+	        import_channels*import_bitrate/1000,
+	        import_config->audioOwner().ascii(),
+	        import_config->audioGroup().ascii());
+      }
+      else {
+        cmd=QString().
+          sprintf("rd_import_copy %s %s 0 %s %s",
+	        (const char *)RDEscapeString(effective_filename).utf8(),  
+	        RDCut::pathName(cut->cutName()).ascii(),  
+	        import_config->audioOwner().ascii(),
+	        import_config->audioGroup().ascii());
+      }  	      
+    }	      
+  }
+  else {
+    if (import_format!=3 && import_format!=5) {
     cmd=QString().
       sprintf("rd_import_file %6.4f %d %d %s %d %d %d %d %s %s %s",
 	      normal,
@@ -709,6 +742,32 @@
 	      (const char *)tempdat_name,
 	      (const char *)tempwav_name);
   }
+    else {
+      if((import_format!=3 && import_format!=5) || open_failed ||
+        import_samprate!=wavefile->getSamplesPerSec()) {
+        cmd=QString().
+          sprintf("rd_import_encode %s %s %d %d %d %d %f %s %s",
+	        (const char *)RDEscapeString(effective_filename).utf8(),  
+	        RDCut::pathName(cut->cutName()).ascii(),  
+	        import_format,
+	        import_samprate,
+	        import_channels,
+	        import_channels*import_bitrate/1000,
+	        normal,
+	        import_config->audioOwner().ascii(),
+	        import_config->audioGroup().ascii());
+      }
+      else {
+        cmd=QString().
+          sprintf("rd_import_copy %s %s %f %s %s",
+	        (const char *)RDEscapeString(effective_filename).utf8(),  
+	        RDCut::pathName(cut->cutName()).ascii(),  
+	        normal,
+	        import_config->audioOwner().ascii(),
+	        import_config->audioGroup().ascii());
+      }  	      
+    }	      
+  }
   if(import_verbose) {
     PrintLogDateTime();
     if(wavedata->title().length()==0 || ( (wavedata->title().length()>0) && (wavedata->title()[0] == '\0')) ) {
@@ -879,7 +938,7 @@
 RDWaveFile *MainObject::FixFile(const QString &filename,RDWaveData *wavedata)
 {
   bool fix_needed=false;
-
+printf("FixFile\n");
   //
   // Determine Fixability
   //
@@ -1009,6 +1068,7 @@
 
 bool MainObject::FixChunkSizes(const QString &filename)
 {
+printf("FixChunkSizes\n");
   int i;
   char name[5]={0,0,0,0,0};
   unsigned char buffer[4];
Index: utils/rdimport/rdimport.h
===================================================================
RCS file: /home/cvs/cvsroot/rivendell/utils/rdimport/rdimport.h,v
retrieving revision 1.11
diff -u -r1.11 rdimport.h
--- utils/rdimport/rdimport.h	5 Aug 2008 16:20:45 -0000	1.11
+++ utils/rdimport/rdimport.h	9 Nov 2008 11:13:49 -0000
@@ -105,6 +105,7 @@
   };
   std::list<DropboxList *> import_dropbox_list;
   QString import_temp_fix_filename;
+  bool open_failed;
 };
 
 

