File indexing completed on 2025-03-23 04:28:11
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 }