Changeset 1009
- Timestamp:
- 10/17/07 09:10:58 (15 months ago)
- Location:
- trunk/Audio/Decoders
- Files:
-
- 2 modified
-
MPEGDecoder.h (modified) (1 diff)
-
MPEGDecoder.m (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Audio/Decoders/MPEGDecoder.h
r1008 r1009 26 26 @interface MPEGDecoder : AudioDecoder 27 27 { 28 int _fd;28 FILE *_file; 29 29 unsigned char *_inputBuffer; 30 30 -
trunk/Audio/Decoders/MPEGDecoder.m
r1008 r1009 94 94 NSAssert(NULL != _inputBuffer, @"Unable to allocate memory"); 95 95 96 _f d = open([[[self URL] path] fileSystemRepresentation], O_RDONLY);97 if( -1 == _fd) {96 _file = fopen([[[self URL] path] fileSystemRepresentation], "r"); 97 if(NULL == _file) { 98 98 if(nil != error) { 99 99 NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary]; 100 101 // [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedStringFromTable(@"The format of the file \"%@\" was not recognized.", @"Errors", @""), [[NSFileManager defaultManager] displayNameAtPath:path]] forKey:NSLocalizedDescriptionKey]; 102 // [errorDictionary setObject:NSLocalizedStringFromTable(@"File Format Not Recognized", @"Errors", @"") forKey:NSLocalizedFailureReasonErrorKey]; 103 // [errorDictionary setObject:NSLocalizedStringFromTable(@"The file's extension may not match the file's type.", @"Errors", @"") forKey:NSLocalizedRecoverySuggestionErrorKey]; 104 105 *error = [NSError errorWithDomain:NSPOSIXErrorDomain 106 code:errno 107 userInfo:errorDictionary]; 100 108 } 101 109 … … 150 158 151 159 free(_inputBuffer), _inputBuffer = NULL; 152 close(_fd), _fd = -1;160 fclose(_file), _file = NULL; 153 161 154 162 if(_bufferList) { … … 171 179 { 172 180 double fraction = (double)frame / [self totalFrames]; 173 off_tseekPoint = 0;181 long seekPoint = 0; 174 182 175 183 // If a Xing header was found, interpolate in TOC … … 188 196 189 197 double x = firstOffset + (secondOffset - firstOffset) * (percent - firstIndex); 190 seekPoint = ( off_t)((1.0 / 256.0) * x * _fileBytes);198 seekPoint = (long)((1.0 / 256.0) * x * _fileBytes); 191 199 } 192 200 else 193 seekPoint = ( off_t)_fileBytes * fraction;194 195 off_t result = lseek(_fd, seekPoint, SEEK_SET);196 if( -1 != result) {201 seekPoint = (long)_fileBytes * fraction; 202 203 int result = fseek(_file, seekPoint, SEEK_SET); 204 if(0 == result) { 197 205 mad_stream_buffer(&_mad_stream, NULL, 0); 198 206 … … 270 278 if(NULL == _mad_stream.buffer || MAD_ERROR_BUFLEN == _mad_stream.error) { 271 279 if(NULL != _mad_stream.next_frame) { 272 bytesRemaining = _mad_stream.bufend - _mad_stream.next_frame; 273 280 bytesRemaining = _mad_stream.bufend - _mad_stream.next_frame; 274 281 memmove(_inputBuffer, _mad_stream.next_frame, bytesRemaining); 275 282 … … 284 291 285 292 // Read raw bytes from the MP3 file 286 ssize_t bytesRead = read(_fd, readStartPointer, bytesToRead); 287 288 if(-1 == bytesRead) { 293 size_t bytesRead = fread(readStartPointer, 1, bytesToRead, _file); 294 if(ferror(_file)) { 289 295 #if DEBUG 290 296 NSLog(@"Read error: %s.", strerror(errno)); … … 294 300 295 301 // MAD_BUFFER_GUARD zeroes are required to decode the last frame of the file 296 if(0 == bytesRead ) {302 if(0 == bytesRead && feof(_file)) { 297 303 memset(readStartPointer + bytesRead, 0, MAD_BUFFER_GUARD); 298 304 bytesRead += MAD_BUFFER_GUARD; … … 307 313 int result = mad_frame_decode(&_mad_frame, &_mad_stream); 308 314 if(-1 == result) { 309 310 315 if(MAD_RECOVERABLE(_mad_stream.error)) { 311 312 316 // Prevent ID3 tags from reporting recoverable frame errors 313 317 const uint8_t *buffer = _mad_stream.this_frame; … … 324 328 mad_stream_skip(&_mad_stream, id3_length); 325 329 } 326 else {327 330 #if DEBUG 331 else 328 332 NSLog(@"Recoverable frame level error (%s)", mad_stream_errorstr(&_mad_stream)); 329 333 #endif 330 }331 334 332 335 continue; … … 352 355 353 356 // Skip any samples that remain from last frame 354 // This can happen if the LAMEencoder delay is greater than the number of samples in a frame355 // This normally won't happen, but is possible for MP3s that have been gaplessly cut357 // This can happen if the encoder delay is greater than the number of samples in a frame 358 // This normally won't happen, but is possible 356 359 unsigned startingSample = _samplesToSkipInNextFrame; 357 360 … … 401 404 402 405 _currentFrame += framesRead; 406 403 407 return framesRead; 404 408 } … … 412 416 uint32_t framesDecoded = 0; 413 417 UInt32 bytesToRead, bytesRemaining; 414 s size_t bytesRead;418 size_t bytesRead; 415 419 unsigned char *readStartPointer; 416 420 BOOL readEOF; … … 429 433 readEOF = NO; 430 434 431 result = fstat( _fd, &stat);435 result = fstat(fileno(_file), &stat); 432 436 if(-1 == result) 433 437 return NO; … … 437 441 for(;;) { 438 442 if(NULL == stream.buffer || MAD_ERROR_BUFLEN == stream.error) { 439 440 443 if(stream.next_frame) { 441 bytesRemaining = stream.bufend - stream.next_frame; 442 444 bytesRemaining = stream.bufend - stream.next_frame; 443 445 memmove(_inputBuffer, stream.next_frame, bytesRemaining); 444 446 … … 453 455 454 456 // Read raw bytes from the MP3 file 455 bytesRead = read(_fd, readStartPointer, bytesToRead); 456 457 if(-1 == bytesRead) { 457 bytesRead = fread(readStartPointer, 1, bytesToRead, _file); 458 if(ferror(_file)) { 458 459 #if DEBUG 459 460 NSLog(@"Read error: %s.", strerror(errno)); … … 463 464 464 465 // MAD_BUFFER_GUARD zeroes are required to decode the last frame of the file 465 if(0 == bytesRead ) {466 if(0 == bytesRead && feof(_file)) { 466 467 memset(readStartPointer + bytesRead, 0, MAD_BUFFER_GUARD); 467 468 bytesRead += MAD_BUFFER_GUARD; … … 474 475 475 476 result = mad_frame_decode(&frame, &stream); 476 477 477 if(-1 == result) { 478 479 478 if(MAD_RECOVERABLE(stream.error)) { 480 481 479 // Prevent ID3 tags from reporting recoverable frame errors 482 480 const uint8_t *buffer = stream.this_frame; … … 492 490 mad_stream_skip(&stream, id3_length); 493 491 } 494 else {495 492 #if DEBUG 493 else 496 494 NSLog(@"Recoverable frame level error (%s)", mad_stream_errorstr(&stream)); 497 495 #endif 498 }499 496 500 497 continue; … … 518 515 // Reference http://www.codeproject.com/audio/MPEGAudioInfo.asp 519 516 if(1 == framesDecoded) { 520 521 517 _format.mSampleRate = frame.header.samplerate; 522 518 _format.mChannelsPerFrame = MAD_NCHANNELS(&frame.header); … … 549 545 550 546 if('Xing' == magic || 'Info' == magic) { 551 // if((('X' << 24) | ('i' << 16) | ('n' << 8) | ('g')) == magic) {552 553 547 unsigned i; 554 548 uint32_t flags = 0, frames = 0, bytes = 0, vbrScale = 0; … … 670 664 671 665 } 672 }673 }666 } 667 } 674 668 else { 675 669 // Just estimate the number of frames based on the file's size … … 679 673 break; 680 674 } 681 }675 } 682 676 683 677 // Clean up … … 686 680 687 681 // Rewind to the beginning of file 688 if(-1 == lseek(_fd, 0, SEEK_SET))682 if(-1 == fseek(_file, 0, SEEK_SET)) 689 683 return NO; 690 684 691 685 return YES; 692 }686 } 693 687 694 688 @end
