File indexing completed on 2024-04-14 04:44:45

0001 /*
0002     SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "k3bmsf.h"
0008 #include <QDebug>
0009 #include <QRegExp>
0010 #include <QSharedData>
0011 
0012 #include <cmath>
0013 
0014 class K3b::Msf::Private : public QSharedData
0015 {
0016 public:
0017     Private( int m = 0, int s = 0, int f = 0 )
0018         : minutes(m),
0019           seconds(s),
0020           frames(f)
0021     {
0022         makeValid();
0023     }
0024 
0025     int minutes;
0026     int seconds;
0027     int frames;
0028 
0029     void setValue( int m = 0, int s = 0, int f = 0 );
0030     void makeValid();
0031 };
0032 
0033 
0034 void K3b::Msf::Private::makeValid()
0035 {
0036     if( frames < 0 ) {
0037         int newFrames = frames/-75 + 1;
0038         seconds -= newFrames;
0039         frames += 75*newFrames;
0040     }
0041     seconds += frames/75;
0042     frames = frames % 75;
0043     if( seconds < 0 ) {
0044         int newSecs = seconds/-60 + 1;
0045         minutes -= newSecs;
0046         seconds += 60*newSecs;
0047     }
0048     minutes += seconds/60;
0049     seconds = seconds % 60;
0050     if( minutes < 0 ) {
0051         minutes = 0;
0052         seconds = 0;
0053         frames = 0;
0054     }
0055 }
0056 
0057 
0058 void K3b::Msf::Private::setValue( int m, int s, int f )
0059 {
0060     minutes = m;
0061     seconds = s;
0062     frames = f;
0063     makeValid();
0064 }
0065 
0066 
0067 K3b::Msf::Msf()
0068     : d( new Private() )
0069 {
0070 }
0071 
0072 
0073 K3b::Msf::Msf( const K3b::Msf& m )
0074 {
0075     d = m.d;
0076 }
0077 
0078 
0079 K3b::Msf::Msf( int m, int s, int f )
0080     : d( new Private( m, s, f ) )
0081 {
0082 }
0083 
0084 
0085 K3b::Msf::Msf( int i )
0086     : d( new Private( 0, 0, i ) )
0087 {
0088 }
0089 
0090 
0091 K3b::Msf::~Msf()
0092 {
0093 }
0094 
0095 
0096 int K3b::Msf::minutes() const
0097 {
0098     return d->minutes;
0099 }
0100 
0101 
0102 int K3b::Msf::seconds() const
0103 {
0104     return d->seconds;
0105 }
0106 
0107 
0108 int K3b::Msf::frames() const
0109 {
0110     return d->frames;
0111 }
0112 
0113 
0114 int K3b::Msf::totalFrames() const
0115 {
0116     return ( d->minutes*60 + d->seconds )*75 + d->frames;
0117 }
0118 
0119 
0120 int K3b::Msf::lba() const
0121 {
0122     return totalFrames();
0123 }
0124 
0125 
0126 void K3b::Msf::setValue( int m, int s, int f )
0127 {
0128     d->setValue( m, s, f );
0129 }
0130 
0131 
0132 void K3b::Msf::addMinutes( int m )
0133 {
0134     d->setValue( d->minutes + m, d->seconds, d->frames );
0135 }
0136 
0137 
0138 void K3b::Msf::addSeconds( int s )
0139 {
0140     d->setValue( d->minutes, d->seconds + s, d->frames );
0141 }
0142 
0143 
0144 void K3b::Msf::addFrames( int f )
0145 {
0146     d->setValue( d->minutes, d->seconds, d->frames + f );
0147 }
0148 
0149 
0150 K3b::Msf& K3b::Msf::operator=( const K3b::Msf& m )
0151 {
0152     d = m.d;
0153     return *this;
0154 }
0155 
0156 
0157 K3b::Msf& K3b::Msf::operator=( int i )
0158 {
0159     d->setValue( 0, 0, i );
0160     return *this;
0161 }
0162 
0163 
0164 K3b::Msf& K3b::Msf::operator+=( const K3b::Msf& m )
0165 {
0166     d->setValue( d->minutes + m.minutes(),
0167                  d->seconds + m.seconds(),
0168                  d->frames + m.frames() );
0169     return *this;
0170 }
0171 
0172 
0173 K3b::Msf& K3b::Msf::operator+=( int i )
0174 {
0175     addFrames(i);
0176     return *this;
0177 }
0178 
0179 
0180 K3b::Msf& K3b::Msf::operator-=( const K3b::Msf& m )
0181 {
0182     d->setValue( d->minutes - m.minutes(),
0183                  d->seconds - m.seconds(),
0184                  d->frames - m.frames() );
0185     return *this;
0186 }
0187 
0188 K3b::Msf& K3b::Msf::operator-=( int i )
0189 {
0190     addFrames( -i );
0191     return *this;
0192 }
0193 
0194 
0195 const K3b::Msf K3b::Msf::operator++( int )
0196 {
0197     Msf old = *this;
0198     ++(*this);
0199     return old;
0200 }
0201 
0202 
0203 K3b::Msf& K3b::Msf::operator++()
0204 {
0205     (*this) += 1;
0206     return *this;
0207 }
0208 
0209 
0210 const K3b::Msf K3b::Msf::operator--( int )
0211 {
0212     Msf old = *this;
0213     --(*this);
0214     return old;
0215 }
0216 
0217 
0218 K3b::Msf& K3b::Msf::operator--()
0219 {
0220     (*this) -= 1;
0221     return *this;
0222 }
0223 
0224 
0225 QString K3b::Msf::toString( bool showFrames ) const
0226 {
0227     QString str;
0228 
0229     if( showFrames )
0230         str = QString::asprintf( "%.2i:%.2i:%.2i", d->minutes, d->seconds, d->frames );
0231     else
0232         str = QString::asprintf( "%.2i:%.2i", d->minutes, d->seconds );
0233 
0234     return str;
0235 }
0236 
0237 
0238 KIO::filesize_t K3b::Msf::mode1Bytes() const
0239 {
0240     return (KIO::filesize_t)2048 * ( (KIO::filesize_t)lba() );
0241 }
0242 
0243 
0244 KIO::filesize_t K3b::Msf::mode2Form1Bytes() const
0245 {
0246     return (KIO::filesize_t)2048 * ( (KIO::filesize_t)lba() );
0247 }
0248 
0249 
0250 KIO::filesize_t K3b::Msf::mode2Form2Bytes() const
0251 {
0252     return (KIO::filesize_t)2324 * ( (KIO::filesize_t)lba() );
0253 }
0254 
0255 
0256 KIO::filesize_t K3b::Msf::audioBytes() const
0257 {
0258     return (KIO::filesize_t)2352 * ( (KIO::filesize_t)lba() );
0259 }
0260 
0261 
0262 KIO::filesize_t K3b::Msf::rawBytes() const
0263 {
0264     return (KIO::filesize_t)2448 * ( (KIO::filesize_t)lba() );
0265 }
0266 
0267 
0268 unsigned long long K3b::Msf::pcmSamples() const
0269 {
0270     return lba()*588;
0271 }
0272 
0273 
0274 QRegExp K3b::Msf::regExp()
0275 {
0276     //
0277     // An MSF can have the following formats:
0278     // 100        (treated as frames)
0279     // 100:23     (minutes:seconds)
0280     // 100:23:72  (minutes:seconds:frames)
0281     // 100:23.72  (minutes:seconds.frames)
0282     //
0283     static QRegExp rx( "(\\d+)(?::([0-5]?\\d)(?:[:\\.]((?:[0-6]?\\d)|(?:7[0-4])))?)?" );
0284     return rx;
0285 }
0286 
0287 
0288 K3b::Msf K3b::Msf::fromSeconds( double ms )
0289 {
0290     return K3b::Msf( static_cast<int>( ::ceil(ms*75.0) ) );
0291 }
0292 
0293 
0294 K3b::Msf K3b::Msf::fromAudioBytes( qint64 bytes )
0295 {
0296     if( bytes % 2352 != 0 ) {
0297         qWarning() << "bytes:" << bytes << "(not aligned to" << 2352 << ")!";
0298     }
0299     return Msf( bytes/2352 );
0300 }
0301 
0302 
0303 K3b::Msf K3b::Msf::fromString( const QString& s, bool* ok )
0304 {
0305     QRegExp rx = regExp();
0306 
0307     K3b::Msf msf;
0308 
0309     if( rx.exactMatch( s ) ) {
0310         //
0311         // first number - cap(1)
0312         // second number - cap(2)
0313         // third number - cap(3)
0314         //
0315         if( rx.cap(2).isEmpty() ) {
0316             msf.d->setValue( 0, 0, rx.cap(1).toInt() );
0317         }
0318         else {
0319             msf.d->setValue( rx.cap(1).toInt(), rx.cap(2).toInt(), rx.cap(3).toInt() );
0320         }
0321 
0322         if( ok ) {
0323             *ok = true;
0324         }
0325     }
0326     else if( ok ) {
0327         *ok = false;
0328     }
0329 
0330     return msf;
0331 }
0332 
0333 
0334 
0335 K3b::Msf K3b::operator+( const K3b::Msf& m1, const K3b::Msf& m2 )
0336 {
0337     K3b::Msf msf(m1);
0338     return msf += m2;
0339 }
0340 
0341 
0342 K3b::Msf K3b::operator+( const K3b::Msf& m, int i )
0343 {
0344     K3b::Msf msf(m);
0345     return msf += i;
0346 }
0347 
0348 
0349 K3b::Msf K3b::operator-( const K3b::Msf& m1, const K3b::Msf& m2 )
0350 {
0351     K3b::Msf msf(m1);
0352     return msf -= m2;
0353 }
0354 
0355 
0356 K3b::Msf K3b::operator-( const K3b::Msf& m, int i )
0357 {
0358     K3b::Msf msf(m);
0359     return msf -= i;
0360 }
0361 
0362 
0363 bool K3b::operator==( const K3b::Msf& m1, const K3b::Msf& m2 )
0364 {
0365     return ( m1.minutes() == m2.minutes() &&
0366              m1.seconds() == m2.seconds() &&
0367              m1.frames() == m2.frames() );
0368 }
0369 
0370 
0371 bool K3b::operator!=( const K3b::Msf& m1, const K3b::Msf& m2 )
0372 {
0373     return !operator==( m1, m2 );
0374 }
0375 
0376 
0377 bool K3b::operator<( const K3b::Msf& m1, const K3b::Msf& m2 )
0378 {
0379     return ( m1.lba() < m2.lba() );
0380 }
0381 
0382 
0383 bool K3b::operator>( const K3b::Msf& m1, const K3b::Msf& m2 )
0384 {
0385     return ( m1.lba() > m2.lba() );
0386 }
0387 
0388 
0389 bool K3b::operator<=( const K3b::Msf& m1, const K3b::Msf& m2 )
0390 {
0391     return ( m1.lba() <= m2.lba() );
0392 }
0393 
0394 
0395 bool K3b::operator>=( const K3b::Msf& m1, const K3b::Msf& m2 )
0396 {
0397     return ( m1.lba() >= m2.lba() );
0398 }
0399 
0400 
0401 QDebug& K3b::operator<<( QDebug& s, const Msf& m )
0402 {
0403     return s << m.toString();
0404 }