Főoldal | Osztályhierarchia | Osztálylista | Fájllista | Osztálytagok | Fájlelemek | Kapcsolódó lapok

oggwave.cc

00001 /*
00002  * SubTimer source file
00003  *  Copyright (C) 2005 Peter Salvi
00004  *   Last modification: <2005.03.23., 16:16:16>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00019  */
00020 
00021 #include <qdatetime.h>
00022 #include <qprogressdialog.h>
00023 
00024 #include <vorbis/vorbisfile.h>
00025 
00026 #include "common.hh"
00027 #include "oggwave.hh"
00028 
00029 OggWave::OggWave() : WaveFile()
00030 {
00031   ogg = new OggVorbis_File;
00032 }
00033 
00034 OggWave::~OggWave()
00035 {
00036 }
00037 
00038 bool OggWave::open(QString fname, int xres)
00039 {
00040   FILE *f;
00041   f = fopen(fname, "rb");
00042 
00043   if(ov_open(f, ogg, NULL, 0) < 0)
00044     return false;
00045 
00046   if(ov_seekable(ogg) == 0)
00047     return false;
00048 
00049   if(ov_streams(ogg) != 1) {
00050     // todo
00051   }
00052   active_stream = 0;
00053 
00054   channels = ov_info(ogg, active_stream)->channels;
00055   sampling = ov_info(ogg, active_stream)->rate;
00056 
00057   loadWave();
00058   changeRes(xres);
00059 
00060   opened = true;
00061   return true;
00062 }
00063 
00064 void OggWave::close()
00065 {
00066   ov_clear(ogg);
00067   opened = false;
00068 }
00069 
00070 QTime OggWave::length() const
00071 {
00072   return QTIME_MS((int)(1000.0 * ov_time_total(ogg, active_stream)));
00073 }
00074 
00075 void OggWave::loadWave()
00076 {
00077   if(wave != NULL)
00078     delete[] wave;
00079 
00080   char *packet = new char[PACKET_LENGTH * channels];
00081   size_t rate = (size_t)((double)sampling / MAX_PIXPERSEC) * channels;
00082   char *tmp = new char[rate];
00083   size_t tmppos = 0, bufpos = 0;
00084 
00085   double const endtime = ov_time_total(ogg, active_stream);
00086   wavelength = (size_t)(endtime * MAX_PIXPERSEC * 2.0);
00087 
00088   wave = new char[wavelength];
00089 
00090   QProgressDialog progress(QObject::tr("Loading wave..."), 0, wavelength,
00091                            0, "progress", TRUE);
00092 
00093   ov_time_seek(ogg, 0);
00094   while(ov_time_tell(ogg) < endtime && bufpos <= wavelength - 2) {
00095     int curr;
00096     long i = 0;
00097     if((int)((double)bufpos / (double)wavelength * 1000.0) % 10 == 0)
00098       progress.setProgress(bufpos);
00099     long res = ov_read(ogg, packet, PACKET_LENGTH * channels, 0, 1, 1, &curr);
00100     while(i < res) {
00101       while(i < res && tmppos < rate)
00102         tmp[tmppos++] = packet[i++];
00103       if(tmppos == rate) {
00104         if(bufpos <= wavelength - 2) {
00105           char min = 0, max = 0;
00106           for(size_t j = 0; j < rate; ++j) {
00107             char const minmax = tmp[j];
00108             if(minmax < min)
00109               min = minmax;
00110             if(minmax > max)
00111               max = minmax;
00112           }
00113           wave[bufpos++] = min;
00114           wave[bufpos++] = max;
00115         }
00116         tmppos = 0;
00117       }
00118     }
00119     size_t newpos = ((size_t)(ov_time_tell(ogg) * 
00120                               MAX_PIXPERSEC * 2.0) / 2) * 2;
00121     if(newpos > bufpos && bufpos > 2)
00122       for(size_t j = bufpos; j < newpos; ++j)
00123         wave[j] = wave[j - 2];
00124     bufpos = newpos;
00125   }
00126   progress.setProgress(wavelength);
00127 
00128   for(size_t i = bufpos; i < wavelength; ++i)
00129     wave[i] = 0;
00130 
00131   delete[] tmp;
00132   delete[] packet;
00133   
00134 }
00135 
00136 void OggWave::waveFormat(WaveFormat &f) const
00137 {
00138   f.channels = channels;
00139   f.rate = (unsigned int)sampling;
00140   f.format = SND_PCM_FORMAT_S16_LE; 
00141   f.access = SND_PCM_ACCESS_RW_INTERLEAVED;
00142 }
00143 
00144 size_t OggWave::getPlayBufferSize(QTime const start, QTime const end) const
00145 {
00146   double const duration = (double)start.msecsTo(end) / 1000.0;
00147   return (size_t)(duration * (double)sampling) * channels * 2;
00148 }
00149 
00150 void OggWave::getPlayBuffer(QTime const start, char *buf, size_t &size)
00151 {
00152   char *packet = new char[PACKET_LENGTH * channels];
00153   size_t bufpos = 0;
00154 
00155   ov_time_seek(ogg, (double)MSECS(start) / 1000.0);
00156   while(bufpos < size) {
00157     int curr;
00158     long i = 0;
00159     long res = ov_read(ogg, packet, PACKET_LENGTH * channels, 0, 2, 1, &curr);
00160     if(res <= 0)
00161       break;
00162     while(i < res && bufpos < size)
00163       buf[bufpos++] = packet[i++];
00164   }
00165   if(size > bufpos)
00166     size = bufpos;
00167   
00168   delete[] packet;  
00169 }
00170 

Projekt: SubTimer Készült: Wed Mar 23 22:06:53 2005 Készítette: doxygen 1.3.6