diff --git a/Plugins/FileSource/FileSource.m b/Plugins/FileSource/FileSource.m index 6343a5c09..51a9167b3 100644 --- a/Plugins/FileSource/FileSource.m +++ b/Plugins/FileSource/FileSource.m @@ -30,7 +30,7 @@ - (BOOL)seekable { - return YES; + return NO; } - (BOOL)seek:(long)position whence:(int)whence diff --git a/Plugins/HTTPSource/HTTPSource.h b/Plugins/HTTPSource/HTTPSource.h index eb5310531..5977ba95e 100644 --- a/Plugins/HTTPSource/HTTPSource.h +++ b/Plugins/HTTPSource/HTTPSource.h @@ -15,6 +15,8 @@ { Socket *_socket; + BOOL pastHeader; + long byteCount; } diff --git a/Plugins/HTTPSource/HTTPSource.m b/Plugins/HTTPSource/HTTPSource.m index 1fc9e2931..3320e2edf 100644 --- a/Plugins/HTTPSource/HTTPSource.m +++ b/Plugins/HTTPSource/HTTPSource.m @@ -28,6 +28,7 @@ if (_socket) { NSData *request = [[NSString stringWithFormat:@"GET %@ HTTP/1.0\nHOST: %@\n\n",[url path],[url host]] dataUsingEncoding:NSUTF8StringEncoding]; [_socket send:(void *)[request bytes] amount:[request length]]; + pastHeader = NO; } return (_socket != nil); @@ -56,6 +57,44 @@ - (int)read:(void *)buffer amount:(int)amount { int l = [_socket receive:buffer amount:amount]; + + if (!pastHeader) { + uint8_t *f = (uint8_t *)strnstr((const char *)buffer, "\r\n\r\n", l); + if (f) + { + pastHeader = YES; + + uint8_t *bufferOffset = f + 4; //\r\n\r\n + uint8_t *bufferEnd = (uint8_t *)buffer + l; + int amountRemaining = bufferEnd - bufferOffset; + + /* + //For testing only + FILE *testFout = fopen("header.raw", "w"); + fwrite(buffer, 1, bufferOffset - (uint8_t *)buffer, testFout); + fclose(testFout); + + testFout = fopen("test.raw", "w"); + fwrite(bufferOffset, 1, amountRemaining, testFout); + fclose(testFout); + */ + + memmove(buffer,bufferOffset, amountRemaining); + + return amountRemaining + [self read:((uint8_t *)buffer + amountRemaining) amount:(amount - amountRemaining)]; + } + else { + //Keep searching for header. Note: NEED TO WATCH BOUNDARY CASES + return [self read:buffer amount:amount]; + } + } + + /* + //FOR TESTING ONLY + FILE *testFout = fopen("test.raw", "a"); + fwrite(buffer, 1, l, testFout); + fclose(testFout); + */ if (l > 0) byteCount += l; diff --git a/Plugins/MAD/MADDecoder.h b/Plugins/MAD/MADDecoder.h index 2802e620c..da4f13ff5 100644 --- a/Plugins/MAD/MADDecoder.h +++ b/Plugins/MAD/MADDecoder.h @@ -33,6 +33,8 @@ BOOL _seekSkip; + BOOL _firstFrame; + //For gapless playback of mp3s BOOL _gapless; long _currentFrame; diff --git a/Plugins/MAD/MADDecoder.m b/Plugins/MAD/MADDecoder.m index a308b0326..fc1a40c0f 100644 --- a/Plugins/MAD/MADDecoder.m +++ b/Plugins/MAD/MADDecoder.m @@ -270,6 +270,8 @@ int parse_headers(struct xing *xing, struct lame *lame, struct mad_bitptr ptr, u length = mad_timer_count(_duration, MAD_UNITS_MILLISECONDS); bitrate /= 1000; + + bitsPerSample = 16; [_source seek:0 whence:SEEK_SET]; @@ -291,10 +293,14 @@ int parse_headers(struct xing *xing, struct lame *lame, struct mad_bitptr ptr, u mad_frame_init(&_frame); mad_synth_init(&_synth); mad_timer_reset(&_timer); - - bitsPerSample = 16; - return [self scanFileFast:YES useXing:YES]; + _firstFrame = YES; + + if ([_source seekable]) { + return [self scanFileFast:YES useXing:YES]; + } + NSLog(@"NOT SCANNING FILE!!!"); + return YES; } @@ -506,6 +512,18 @@ static inline signed int scale (mad_fixed_t sample) continue; } + if (_firstFrame && ![_source seekable]) { + frequency = _frame.header.samplerate; + channels = MAD_NCHANNELS(&_frame.header); + bitsPerSample = 16; + + NSLog(@"FORMAT CHANGED: %f", frequency); + [self willChangeValueForKey:@"properties"]; + [self didChangeValueForKey:@"properties"]; + + _firstFrame = NO; + } + mad_timer_add (&_timer, _frame.header.duration); mad_synth_frame (&_synth, &_frame);