[Input API] Change input readAudio method

readAudio now returns an AudioChunk object directly, and all inputs have
been changed to accomodate this. Also, input and converter processing
have been altered to better work with this.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
main
Christopher Snowhill 2022-07-10 15:14:47 -07:00
parent 8bc9738ccb
commit 3c351f6968
58 changed files with 472 additions and 251 deletions

View File

@ -80,6 +80,7 @@ enum {
+ (uint32_t)findChannelIndex:(uint32_t)flag; + (uint32_t)findChannelIndex:(uint32_t)flag;
- (id)init; - (id)init;
- (id)initWithProperties:(NSDictionary *)properties;
- (void)assignSamples:(const void *)data frameCount:(size_t)count; - (void)assignSamples:(const void *)data frameCount:(size_t)count;
@ -88,6 +89,7 @@ enum {
- (BOOL)isEmpty; - (BOOL)isEmpty;
- (size_t)frameCount; - (size_t)frameCount;
- (void)setFrameCount:(size_t)count; // For truncation only
- (double)duration; - (double)duration;

View File

@ -7,6 +7,8 @@
#import "AudioChunk.h" #import "AudioChunk.h"
#import "CoreAudioUtils.h"
@implementation AudioChunk @implementation AudioChunk
- (id)init { - (id)init {
@ -21,6 +23,18 @@
return self; return self;
} }
- (id)initWithProperties:(NSDictionary *)properties {
self = [super init];
if(self) {
chunkData = [[NSMutableData alloc] init];
[self setFormat:propertiesToASBD(properties)];
lossless = [[properties objectForKey:@"encoding"] isEqualToString:@"lossless"];
}
return self;
}
static const uint32_t AudioChannelConfigTable[] = { static const uint32_t AudioChannelConfigTable[] = {
0, 0,
AudioConfigMono, AudioConfigMono,
@ -156,6 +170,16 @@ static const uint32_t AudioChannelConfigTable[] = {
return 0; return 0;
} }
- (void)setFrameCount:(size_t)count {
if(formatAssigned) {
count *= format.mBytesPerPacket;
size_t currentLength = [chunkData length];
if(count < currentLength) {
[chunkData replaceBytesInRange:NSMakeRange(count, currentLength - count) withBytes:NULL length:0];
}
}
}
- (double)duration { - (double)duration {
if(formatAssigned) { if(formatAssigned) {
const size_t bytesPerPacket = format.mBytesPerPacket; const size_t bytesPerPacket = format.mBytesPerPacket;

View File

@ -432,34 +432,32 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
} }
- (void)process { - (void)process {
char writeBuf[CHUNK_SIZE];
// Removed endOfStream check from here, since we want to be able to flush the converter // Removed endOfStream check from here, since we want to be able to flush the converter
// when the end of stream is reached. Convert function instead processes what it can, // when the end of stream is reached. Convert function instead processes what it can,
// and returns 0 samples when it has nothing more to process at the end of stream. // and returns 0 samples when it has nothing more to process at the end of stream.
while([self shouldContinue] == YES) { while([self shouldContinue] == YES) {
int amountConverted; AudioChunk *chunk = nil;
while(paused) { while(paused) {
usleep(500); usleep(500);
} }
@autoreleasepool { @autoreleasepool {
amountConverted = [self convert:writeBuf amount:CHUNK_SIZE]; chunk = [self convert];
} }
if(!amountConverted) { if(!chunk) {
if(paused) { continue;
continue; }
} else if(streamFormatChanged) { @autoreleasepool {
[self cleanUp]; [self writeChunk:chunk];
[self setupWithInputFormat:newInputFormat withInputConfig:newInputChannelConfig isLossless:rememberedLossless]; chunk = nil;
continue; }
} else if(streamFormatChanged) {
break; [self cleanUp];
[self setupWithInputFormat:newInputFormat withInputConfig:newInputChannelConfig isLossless:rememberedLossless];
} }
[self writeData:writeBuf amount:amountConverted];
} }
} }
- (int)convert:(void *)dest amount:(int)amount { - (AudioChunk *)convert {
UInt32 ioNumberPackets; UInt32 ioNumberPackets;
int amountReadFromFC; int amountReadFromFC;
int amountRead = 0; int amountRead = 0;
@ -472,7 +470,7 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
tryagain: tryagain:
if(stopping || [self shouldContinue] == NO) { if(stopping || [self shouldContinue] == NO) {
convertEntered = NO; convertEntered = NO;
return amountRead; return nil;
} }
amountReadFromFC = 0; amountReadFromFC = 0;
@ -543,7 +541,7 @@ tryagain:
if(!bytesReadFromInput) { if(!bytesReadFromInput) {
convertEntered = NO; convertEntered = NO;
return amountRead; return nil;
} }
if(bytesReadFromInput && isBigEndian) { if(bytesReadFromInput && isBigEndian) {
@ -703,19 +701,22 @@ tryagain:
if(floatOffset == floatSize) if(floatOffset == floatSize)
goto tryagain; goto tryagain;
ioNumberPackets = (amount - amountRead); ioNumberPackets = (UInt32)(floatSize - floatOffset);
if(ioNumberPackets > (floatSize - floatOffset))
ioNumberPackets = (UInt32)(floatSize - floatOffset);
ioNumberPackets -= ioNumberPackets % dmFloatFormat.mBytesPerPacket; ioNumberPackets -= ioNumberPackets % dmFloatFormat.mBytesPerPacket;
memcpy(((uint8_t *)dest) + amountRead, ((uint8_t *)floatBuffer) + floatOffset, ioNumberPackets); AudioChunk *chunk = [[AudioChunk alloc] init];
[chunk setFormat:nodeFormat];
if(nodeChannelConfig) {
[chunk setChannelConfig:nodeChannelConfig];
}
[chunk assignSamples:floatBuffer frameCount:ioNumberPackets / dmFloatFormat.mBytesPerPacket];
floatOffset += ioNumberPackets; floatOffset += ioNumberPackets;
amountRead += ioNumberPackets; amountRead += ioNumberPackets;
convertEntered = NO; convertEntered = NO;
return amountRead; return chunk;
} }
- (void)observeValueForKeyPath:(NSString *)keyPath - (void)observeValueForKeyPath:(NSString *)keyPath

View File

@ -142,10 +142,6 @@ static void *kInputNodeContext = &kInputNodeContext;
} }
- (void)process { - (void)process {
int amountInBuffer = 0;
int bytesInBuffer = 0;
void *inputBuffer = malloc(CHUNK_SIZE * 8 * 18); // Maximum 18 channels, dunno what we'll receive
BOOL shouldClose = YES; BOOL shouldClose = YES;
BOOL seekError = NO; BOOL seekError = NO;
@ -165,7 +161,6 @@ static void *kInputNodeContext = &kInputNodeContext;
ConverterNode *converter = [bufferChain converter]; ConverterNode *converter = [bufferChain converter];
DLog(@"SEEKING! Resetting Buffer"); DLog(@"SEEKING! Resetting Buffer");
amountInBuffer = 0;
// This resets the converter's buffer // This resets the converter's buffer
[self resetBuffer]; [self resetBuffer];
[converter resetBuffer]; [converter resetBuffer];
@ -174,7 +169,9 @@ static void *kInputNodeContext = &kInputNodeContext;
DLog(@"Reset buffer!"); DLog(@"Reset buffer!");
DLog(@"SEEKING!"); DLog(@"SEEKING!");
seekError = [decoder seek:seekFrame] < 0; @autoreleasepool {
seekError = [decoder seek:seekFrame] < 0;
}
shouldSeek = NO; shouldSeek = NO;
DLog(@"Seeked! Resetting Buffer"); DLog(@"Seeked! Resetting Buffer");
@ -185,44 +182,39 @@ static void *kInputNodeContext = &kInputNodeContext;
} }
} }
if(amountInBuffer < CHUNK_SIZE) { AudioChunk *chunk;
int framesToRead = CHUNK_SIZE - amountInBuffer; @autoreleasepool {
int framesRead; chunk = [decoder readAudio];
}
if(chunk) {
@autoreleasepool { @autoreleasepool {
framesRead = [decoder readAudio:((char *)inputBuffer) + bytesInBuffer frames:framesToRead]; [self writeChunk:chunk];
chunk = nil;
}
} else {
DLog(@"End of stream? %@", [self properties]);
endOfStream = YES;
shouldClose = [controller endOfInputReached]; // Lets us know if we should keep going or not (occassionally, for track changes within a file)
DLog(@"closing? is %i", shouldClose);
// Move this here, so that the above endOfInputReached has a chance to queue another track before starting output
// Technically, the output should still play out its buffer first before checking if it should stop
if(initialBufferFilled == NO) {
[controller initialBufferFilled:self];
} }
if(framesRead > 0 && !seekError) { // wait before exiting, as we might still get seeking request
amountInBuffer += framesRead; DLog("InputNode: Before wait")
bytesInBuffer += framesRead * bytesPerFrame; [exitAtTheEndOfTheStream waitIndefinitely];
[self writeData:inputBuffer amount:bytesInBuffer]; DLog("InputNode: After wait, should seek = %d", shouldSeek);
amountInBuffer = 0; if(shouldSeek) {
bytesInBuffer = 0; endOfStream = NO;
shouldClose = NO;
continue;
} else { } else {
DLog(@"End of stream? %@", [self properties]); break;
endOfStream = YES;
shouldClose = [controller endOfInputReached]; // Lets us know if we should keep going or not (occassionally, for track changes within a file)
DLog(@"closing? is %i", shouldClose);
// Move this here, so that the above endOfInputReached has a chance to queue another track before starting output
// Technically, the output should still play out its buffer first before checking if it should stop
if(initialBufferFilled == NO) {
[controller initialBufferFilled:self];
}
// wait before exiting, as we might still get seeking request
DLog("InputNode: Before wait")
[exitAtTheEndOfTheStream waitIndefinitely];
DLog("InputNode: After wait, should seek = %d", shouldSeek);
if(shouldSeek) {
endOfStream = NO;
shouldClose = NO;
continue;
}
else {
break;
}
} }
} }
} }
@ -230,8 +222,6 @@ static void *kInputNodeContext = &kInputNodeContext;
if(shouldClose) if(shouldClose)
[decoder close]; [decoder close];
free(inputBuffer);
[exitAtTheEndOfTheStream signal]; [exitAtTheEndOfTheStream signal];
DLog("Input node thread stopping"); DLog("Input node thread stopping");

View File

@ -19,7 +19,7 @@
ChunkList *buffer; ChunkList *buffer;
Semaphore *semaphore; Semaphore *semaphore;
NSRecursiveLock *accessLock; NSLock *accessLock;
id __weak previousNode; id __weak previousNode;
id __weak controller; id __weak controller;
@ -37,6 +37,7 @@
- (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p; - (id _Nullable)initWithController:(id _Nonnull)c previous:(id _Nullable)p;
- (void)writeData:(const void *_Nonnull)ptr amount:(size_t)a; - (void)writeData:(const void *_Nonnull)ptr amount:(size_t)a;
- (void)writeChunk:(AudioChunk *_Nonnull)chunk;
- (AudioChunk *_Nonnull)readChunk:(size_t)maxFrames; - (AudioChunk *_Nonnull)readChunk:(size_t)maxFrames;
- (BOOL)peekFormat:(AudioStreamBasicDescription *_Nonnull)format channelConfig:(uint32_t *_Nonnull)config; - (BOOL)peekFormat:(AudioStreamBasicDescription *_Nonnull)format channelConfig:(uint32_t *_Nonnull)config;

View File

@ -25,7 +25,7 @@
buffer = [[ChunkList alloc] initWithMaximumDuration:3.0]; buffer = [[ChunkList alloc] initWithMaximumDuration:3.0];
semaphore = [[Semaphore alloc] init]; semaphore = [[Semaphore alloc] init];
accessLock = [[NSRecursiveLock alloc] init]; accessLock = [[NSLock alloc] init];
initialBufferFilled = NO; initialBufferFilled = NO;
@ -91,6 +91,35 @@
[accessLock unlock]; [accessLock unlock];
} }
- (void)writeChunk:(AudioChunk *)chunk {
[accessLock lock];
const double chunkDuration = [chunk duration];
double durationLeft = [buffer maxDuration] - [buffer listDuration];
while(shouldContinue == YES && chunkDuration > durationLeft) {
if(durationLeft < chunkDuration) {
if(initialBufferFilled == NO) {
initialBufferFilled = YES;
if([controller respondsToSelector:@selector(initialBufferFilled:)])
[controller performSelector:@selector(initialBufferFilled:) withObject:self];
}
}
if(durationLeft < chunkDuration || shouldReset) {
[accessLock unlock];
[semaphore wait];
[accessLock lock];
}
durationLeft = [buffer maxDuration] - [buffer listDuration];
}
[buffer addChunk:chunk];
[accessLock unlock];
}
// Should be overwriten by subclass. // Should be overwriten by subclass.
- (void)process { - (void)process {
} }

View File

@ -79,9 +79,9 @@ static void *kCogDecoderMultiContext = &kCogDecoderMultiContext;
return @{}; return @{};
} }
- (int)readAudio:(void *)buffer frames:(UInt32)frames { - (AudioChunk *)readAudio {
if(theDecoder != nil) return [theDecoder readAudio:buffer frames:frames]; if(theDecoder != nil) return [theDecoder readAudio];
return 0; return nil;
} }
- (BOOL)open:(id<CogSource>)source { - (BOOL)open:(id<CogSource>)source {

View File

@ -1,5 +1,7 @@
// Plugins! HOORAY! // Plugins! HOORAY!
#import "AudioChunk.h"
@protocol CogSource <NSObject> @protocol CogSource <NSObject>
+ (NSArray *)schemes; // http, file, etc + (NSArray *)schemes; // http, file, etc
@ -42,7 +44,7 @@
- (NSDictionary *)properties; - (NSDictionary *)properties;
- (NSDictionary *)metadata; // Only to be implemented for dynamic metadata, send events on change - (NSDictionary *)metadata; // Only to be implemented for dynamic metadata, send events on change
- (int)readAudio:(void *)buffer frames:(UInt32)frames; - (AudioChunk *)readAudio;
- (BOOL)open:(id<CogSource>)source; - (BOOL)open:(id<CogSource>)source;
- (long)seek:(long)frame; - (long)seek:(long)frame;

View File

@ -927,6 +927,7 @@
83489C4E2782F2DF00BDCEA2 /* libvgmPlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libvgmPlayer.xcodeproj; path = Plugins/libvgmPlayer/libvgmPlayer.xcodeproj; sourceTree = "<group>"; }; 83489C4E2782F2DF00BDCEA2 /* libvgmPlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libvgmPlayer.xcodeproj; path = Plugins/libvgmPlayer/libvgmPlayer.xcodeproj; sourceTree = "<group>"; };
8349270127B4EFFC0009AB2B /* duplicateItemsTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = duplicateItemsTemplate.pdf; path = Images/duplicateItemsTemplate.pdf; sourceTree = "<group>"; }; 8349270127B4EFFC0009AB2B /* duplicateItemsTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = duplicateItemsTemplate.pdf; path = Images/duplicateItemsTemplate.pdf; sourceTree = "<group>"; };
8349270B27B4EFFC0009AB2B /* deadItemsTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = deadItemsTemplate.pdf; path = Images/deadItemsTemplate.pdf; sourceTree = "<group>"; }; 8349270B27B4EFFC0009AB2B /* deadItemsTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; name = deadItemsTemplate.pdf; path = Images/deadItemsTemplate.pdf; sourceTree = "<group>"; };
834A42C4287B01B600EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = Audio/Chain/AudioChunk.h; sourceTree = SOURCE_ROOT; };
834B05E82859C006000B7DC0 /* TotalTimeTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TotalTimeTransformer.h; path = Transformers/TotalTimeTransformer.h; sourceTree = "<group>"; }; 834B05E82859C006000B7DC0 /* TotalTimeTransformer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TotalTimeTransformer.h; path = Transformers/TotalTimeTransformer.h; sourceTree = "<group>"; };
834B05E92859C006000B7DC0 /* TotalTimeTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TotalTimeTransformer.m; path = Transformers/TotalTimeTransformer.m; sourceTree = "<group>"; }; 834B05E92859C006000B7DC0 /* TotalTimeTransformer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TotalTimeTransformer.m; path = Transformers/TotalTimeTransformer.m; sourceTree = "<group>"; };
8355D6B4180612F300D05687 /* NSData+MD5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+MD5.h"; sourceTree = "<group>"; }; 8355D6B4180612F300D05687 /* NSData+MD5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+MD5.h"; sourceTree = "<group>"; };
@ -1227,6 +1228,7 @@
177EC0110B8BC2CF0000BC8C /* Utils */ = { 177EC0110B8BC2CF0000BC8C /* Utils */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42C4287B01B600EB9D9B /* AudioChunk.h */,
8384912518080F2D00E7332D /* Logging.h */, 8384912518080F2D00E7332D /* Logging.h */,
07E18DF10D62B38400BB0E11 /* NSArray+ShuffleUtils.h */, 07E18DF10D62B38400BB0E11 /* NSArray+ShuffleUtils.h */,
07E18DF20D62B38400BB0E11 /* NSArray+ShuffleUtils.m */, 07E18DF20D62B38400BB0E11 /* NSArray+ShuffleUtils.m */,

View File

@ -17,6 +17,7 @@
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
32DBCF630370AF2F00C91783 /* APL_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APL_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* APL_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APL_Prefix.pch; sourceTree = "<group>"; };
834A42AF287AF34300EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
83747FE32862E8B60021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747FE32862E8B60021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
838491281808135500E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 838491281808135500E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -74,6 +75,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42AF287AF34300EB9D9B /* AudioChunk.h */,
838491281808135500E7332D /* Logging.h */, 838491281808135500E7332D /* Logging.h */,
8E8D423C0CBB0FF600135C1B /* Plugin.h */, 8E8D423C0CBB0FF600135C1B /* Plugin.h */,
8E8D42350CBB0F9800135C1B /* APLDecoder.h */, 8E8D42350CBB0F9800135C1B /* APLDecoder.h */,

View File

@ -108,18 +108,24 @@
return framePosition; return framePosition;
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
if(framePosition + frames > trackEnd) int maxFrames = INT_MAX;
frames = (UInt32)(trackEnd - framePosition);
if(!frames) { if(framePosition + maxFrames > trackEnd)
maxFrames = (int)(trackEnd - framePosition);
if(!maxFrames) {
DLog(@"APL readAudio Returning 0"); DLog(@"APL readAudio Returning 0");
return 0; return nil;
} }
int n = [decoder readAudio:buf frames:frames]; AudioChunk *chunk = [decoder readAudio];
framePosition += n; if(chunk.frameCount > maxFrames) {
return n; [chunk setFrameCount:maxFrames];
}
framePosition += chunk.frameCount;
return chunk;
} }
- (BOOL)isSilence { - (BOOL)isSilence {

View File

@ -52,6 +52,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
833A8999286FF2FD0022E036 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 833A8999286FF2FD0022E036 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
834A42AE287AF27A00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
83747C6D2862DDDB0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C6D2862DDDB0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
83D3C5F3201C674D005564CB /* AdPlug.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AdPlug.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 83D3C5F3201C674D005564CB /* AdPlug.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AdPlug.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
83D3C5F6201C674D005564CB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 83D3C5F6201C674D005564CB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -123,6 +124,7 @@
83D3C5F5201C674D005564CB /* AdPlug */ = { 83D3C5F5201C674D005564CB /* AdPlug */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42AE287AF27A00EB9D9B /* AudioChunk.h */,
83D3C667201C7020005564CB /* adplug.db */, 83D3C667201C7020005564CB /* adplug.db */,
83D3C657201C6E24005564CB /* AdPlugContainer.h */, 83D3C657201C6E24005564CB /* AdPlugContainer.h */,
83D3C654201C6E24005564CB /* AdPlugContainer.mm */, 83D3C654201C6E24005564CB /* AdPlugContainer.mm */,

View File

@ -103,7 +103,14 @@ static CAdPlugDatabase *g_database = NULL;
return @{}; return @{};
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
int frames = 1024;
int16_t buffer[1024 * 2];
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
void *buf = (void *)buffer;
int total = 0; int total = 0;
bool dont_loop = !IsRepeatOneSet(); bool dont_loop = !IsRepeatOneSet();
if(dont_loop && current_pos + frames > length) if(dont_loop && current_pos + frames > length)
@ -128,7 +135,9 @@ static CAdPlugDatabase *g_database = NULL;
total += samples_now; total += samples_now;
} }
return total; [chunk assignSamples:buffer frameCount:total];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {

View File

@ -33,6 +33,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
8307D31A286070EA000FF8EB /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../../Utils/SandboxBroker.h; sourceTree = "<group>"; }; 8307D31A286070EA000FF8EB /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../../Utils/SandboxBroker.h; sourceTree = "<group>"; };
834A42B0287AF4BF00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
8359009717FEF6490060F3ED /* ArchiveSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchiveSource.h; sourceTree = "<group>"; }; 8359009717FEF6490060F3ED /* ArchiveSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchiveSource.h; sourceTree = "<group>"; };
8359009817FEF6490060F3ED /* ArchiveSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArchiveSource.m; sourceTree = "<group>"; }; 8359009817FEF6490060F3ED /* ArchiveSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArchiveSource.m; sourceTree = "<group>"; };
8359009A17FEFDA80060F3ED /* ArchiveContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchiveContainer.h; sourceTree = "<group>"; }; 8359009A17FEFDA80060F3ED /* ArchiveContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArchiveContainer.h; sourceTree = "<group>"; };
@ -105,6 +106,7 @@
8359FF2017FEF35C0060F3ED /* ArchiveSource */ = { 8359FF2017FEF35C0060F3ED /* ArchiveSource */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42B0287AF4BF00EB9D9B /* AudioChunk.h */,
8307D31A286070EA000FF8EB /* SandboxBroker.h */, 8307D31A286070EA000FF8EB /* SandboxBroker.h */,
8384913518081BA000E7332D /* Logging.h */, 8384913518081BA000E7332D /* Logging.h */,
835900A017FF079C0060F3ED /* Plugin.h */, 835900A017FF079C0060F3ED /* Plugin.h */,

View File

@ -23,6 +23,7 @@
17C93EAB0B8FF3CE008627D6 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; }; 17C93EAB0B8FF3CE008627D6 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
17C93EB20B8FF3E1008627D6 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; }; 17C93EB20B8FF3E1008627D6 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
32DBCF630370AF2F00C91783 /* CoreAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreAudio_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* CoreAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreAudio_Prefix.pch; sourceTree = "<group>"; };
834A42B1287AF4D900EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
83747C5E2862DD880021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C5E2862DD880021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
83849129180813E800E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 83849129180813E800E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* CoreAudio.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreAudio.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B6048680CD000E48DA /* CoreAudio.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreAudio.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
@ -77,6 +78,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42B1287AF4D900EB9D9B /* AudioChunk.h */,
83849129180813E800E7332D /* Logging.h */, 83849129180813E800E7332D /* Logging.h */,
177FCFCA0B90C9A10011C3B5 /* Plugin.h */, 177FCFCA0B90C9A10011C3B5 /* Plugin.h */,
17C93E720B8FF192008627D6 /* CoreAudioDecoder.h */, 17C93E720B8FF192008627D6 /* CoreAudioDecoder.h */,

View File

@ -306,25 +306,33 @@ static SInt64 getSizeProc(void *clientData) {
return YES; return YES;
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
OSStatus err; OSStatus err;
AudioBufferList bufferList; AudioBufferList bufferList;
UInt32 frameCount; UInt32 frameCount;
int frames = 1024;
size_t bytesPerFrame = channels * (bitsPerSample / 8);
uint8_t buffer[frames * bytesPerFrame];
// Set up the AudioBufferList // Set up the AudioBufferList
bufferList.mNumberBuffers = 1; bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = channels; bufferList.mBuffers[0].mNumberChannels = channels;
bufferList.mBuffers[0].mData = buf; bufferList.mBuffers[0].mData = buffer;
bufferList.mBuffers[0].mDataByteSize = frames * channels * (bitsPerSample / 8); bufferList.mBuffers[0].mDataByteSize = frames * channels * (bitsPerSample / 8);
// Read a chunk of PCM input (converted from whatever format) // Read a chunk of PCM input (converted from whatever format)
frameCount = frames; frameCount = frames;
err = ExtAudioFileRead(_in, &frameCount, &bufferList); err = ExtAudioFileRead(_in, &frameCount, &bufferList);
if(err != noErr) { if(err != noErr) {
return 0; return nil;
} }
return frameCount; id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:frameCount];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {

View File

@ -24,6 +24,7 @@
17DA346D0CC04FCD0003F6B2 /* CueSheetMetadataReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CueSheetMetadataReader.m; sourceTree = "<group>"; }; 17DA346D0CC04FCD0003F6B2 /* CueSheetMetadataReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CueSheetMetadataReader.m; sourceTree = "<group>"; };
32DBCF630370AF2F00C91783 /* CueSheet_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CueSheet_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* CueSheet_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CueSheet_Prefix.pch; sourceTree = "<group>"; };
833F68371CDBCAB200AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F68371CDBCAB200AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
834A42B2287AF59900EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
835C888E22CC1883001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 835C888E22CC1883001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83747C592862DD660021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C592862DD660021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
8384912A180814D900E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 8384912A180814D900E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
@ -89,6 +90,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42B2287AF59900EB9D9B /* AudioChunk.h */,
839DA7D3274A2FD4001B18E5 /* NSDictionary+Merge.h */, 839DA7D3274A2FD4001B18E5 /* NSDictionary+Merge.h */,
839DA7D0274A2EA9001B18E5 /* AudioMetadataReader.h */, 839DA7D0274A2EA9001B18E5 /* AudioMetadataReader.h */,
8384912A180814D900E7332D /* Logging.h */, 8384912A180814D900E7332D /* Logging.h */,

View File

@ -309,25 +309,32 @@ static void *kCueSheetDecoderContext = &kCueSheetDecoderContext;
return framePosition - trackStart; return framePosition - trackStart;
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
if(!seekedToStart) { if(!seekedToStart) {
[self seek:0]; [self seek:0];
} }
int frames = INT_MAX;
if(!noFragment && framePosition + frames > trackEnd) { if(!noFragment && framePosition + frames > trackEnd) {
frames = (UInt32)(trackEnd - framePosition); frames = (UInt32)(trackEnd - framePosition);
} }
if(!frames) { if(!frames) {
DLog(@"Returning 0"); DLog(@"Returning 0");
return 0; return nil;
} }
int n = [decoder readAudio:buf frames:frames]; AudioChunk *chunk = [decoder readAudio];
framePosition += n; size_t n = chunk.frameCount;
if(n > frames) {
[chunk setFrameCount:frames];
}
return n; framePosition += chunk.frameCount;
return chunk;
} }
- (BOOL)isSilence { - (BOOL)isSilence {

View File

@ -45,6 +45,7 @@
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; }; 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; }; 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
834A42B3287AF65000EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
8352D48E1CDDB023009D16AA /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; 8352D48E1CDDB023009D16AA /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
8352D4901CDDB02A009D16AA /* VideoDecodeAcceleration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoDecodeAcceleration.framework; path = System/Library/Frameworks/VideoDecodeAcceleration.framework; sourceTree = SDKROOT; }; 8352D4901CDDB02A009D16AA /* VideoDecodeAcceleration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VideoDecodeAcceleration.framework; path = System/Library/Frameworks/VideoDecodeAcceleration.framework; sourceTree = SDKROOT; };
8352D4921CDDB034009D16AA /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 8352D4921CDDB034009D16AA /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
@ -145,6 +146,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42B3287AF65000EB9D9B /* AudioChunk.h */,
8356BD1A27B3D06F0074E50C /* HTTPSource.h */, 8356BD1A27B3D06F0074E50C /* HTTPSource.h */,
8356BCEA27B37DA40074E50C /* TagLibID3v2Reader.h */, 8356BCEA27B37DA40074E50C /* TagLibID3v2Reader.h */,
8356BCE827B37C6F0074E50C /* NSDictionary+Merge.h */, 8356BCE827B37C6F0074E50C /* NSDictionary+Merge.h */,

View File

@ -45,8 +45,7 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence);
BOOL metadataUpdated; BOOL metadataUpdated;
int prebufferedAudio; AudioChunk *prebufferedChunk;
uint8_t *prebufferedAudioData;
BOOL rawDSD; BOOL rawDSD;
BOOL rawDSDReverseBits; BOOL rawDSDReverseBits;

View File

@ -471,13 +471,10 @@ static uint8_t reverse_bits[0x100];
metadataUpdated = NO; metadataUpdated = NO;
[self updateMetadata]; [self updateMetadata];
prebufferedAudio = 0; prebufferedChunk = nil;
prebufferedAudioData = NULL;
if(attachedPicIndex >= 0) { if(attachedPicIndex >= 0) {
int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8); prebufferedChunk = [self readAudio];
prebufferedAudioData = malloc(1024 * frameSize);
[self readAudio:prebufferedAudioData frames:1024];
} }
return YES; return YES;
@ -681,30 +678,31 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
} }
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
if(!seekedToStart) { if(!seekedToStart) {
[self seek:0]; [self seek:0];
} }
if(prebufferedChunk) {
// A bit of ignored read-ahead to support embedded artwork
size_t framesReadNow = prebufferedChunk.frameCount;
framesRead -= framesReadNow;
AudioChunk *chunk = prebufferedChunk;
prebufferedChunk = nil;
return chunk;
}
if(totalFrames && framesRead >= totalFrames)
return nil;
int frames = 1024;
int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8); int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8);
int bytesToRead = frames * frameSize; int bytesToRead = frames * frameSize;
int bytesRead = 0; int bytesRead = 0;
if(prebufferedAudio) { uint8_t buffer[bytesToRead];
// A bit of ignored read-ahead to support embedded artwork void *buf = (void *)buffer;
int bytesBuffered = prebufferedAudio * frameSize;
int bytesToCopy = (bytesBuffered > bytesToRead) ? bytesToRead : bytesBuffered;
memcpy(buf, prebufferedAudioData, bytesToCopy);
memmove(prebufferedAudioData, prebufferedAudioData + bytesToCopy, bytesBuffered - bytesToCopy);
prebufferedAudio -= bytesToCopy / frameSize;
bytesRead = bytesToCopy;
int framesReadNow = bytesRead / frameSize;
framesRead -= framesReadNow;
}
if(totalFrames && framesRead >= totalFrames)
return 0;
int dataSize = 0; int dataSize = 0;
@ -909,7 +907,11 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
framesRead += framesReadNow; framesRead += framesReadNow;
return framesReadNow; id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:framesReadNow];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {
@ -918,7 +920,7 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
seekedToStart = YES; seekedToStart = YES;
prebufferedAudio = 0; prebufferedChunk = nil;
if(frame >= totalFrames) { if(frame >= totalFrames) {
framesRead = totalFrames; framesRead = totalFrames;

View File

@ -39,6 +39,7 @@
32DBCF630370AF2F00C91783 /* FileSource_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSource_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* FileSource_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSource_Prefix.pch; sourceTree = "<group>"; };
8307D31B2860722C000FF8EB /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../Utils/SandboxBroker.h; sourceTree = "<group>"; }; 8307D31B2860722C000FF8EB /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../Utils/SandboxBroker.h; sourceTree = "<group>"; };
8335FF6817FF765A002D8DD2 /* File_Extractor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = File_Extractor.xcodeproj; path = ../../Frameworks/File_Extractor/File_Extractor.xcodeproj; sourceTree = "<group>"; }; 8335FF6817FF765A002D8DD2 /* File_Extractor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = File_Extractor.xcodeproj; path = ../../Frameworks/File_Extractor/File_Extractor.xcodeproj; sourceTree = "<group>"; };
834A42AD287AF25600EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
83747C4F2862DD2F0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C4F2862DD2F0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* FileSource.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FileSource.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B6048680CD000E48DA /* FileSource.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FileSource.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -91,6 +92,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42AD287AF25600EB9D9B /* AudioChunk.h */,
8307D31B2860722C000FF8EB /* SandboxBroker.h */, 8307D31B2860722C000FF8EB /* SandboxBroker.h */,
17ADB4080B979A8A00257CA2 /* Plugin.h */, 17ADB4080B979A8A00257CA2 /* Plugin.h */,
17ADB4180B979AEB00257CA2 /* FileSource.h */, 17ADB4180B979AEB00257CA2 /* FileSource.h */,

View File

@ -36,6 +36,7 @@
32DBCF630370AF2F00C91783 /* Flac_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Flac_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* Flac_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Flac_Prefix.pch; sourceTree = "<group>"; };
8301C145287805F500651A6E /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; }; 8301C145287805F500651A6E /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; };
8301C146287805F500651A6E /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+Merge.m"; path = "../../Utils/NSDictionary+Merge.m"; sourceTree = "<group>"; }; 8301C146287805F500651A6E /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+Merge.m"; path = "../../Utils/NSDictionary+Merge.m"; sourceTree = "<group>"; };
834A42B4287AF7AA00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
8356BD1927B3CCBB0074E50C /* HTTPSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPSource.h; path = ../HTTPSource/HTTPSource.h; sourceTree = "<group>"; }; 8356BD1927B3CCBB0074E50C /* HTTPSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPSource.h; path = ../HTTPSource/HTTPSource.h; sourceTree = "<group>"; };
836EF0D927BB970B00BF35B2 /* libFLAC.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libFLAC.8.dylib; path = ../../ThirdParty/flac/lib/libFLAC.8.dylib; sourceTree = "<group>"; }; 836EF0D927BB970B00BF35B2 /* libFLAC.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libFLAC.8.dylib; path = ../../ThirdParty/flac/lib/libFLAC.8.dylib; sourceTree = "<group>"; };
83747C4A2862DCF40021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C4A2862DCF40021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
@ -92,6 +93,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42B4287AF7AA00EB9D9B /* AudioChunk.h */,
8301C145287805F500651A6E /* NSDictionary+Merge.h */, 8301C145287805F500651A6E /* NSDictionary+Merge.h */,
8301C146287805F500651A6E /* NSDictionary+Merge.m */, 8301C146287805F500651A6E /* NSDictionary+Merge.m */,
83AA660A27B7DAE40098D4B8 /* cuesheet.m */, 83AA660A27B7DAE40098D4B8 /* cuesheet.m */,

View File

@ -361,39 +361,23 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
return YES; return YES;
} }
- (int)readAudio:(void *)buffer frames:(UInt32)frames { - (AudioChunk *)readAudio {
int framesRead = 0; id audioChunkClass = NSClassFromString(@"AudioChunk");
while(framesRead < frames) { AudioChunk *chunk = nil;
if(blockBufferFrames == 0) {
if(framesRead) {
break;
}
if(FLAC__stream_decoder_get_state(decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) { if(FLAC__stream_decoder_get_state(decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) {
break; return nil;
} }
if(!FLAC__stream_decoder_process_single(decoder)) { if(!FLAC__stream_decoder_process_single(decoder)) {
break; return nil;
} }
}
int bytesPerFrame = ((bitsPerSample + 7) / 8) * channels; if(blockBufferFrames > 0) {
chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:blockBuffer frameCount:blockBufferFrames];
int framesToRead = blockBufferFrames; blockBufferFrames = 0;
if(blockBufferFrames > frames) {
framesToRead = frames;
}
memcpy(((uint8_t *)buffer) + (framesRead * bytesPerFrame), (uint8_t *)blockBuffer, framesToRead * bytesPerFrame);
frames -= framesToRead;
framesRead += framesToRead;
blockBufferFrames -= framesToRead;
if(blockBufferFrames > 0) {
memmove((uint8_t *)blockBuffer, ((uint8_t *)blockBuffer) + (framesToRead * bytesPerFrame), blockBufferFrames * bytesPerFrame);
}
} }
if(![source seekable]) { if(![source seekable]) {
@ -429,7 +413,7 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
} }
} }
return framesRead; return chunk;
} }
- (void)close { - (void)close {

View File

@ -63,6 +63,7 @@
8319C74E237629D300BFFAE0 /* GamePropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GamePropertiesReader.h; sourceTree = "<group>"; }; 8319C74E237629D300BFFAE0 /* GamePropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GamePropertiesReader.h; sourceTree = "<group>"; };
8319C74F237629D400BFFAE0 /* GamePropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GamePropertiesReader.m; sourceTree = "<group>"; }; 8319C74F237629D400BFFAE0 /* GamePropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GamePropertiesReader.m; sourceTree = "<group>"; };
833F68351CDBCAB200AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F68351CDBCAB200AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
834A42B5287AF8FE00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
835C888F22CC1883001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 835C888F22CC1883001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83747C452862DCD90021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C452862DCD90021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
8384912E1808175400E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 8384912E1808175400E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
@ -119,6 +120,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42B5287AF8FE00EB9D9B /* AudioChunk.h */,
17C8F33B0CBED3BE008D969D /* GameContainer.h */, 17C8F33B0CBED3BE008D969D /* GameContainer.h */,
17C8F33C0CBED3BE008D969D /* GameContainer.m */, 17C8F33C0CBED3BE008D969D /* GameContainer.m */,
17C8F33D0CBED3BE008D969D /* GameDecoder.h */, 17C8F33D0CBED3BE008D969D /* GameDecoder.h */,

View File

@ -174,11 +174,18 @@ gme_err_t readCallback(void *data, void *out, int count) {
return @{}; return @{};
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
int frames = 1024;
int16_t buffer[frames * 2];
void *buf = (void *)buffer;
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
int numSamples = frames * 2; // channels = 2 int numSamples = frames * 2; // channels = 2
if(gme_track_ended(emu)) { if(gme_track_ended(emu)) {
return 0; return nil;
} }
if(IsRepeatOneSet()) if(IsRepeatOneSet())
@ -190,7 +197,11 @@ gme_err_t readCallback(void *data, void *out, int count) {
// Some formats support length, but we'll add that in the future. // Some formats support length, but we'll add that in the future.
//(From gme.txt) If track length, then use it. If loop length, play for intro + loop * 2. Otherwise, default to 2.5 minutes //(From gme.txt) If track length, then use it. If loop length, play for intro + loop * 2. Otherwise, default to 2.5 minutes
return frames; // GME will always generate samples. There's no real EOS. // GME will always generate samples. There's no real EOS.
[chunk assignSamples:buffer frameCount:numSamples];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {

View File

@ -32,6 +32,7 @@
17ADB60C0B97A74800257CA2 /* HTTPSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTTPSource.h; sourceTree = "<group>"; }; 17ADB60C0B97A74800257CA2 /* HTTPSource.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = HTTPSource.h; sourceTree = "<group>"; };
17ADB6340B97A8B400257CA2 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; 17ADB6340B97A8B400257CA2 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; };
32DBCF630370AF2F00C91783 /* HTTPSource_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPSource_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* HTTPSource_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HTTPSource_Prefix.pch; sourceTree = "<group>"; };
834A42B9287AFAB500EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
8356BD1727B3B7340074E50C /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; }; 8356BD1727B3B7340074E50C /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; };
83747C362862DC0D0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C362862DC0D0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
8384912F1808180000E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 8384912F1808180000E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
@ -87,6 +88,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42B9287AFAB500EB9D9B /* AudioChunk.h */,
8384912F1808180000E7332D /* Logging.h */, 8384912F1808180000E7332D /* Logging.h */,
17ADB6340B97A8B400257CA2 /* Plugin.h */, 17ADB6340B97A8B400257CA2 /* Plugin.h */,
17ADB60C0B97A74800257CA2 /* HTTPSource.h */, 17ADB60C0B97A74800257CA2 /* HTTPSource.h */,

View File

@ -190,6 +190,7 @@
8343790C17F96E2600584396 /* HighlyQuixotic.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HighlyQuixotic.xcodeproj; path = ../../Frameworks/HighlyQuixotic/HighlyQuixotic.xcodeproj; sourceTree = "<group>"; }; 8343790C17F96E2600584396 /* HighlyQuixotic.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HighlyQuixotic.xcodeproj; path = ../../Frameworks/HighlyQuixotic/HighlyQuixotic.xcodeproj; sourceTree = "<group>"; };
8343796317F97BDB00584396 /* HighlyAdvanced.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HighlyAdvanced.xcodeproj; path = ../../Frameworks/HighlyAdvanced/HighlyAdvanced.xcodeproj; sourceTree = "<group>"; }; 8343796317F97BDB00584396 /* HighlyAdvanced.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HighlyAdvanced.xcodeproj; path = ../../Frameworks/HighlyAdvanced/HighlyAdvanced.xcodeproj; sourceTree = "<group>"; };
834379A717F9818400584396 /* HCDecoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HCDecoder.mm; sourceTree = "<group>"; }; 834379A717F9818400584396 /* HCDecoder.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = HCDecoder.mm; sourceTree = "<group>"; };
834A42B6287AF99600EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
8360EEE417F92AC8005208A4 /* HighlyComplete.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HighlyComplete.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8360EEE417F92AC8005208A4 /* HighlyComplete.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HighlyComplete.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
8360EEE717F92AC8005208A4 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 8360EEE717F92AC8005208A4 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
8360EEEA17F92AC8005208A4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 8360EEEA17F92AC8005208A4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@ -311,6 +312,7 @@
8360EEED17F92AC8005208A4 /* HighlyComplete */ = { 8360EEED17F92AC8005208A4 /* HighlyComplete */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42B6287AF99600EB9D9B /* AudioChunk.h */,
83AA660827B7CCB00098D4B8 /* Logging.h */, 83AA660827B7CCB00098D4B8 /* Logging.h */,
83FAF8A318ADD27F00057CAF /* PlaylistController.h */, 83FAF8A318ADD27F00057CAF /* PlaylistController.h */,
8324C584181513A10046F78F /* circular_buffer.h */, 8324C584181513A10046F78F /* circular_buffer.h */,

View File

@ -72,7 +72,7 @@
- (psf_file_container *)init { - (psf_file_container *)init {
if((self = [super init])) { if((self = [super init])) {
lock = [[NSLock alloc] init]; lock = [[NSLock alloc] init];
list = [[NSMutableDictionary alloc] initWithCapacity:0]; list = [[NSMutableDictionary alloc] init];
} }
return self; return self;
} }
@ -1302,7 +1302,7 @@ static int usf_info(void *context, const char *name, const char *value) {
return frames; return frames;
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
if(!emulatorCore) { if(!emulatorCore) {
if(![self initializeDecoder]) if(![self initializeDecoder])
return 0; return 0;
@ -1314,6 +1314,10 @@ static int usf_info(void *context, const char *name, const char *value) {
usfRemoveSilence = NO; usfRemoveSilence = NO;
} }
int frames = 1024;
int16_t buffer[frames * 2];
void *buf = (void *)buffer;
unsigned long written = silence_test_buffer.data_available() / 2; unsigned long written = silence_test_buffer.data_available() / 2;
if(written > frames) if(written > frames)
written = frames; written = frames;
@ -1342,7 +1346,11 @@ static int usf_info(void *context, const char *name, const char *value) {
framesRead += written; framesRead += written;
return (int)written; id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:written];
return chunk;
} }
- (void)closeDecoder { - (void)closeDecoder {

View File

@ -49,6 +49,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
831C7F6918ADD73F00CE4A69 /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../../Playlist/PlaylistController.h; sourceTree = "<group>"; }; 831C7F6918ADD73F00CE4A69 /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../../Playlist/PlaylistController.h; sourceTree = "<group>"; };
833F68471CDBCABF00AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F68471CDBCABF00AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
834A42B8287AFA3600EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
836FB52D1820538700B3AD2D /* Hively.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Hively.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 836FB52D1820538700B3AD2D /* Hively.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Hively.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
836FB5301820538700B3AD2D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 836FB5301820538700B3AD2D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
836FB5331820538700B3AD2D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 836FB5331820538700B3AD2D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
@ -122,6 +123,7 @@
836FB5361820538700B3AD2D /* Hively */ = { 836FB5361820538700B3AD2D /* Hively */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42B8287AFA3600EB9D9B /* AudioChunk.h */,
831C7F6918ADD73F00CE4A69 /* PlaylistController.h */, 831C7F6918ADD73F00CE4A69 /* PlaylistController.h */,
836FB5A31820557E00B3AD2D /* Plugin.h */, 836FB5A31820557E00B3AD2D /* Plugin.h */,
836FB59A1820556F00B3AD2D /* HVLDecoder.h */, 836FB59A1820556F00B3AD2D /* HVLDecoder.h */,

View File

@ -107,7 +107,11 @@ static void oneTimeInit(void) {
return @{}; return @{};
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
int frames = 1024;
float buffer[frames * 2];
void *buf = (void *)buffer;
BOOL repeatone = IsRepeatOneSet(); BOOL repeatone = IsRepeatOneSet();
if(!repeatone && framesRead >= totalFrames) if(!repeatone && framesRead >= totalFrames)
@ -157,7 +161,11 @@ static void oneTimeInit(void) {
framesRead += total; framesRead += total;
return total; id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:total];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {

View File

@ -18,6 +18,7 @@
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
32DBCF630370AF2F00C91783 /* M3u_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M3u_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* M3u_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M3u_Prefix.pch; sourceTree = "<group>"; };
833F68391CDBCAB200AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F68391CDBCAB200AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
834A42BA287AFAEF00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
835C889122CC1885001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 835C889122CC1885001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83747C2C2862DBBE0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C2C2862DBBE0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
83849130180818B100E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 83849130180818B100E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
@ -75,6 +76,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42BA287AFAEF00EB9D9B /* AudioChunk.h */,
83849130180818B100E7332D /* Logging.h */, 83849130180818B100E7332D /* Logging.h */,
8E8D401B0CBAFEF200135C1B /* Plugin.h */, 8E8D401B0CBAFEF200135C1B /* Plugin.h */,
8E8D40270CBAFF4300135C1B /* M3uContainer.h */, 8E8D40270CBAFF4300135C1B /* M3uContainer.h */,

View File

@ -15,6 +15,7 @@
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
834A42BB287AFB0700EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
8372C92327C785BD00E250C9 /* MAD.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MAD.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8372C92327C785BD00E250C9 /* MAD.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MAD.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
8372C93327C7861300E250C9 /* MADDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MADDecoder.h; sourceTree = "<group>"; }; 8372C93327C7861300E250C9 /* MADDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MADDecoder.h; sourceTree = "<group>"; };
8372C93427C7861300E250C9 /* MADDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MADDecoder.m; sourceTree = "<group>"; }; 8372C93427C7861300E250C9 /* MADDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MADDecoder.m; sourceTree = "<group>"; };
@ -48,6 +49,7 @@
children = ( children = (
83747C262862DB9F0021245F /* Xcode-config */, 83747C262862DB9F0021245F /* Xcode-config */,
83F97B6628600F9300A70B97 /* ThirdParty */, 83F97B6628600F9300A70B97 /* ThirdParty */,
834A42BB287AFB0700EB9D9B /* AudioChunk.h */,
8372C93A27C786DD00E250C9 /* HTTPSource.h */, 8372C93A27C786DD00E250C9 /* HTTPSource.h */,
8372C93927C7866B00E250C9 /* Logging.h */, 8372C93927C7866B00E250C9 /* Logging.h */,
8372C93827C7865A00E250C9 /* Plugin.h */, 8372C93827C7865A00E250C9 /* Plugin.h */,

View File

@ -651,7 +651,7 @@
return 1; return 1;
} }
- (BOOL)syncFormat:(BOOL)updateNow { - (BOOL)syncFormat {
float _sampleRate = _frame.header.samplerate; float _sampleRate = _frame.header.samplerate;
int _channels = MAD_NCHANNELS(&_frame.header); int _channels = MAD_NCHANNELS(&_frame.header);
int _layer = 3; int _layer = 3;
@ -674,7 +674,7 @@
_channels != channels || _channels != channels ||
_layer != layer); _layer != layer);
if(changed && updateNow) { if(changed) {
sampleRate = _sampleRate; sampleRate = _sampleRate;
channels = _channels; channels = _channels;
layer = _layer; layer = _layer;
@ -686,29 +686,24 @@
return changed; return changed;
} }
- (int)readAudio:(void *)buffer frames:(UInt32)frames { - (AudioChunk *)readAudio {
int framesRead = 0; int framesRead = 0;
if(!_firstFrame) if(!_firstFrame)
[self syncFormat:YES]; [self syncFormat];
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = nil;
for(;;) { for(;;) {
long framesRemaining = frames - framesRead; long framesToCopy = _outputFrames;
long framesToCopy = (_outputFrames > framesRemaining ? framesRemaining : _outputFrames);
if(framesToCopy) { if(framesToCopy) {
memcpy(buffer + (framesRead * channels * sizeof(float)), _outputBuffer, framesToCopy * channels * sizeof(float)); chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
framesRead += framesToCopy; [chunk assignSamples:_outputBuffer frameCount:framesToCopy];
_outputFrames = 0;
if(framesToCopy != _outputFrames) {
memmove(_outputBuffer, _outputBuffer + (framesToCopy * channels), (_outputFrames - framesToCopy) * channels * sizeof(float));
}
_outputFrames -= framesToCopy;
}
if(framesRead == frames)
break; break;
}
int r = [self decodeMPEGFrame]; int r = [self decodeMPEGFrame];
// DLog(@"Decoding frame: %i", r); // DLog(@"Decoding frame: %i", r);
@ -720,18 +715,13 @@
[self writeOutput]; [self writeOutput];
// DLog(@"Wrote output"); // DLog(@"Wrote output");
if([self syncFormat:NO]) { [self syncFormat];
if(framesRead)
break;
else
[self syncFormat:YES];
}
} }
[self updateMetadata]; [self updateMetadata];
// DLog(@"Read: %i/%i", bytesRead, size); // DLog(@"Read: %i/%i", bytesRead, size);
return framesRead; return chunk;
} }
- (void)close { - (void)close {

View File

@ -99,6 +99,7 @@
831E2A9427B4B2FA006F1C86 /* json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = json.h; sourceTree = "<group>"; }; 831E2A9427B4B2FA006F1C86 /* json.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = json.h; sourceTree = "<group>"; };
831E2A9527B4B2FA006F1C86 /* json-builder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "json-builder.h"; sourceTree = "<group>"; }; 831E2A9527B4B2FA006F1C86 /* json-builder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "json-builder.h"; sourceTree = "<group>"; };
833F68431CDBCABE00AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F68431CDBCABE00AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
834A42BC287AFC7F00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
834BE9191DE407CB00A07DCD /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = "<group>"; }; 834BE9191DE407CB00A07DCD /* resampler.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = resampler.c; sourceTree = "<group>"; };
834BE91A1DE407CB00A07DCD /* resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resampler.h; sourceTree = "<group>"; }; 834BE91A1DE407CB00A07DCD /* resampler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resampler.h; sourceTree = "<group>"; };
8356BCC427B352620074E50C /* BMPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BMPlayer.cpp; sourceTree = "<group>"; }; 8356BCC427B352620074E50C /* BMPlayer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BMPlayer.cpp; sourceTree = "<group>"; };
@ -306,6 +307,7 @@
83B06690180D5668008E3612 /* MIDI */ = { 83B06690180D5668008E3612 /* MIDI */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42BC287AFC7F00EB9D9B /* AudioChunk.h */,
8307D31E28607377000FF8EB /* SandboxBroker.h */, 8307D31E28607377000FF8EB /* SandboxBroker.h */,
831E2A9127B4B2FA006F1C86 /* json */, 831E2A9127B4B2FA006F1C86 /* json */,
831E2A7D27B4B2B2006F1C86 /* BASS */, 831E2A7D27B4B2B2006F1C86 /* BASS */,

View File

@ -276,14 +276,14 @@ static OSType getOSType(const char *in_) {
return YES; return YES;
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
BOOL repeatone = IsRepeatOneSet(); BOOL repeatone = IsRepeatOneSet();
long localFramesLength = framesLength; long localFramesLength = framesLength;
long localTotalFrames = totalFrames; long localTotalFrames = totalFrames;
if(!player) { if(!player) {
if(![self initDecoder]) if(![self initDecoder])
return -1; return nil;
} }
player->setLoopMode((repeatone || isLooped) ? (MIDIPlayer::loop_mode_enable | MIDIPlayer::loop_mode_force) : 0); player->setLoopMode((repeatone || isLooped) ? (MIDIPlayer::loop_mode_enable | MIDIPlayer::loop_mode_force) : 0);
@ -302,7 +302,10 @@ static OSType getOSType(const char *in_) {
soundFontsAssigned = YES; soundFontsAssigned = YES;
} }
UInt32 frames_done = player->Play((float *)buf, frames); int frames = 1024;
float buffer[frames * 2];
UInt32 frames_done = player->Play(buffer, frames);
if(!frames_done) if(!frames_done)
return 0; return 0;
@ -315,7 +318,7 @@ static OSType getOSType(const char *in_) {
long fadeEnd = (framesRead + frames > localTotalFrames) ? localTotalFrames : (framesRead + frames); long fadeEnd = (framesRead + frames > localTotalFrames) ? localTotalFrames : (framesRead + frames);
long fadePos; long fadePos;
float *buff = (float *)buf; float *buff = buffer;
float fadeScale = (float)(framesFade - (fadeStart - localFramesLength)) / framesFade; float fadeScale = (float)(framesFade - (fadeStart - localFramesLength)) / framesFade;
float fadeStep = 1.0 / (float)framesFade; float fadeStep = 1.0 / (float)framesFade;
@ -337,13 +340,17 @@ static OSType getOSType(const char *in_) {
} }
framesRead += frames; framesRead += frames;
return frames;
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:frames];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {
if(!player) { if(!player) {
float temp[2]; if(![self readAudio])
if([self readAudio:temp frames:1] < 1)
return -1; return -1;
} }

View File

@ -51,6 +51,7 @@
1703330A0B8FB64500327265 /* MusepackDecoder.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MusepackDecoder.m; sourceTree = "<group>"; }; 1703330A0B8FB64500327265 /* MusepackDecoder.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = MusepackDecoder.m; sourceTree = "<group>"; };
17F562570C3BD97B0019975C /* MPCDec.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MPCDec.xcodeproj; path = ../../Frameworks/MPCDec/MPCDec.xcodeproj; sourceTree = SOURCE_ROOT; }; 17F562570C3BD97B0019975C /* MPCDec.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = MPCDec.xcodeproj; path = ../../Frameworks/MPCDec/MPCDec.xcodeproj; sourceTree = SOURCE_ROOT; };
32DBCF630370AF2F00C91783 /* Musepack_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Musepack_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* Musepack_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Musepack_Prefix.pch; sourceTree = "<group>"; };
834A42BD287AFD0D00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
83747C1D2862DB560021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C1D2862DB560021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
838491311808190400E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 838491311808190400E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* Musepack.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Musepack.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B6048680CD000E48DA /* Musepack.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Musepack.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
@ -105,6 +106,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42BD287AFD0D00EB9D9B /* AudioChunk.h */,
838491311808190400E7332D /* Logging.h */, 838491311808190400E7332D /* Logging.h */,
8E2B8B4A0B9B48D000F2D9E8 /* Plugin.h */, 8E2B8B4A0B9B48D000F2D9E8 /* Plugin.h */,
170333090B8FB64500327265 /* MusepackDecoder.h */, 170333090B8FB64500327265 /* MusepackDecoder.h */,

View File

@ -109,11 +109,15 @@ mpc_bool_t CanSeekProc(mpc_reader *p_reader) {
return YES; return YES;
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH]; MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH];
int frames = 1024;
float buffer[frames * 2];
void *buf = (void *)buffer;
int framesRead = 0; int framesRead = 0;
int bytesPerFrame = sizeof(float) * 2; // bitsPerSample == 16, channels == 2 int bytesPerFrame = sizeof(float) * 2; // bitsPerSample == 32, channels == 2
while(framesRead < frames) { while(framesRead < frames) {
// Fill from buffer, going by bufferFrames // Fill from buffer, going by bufferFrames
// if still needs more, decode and repeat // if still needs more, decode and repeat
@ -150,7 +154,11 @@ mpc_bool_t CanSeekProc(mpc_reader *p_reader) {
} }
} }
return framesRead; id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:framesRead];
return chunk;
} }
- (void)close { - (void)close {

View File

@ -48,6 +48,7 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
833A899B286FF3150022E036 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 833A899B286FF3150022E036 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
834A42BE287AFDC300EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
83747C182862DB2F0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C182862DB2F0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
83E5EFA31FFEF78100659F0F /* OpenMPT.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OpenMPT.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 83E5EFA31FFEF78100659F0F /* OpenMPT.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OpenMPT.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
83E5EFA61FFEF78100659F0F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 83E5EFA61FFEF78100659F0F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -124,6 +125,7 @@
83E5FE6A1FFF003900659F0F /* Classes */ = { 83E5FE6A1FFF003900659F0F /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42BE287AFDC300EB9D9B /* AudioChunk.h */,
83E5FE6B1FFF004D00659F0F /* Logging.h */, 83E5FE6B1FFF004D00659F0F /* Logging.h */,
83E5FE761FFF076F00659F0F /* PlaylistController.h */, 83E5FE761FFF076F00659F0F /* PlaylistController.h */,
83E5FE6C1FFF006400659F0F /* Plugin.h */, 83E5FE6C1FFF006400659F0F /* Plugin.h */,

View File

@ -112,9 +112,13 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
return @{}; return @{};
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
mod->set_repeat_count(IsRepeatOneSet() ? -1 : 0); mod->set_repeat_count(IsRepeatOneSet() ? -1 : 0);
int frames = 1024;
float buffer[frames * 2];
void *buf = (void *)buffer;
int total = 0; int total = 0;
while(total < frames) { while(total < frames) {
int framesToRender = 1024; int framesToRender = 1024;
@ -131,7 +135,11 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
break; break;
} }
return total; id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:total];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {

View File

@ -222,7 +222,7 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
} }
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
int numread; int numread;
int total = 0; int total = 0;
@ -236,7 +236,10 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
[self updateMetadata]; [self updateMetadata];
} }
int frames = 1024;
int size = frames * channels; int size = frames * channels;
float buffer[size];
void *buf = (void *)buffer;
do { do {
float *out = ((float *)buf) + total; float *out = ((float *)buf) + total;
@ -265,7 +268,11 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
[self updateIcyMetadata]; [self updateIcyMetadata];
return total / channels; id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:total / channels];
return chunk;
} }
- (void)close { - (void)close {

View File

@ -32,6 +32,7 @@
83186314285CEC91001422CC /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; }; 83186314285CEC91001422CC /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; };
83186315285CEC91001422CC /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+Merge.m"; path = "../../../Utils/NSDictionary+Merge.m"; sourceTree = "<group>"; }; 83186315285CEC91001422CC /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+Merge.m"; path = "../../../Utils/NSDictionary+Merge.m"; sourceTree = "<group>"; };
833F68411CDBCABC00AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F68411CDBCABC00AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
834A42BF287AFE2600EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
8356BD1B27B469B80074E50C /* HTTPSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPSource.h; path = ../../HTTPSource/HTTPSource.h; sourceTree = "<group>"; }; 8356BD1B27B469B80074E50C /* HTTPSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPSource.h; path = ../../HTTPSource/HTTPSource.h; sourceTree = "<group>"; };
836EF0CE27BB952F00BF35B2 /* libopusfile.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libopusfile.0.dylib; path = ../../ThirdParty/opusfile/lib/libopusfile.0.dylib; sourceTree = "<group>"; }; 836EF0CE27BB952F00BF35B2 /* libopusfile.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libopusfile.0.dylib; path = ../../ThirdParty/opusfile/lib/libopusfile.0.dylib; sourceTree = "<group>"; };
83747C0E2862DAC70021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C0E2862DAC70021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
@ -114,6 +115,7 @@
8375B04517FFEA400092A79F /* Opus */ = { 8375B04517FFEA400092A79F /* Opus */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42BF287AFE2600EB9D9B /* AudioChunk.h */,
83186314285CEC91001422CC /* NSDictionary+Merge.h */, 83186314285CEC91001422CC /* NSDictionary+Merge.h */,
83186315285CEC91001422CC /* NSDictionary+Merge.m */, 83186315285CEC91001422CC /* NSDictionary+Merge.m */,
8356BD1B27B469B80074E50C /* HTTPSource.h */, 8356BD1B27B469B80074E50C /* HTTPSource.h */,

View File

@ -18,6 +18,7 @@
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
32DBCF630370AF2F00C91783 /* Pls_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pls_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* Pls_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pls_Prefix.pch; sourceTree = "<group>"; };
833F68381CDBCAB200AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F68381CDBCAB200AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
834A42C0287AFEB100EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
835C889422CC1887001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 835C889422CC1887001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83747C092862DAA90021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C092862DAA90021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
838491321808193F00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 838491321808193F00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
@ -75,6 +76,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42C0287AFEB100EB9D9B /* AudioChunk.h */,
838491321808193F00E7332D /* Logging.h */, 838491321808193F00E7332D /* Logging.h */,
8E8D41A50CBB0CBE00135C1B /* Plugin.h */, 8E8D41A50CBB0CBE00135C1B /* Plugin.h */,
8E8D419F0CBB0CA700135C1B /* PlsContainer.h */, 8E8D419F0CBB0CA700135C1B /* PlsContainer.h */,

View File

@ -52,6 +52,7 @@
177FCFAC0B90C96B0011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; 177FCFAC0B90C96B0011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; };
17F563DD0C3BDBF10019975C /* Shorten.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Shorten.xcodeproj; path = ../../Frameworks/Shorten/Shorten.xcodeproj; sourceTree = SOURCE_ROOT; }; 17F563DD0C3BDBF10019975C /* Shorten.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Shorten.xcodeproj; path = ../../Frameworks/Shorten/Shorten.xcodeproj; sourceTree = SOURCE_ROOT; };
32DBCF630370AF2F00C91783 /* Shorten_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shorten_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* Shorten_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Shorten_Prefix.pch; sourceTree = "<group>"; };
834A42A9287AEF1300EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
83747C042862DA780021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C042862DA780021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* Shorten.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Shorten.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B6048680CD000E48DA /* Shorten.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Shorten.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -104,6 +105,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42A9287AEF1300EB9D9B /* AudioChunk.h */,
177FCFAC0B90C96B0011C3B5 /* Plugin.h */, 177FCFAC0B90C96B0011C3B5 /* Plugin.h */,
1745C42B0B90C1DC00A6768C /* ShortenDecoder.h */, 1745C42B0B90C1DC00A6768C /* ShortenDecoder.h */,
1745C42C0B90C1DC00A6768C /* ShortenDecoder.mm */, 1745C42C0B90C1DC00A6768C /* ShortenDecoder.mm */,

View File

@ -41,16 +41,25 @@
return YES; return YES;
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
long frames = 1024;
long bytesPerFrame = channels * (bitsPerSample / 8); long bytesPerFrame = channels * (bitsPerSample / 8);
long amountRead; long amountRead;
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
uint8_t buffer[bytesPerFrame * 1024];
void *buf = (void *)buffer;
// For some reason a busy loop is causing pops when output is set to 48000. Probably CPU starvation, since the SHN decoder seems to use a multithreaded nonblocking approach. // For some reason a busy loop is causing pops when output is set to 48000. Probably CPU starvation, since the SHN decoder seems to use a multithreaded nonblocking approach.
do { do {
amountRead = decoder->read(buf, frames * bytesPerFrame); amountRead = decoder->read(buf, frames * bytesPerFrame);
} while(amountRead == -1); } while(amountRead == -1);
return (int)(amountRead / bytesPerFrame); [chunk assignSamples:buf frameCount:amountRead / bytesPerFrame];
return chunk;
} }
- (long)seek:(long)sample { - (long)seek:(long)sample {

View File

@ -12,6 +12,7 @@
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
834A42C1287AFED700EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
83747BFA2862D95C0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747BFA2862D95C0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
83F9D7E71A884B44007ABEC2 /* SilenceDecoder.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SilenceDecoder.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 83F9D7E71A884B44007ABEC2 /* SilenceDecoder.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SilenceDecoder.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
83F9D7EB1A884B44007ABEC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 83F9D7EB1A884B44007ABEC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -64,6 +65,7 @@
83F9D7E91A884B44007ABEC2 /* SilenceDecoder */ = { 83F9D7E91A884B44007ABEC2 /* SilenceDecoder */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42C1287AFED700EB9D9B /* AudioChunk.h */,
83F9D8091A884CB5007ABEC2 /* Logging.h */, 83F9D8091A884CB5007ABEC2 /* Logging.h */,
83F9D8081A884C93007ABEC2 /* Plugin.h */, 83F9D8081A884C93007ABEC2 /* Plugin.h */,
83F9D8041A884C23007ABEC2 /* PlaylistController.h */, 83F9D8041A884C23007ABEC2 /* PlaylistController.h */,

View File

@ -50,7 +50,11 @@ enum { channels = 2 };
return @{}; return @{};
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
int frames = 1024;
float buffer[frames * channels];
void *buf = (void *)buffer;
int total = frames; int total = frames;
if(!IsRepeatOneSet()) { if(!IsRepeatOneSet()) {
@ -62,7 +66,11 @@ enum { channels = 2 };
memset(buf, 0, sizeof(float) * total * channels); memset(buf, 0, sizeof(float) * total * channels);
return total; id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:total];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {

View File

@ -12,6 +12,7 @@
17F563B40C3BDBB30019975C /* TagLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17F563A60C3BDB8F0019975C /* TagLib.framework */; }; 17F563B40C3BDBB30019975C /* TagLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17F563A60C3BDB8F0019975C /* TagLib.framework */; };
17F563B60C3BDBB50019975C /* TagLib.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17F563A60C3BDB8F0019975C /* TagLib.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 17F563B60C3BDBB50019975C /* TagLib.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 17F563A60C3BDB8F0019975C /* TagLib.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
8307D31D286072BF000FF8EB /* SandboxBroker.h in Headers */ = {isa = PBXBuildFile; fileRef = 8307D31C286072BF000FF8EB /* SandboxBroker.h */; }; 8307D31D286072BF000FF8EB /* SandboxBroker.h in Headers */ = {isa = PBXBuildFile; fileRef = 8307D31C286072BF000FF8EB /* SandboxBroker.h */; };
834A42C3287AFF5E00EB9D9B /* AudioChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 834A42C2287AFF5E00EB9D9B /* AudioChunk.h */; };
8356BCE527B377C20074E50C /* TagLibID3v2Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 8356BCE327B377C20074E50C /* TagLibID3v2Reader.h */; }; 8356BCE527B377C20074E50C /* TagLibID3v2Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 8356BCE327B377C20074E50C /* TagLibID3v2Reader.h */; };
8356BCE627B377C20074E50C /* TagLibID3v2Reader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8356BCE427B377C20074E50C /* TagLibID3v2Reader.mm */; }; 8356BCE627B377C20074E50C /* TagLibID3v2Reader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8356BCE427B377C20074E50C /* TagLibID3v2Reader.mm */; };
8384913A18081FFC00E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384913918081FFC00E7332D /* Logging.h */; }; 8384913A18081FFC00E7332D /* Logging.h in Headers */ = {isa = PBXBuildFile; fileRef = 8384913918081FFC00E7332D /* Logging.h */; };
@ -60,6 +61,7 @@
17F563A00C3BDB8F0019975C /* TagLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = TagLib.xcodeproj; path = ../../Frameworks/TagLib/TagLib.xcodeproj; sourceTree = SOURCE_ROOT; }; 17F563A00C3BDB8F0019975C /* TagLib.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = TagLib.xcodeproj; path = ../../Frameworks/TagLib/TagLib.xcodeproj; sourceTree = SOURCE_ROOT; };
32DBCF630370AF2F00C91783 /* TagLib_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagLib_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* TagLib_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagLib_Prefix.pch; sourceTree = "<group>"; };
8307D31C286072BF000FF8EB /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../Utils/SandboxBroker.h; sourceTree = "<group>"; }; 8307D31C286072BF000FF8EB /* SandboxBroker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SandboxBroker.h; path = ../../Utils/SandboxBroker.h; sourceTree = "<group>"; };
834A42C2287AFF5E00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
8356BCE327B377C20074E50C /* TagLibID3v2Reader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TagLibID3v2Reader.h; sourceTree = "<group>"; }; 8356BCE327B377C20074E50C /* TagLibID3v2Reader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TagLibID3v2Reader.h; sourceTree = "<group>"; };
8356BCE427B377C20074E50C /* TagLibID3v2Reader.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TagLibID3v2Reader.mm; sourceTree = "<group>"; }; 8356BCE427B377C20074E50C /* TagLibID3v2Reader.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = TagLibID3v2Reader.mm; sourceTree = "<group>"; };
83747BF52862D9470021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747BF52862D9470021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
@ -115,6 +117,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42C2287AFF5E00EB9D9B /* AudioChunk.h */,
8307D31C286072BF000FF8EB /* SandboxBroker.h */, 8307D31C286072BF000FF8EB /* SandboxBroker.h */,
8384913918081FFC00E7332D /* Logging.h */, 8384913918081FFC00E7332D /* Logging.h */,
07CACE890ED1AD1000C0F1E8 /* TagLibMetadataWriter.h */, 07CACE890ED1AD1000C0F1E8 /* TagLibMetadataWriter.h */,
@ -188,6 +191,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
8384913A18081FFC00E7332D /* Logging.h in Headers */, 8384913A18081FFC00E7332D /* Logging.h in Headers */,
834A42C3287AFF5E00EB9D9B /* AudioChunk.h in Headers */,
8307D31D286072BF000FF8EB /* SandboxBroker.h in Headers */, 8307D31D286072BF000FF8EB /* SandboxBroker.h in Headers */,
8356BCE527B377C20074E50C /* TagLibID3v2Reader.h in Headers */, 8356BCE527B377C20074E50C /* TagLibID3v2Reader.h in Headers */,
); );

View File

@ -200,9 +200,10 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
} }
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
int numread; int numread;
int total = 0; int total = 0;
int frames = 1024;
if(currentSection != lastSection) { if(currentSection != lastSection) {
vorbis_info *vi; vorbis_info *vi;
@ -218,6 +219,12 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
[self updateMetadata]; [self updateMetadata];
} }
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
float buffer[frames * channels];
void *buf = (void *)buffer;
do { do {
lastSection = currentSection; lastSection = currentSection;
float **pcm; float **pcm;
@ -247,7 +254,9 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
[self updateIcyMetadata]; [self updateIcyMetadata];
return total; [chunk assignSamples:buffer frameCount:total];
return chunk;
} }
- (void)close { - (void)close {

View File

@ -28,6 +28,7 @@
8301C14A287810F300651A6E /* libFLAC.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libFLAC.8.dylib; path = ../../ThirdParty/flac/lib/libFLAC.8.dylib; sourceTree = "<group>"; }; 8301C14A287810F300651A6E /* libFLAC.8.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libFLAC.8.dylib; path = ../../ThirdParty/flac/lib/libFLAC.8.dylib; sourceTree = "<group>"; };
83186311285CEBD2001422CC /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; }; 83186311285CEBD2001422CC /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; };
83186312285CEBD2001422CC /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+Merge.m"; path = "../../Utils/NSDictionary+Merge.m"; sourceTree = "<group>"; }; 83186312285CEBD2001422CC /* NSDictionary+Merge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+Merge.m"; path = "../../Utils/NSDictionary+Merge.m"; sourceTree = "<group>"; };
834A42AB287AF0B000EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
8356BD1C27B46A2D0074E50C /* HTTPSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPSource.h; path = ../HTTPSource/HTTPSource.h; sourceTree = "<group>"; }; 8356BD1C27B46A2D0074E50C /* HTTPSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HTTPSource.h; path = ../HTTPSource/HTTPSource.h; sourceTree = "<group>"; };
836EF0D427BB969D00BF35B2 /* libvorbisfile.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbisfile.3.dylib; path = ../../ThirdParty/vorbis/lib/libvorbisfile.3.dylib; sourceTree = "<group>"; }; 836EF0D427BB969D00BF35B2 /* libvorbisfile.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbisfile.3.dylib; path = ../../ThirdParty/vorbis/lib/libvorbisfile.3.dylib; sourceTree = "<group>"; };
836EF0DE27BB987000BF35B2 /* libvorbis.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbis.0.dylib; path = ../../ThirdParty/vorbis/lib/libvorbis.0.dylib; sourceTree = "<group>"; }; 836EF0DE27BB987000BF35B2 /* libvorbis.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbis.0.dylib; path = ../../ThirdParty/vorbis/lib/libvorbis.0.dylib; sourceTree = "<group>"; };
@ -92,6 +93,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42AB287AF0B000EB9D9B /* AudioChunk.h */,
83186311285CEBD2001422CC /* NSDictionary+Merge.h */, 83186311285CEBD2001422CC /* NSDictionary+Merge.h */,
83186312285CEBD2001422CC /* NSDictionary+Merge.m */, 83186312285CEBD2001422CC /* NSDictionary+Merge.m */,
8356BD1C27B46A2D0074E50C /* HTTPSource.h */, 8356BD1C27B46A2D0074E50C /* HTTPSource.h */,

View File

@ -52,6 +52,7 @@
177FCF940B90C9450011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; }; 177FCF940B90C9450011C3B5 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; };
17F562C20C3BDA5A0019975C /* WavPack.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = WavPack.xcodeproj; path = ../../Frameworks/WavPack/WavPack.xcodeproj; sourceTree = SOURCE_ROOT; }; 17F562C20C3BDA5A0019975C /* WavPack.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = WavPack.xcodeproj; path = ../../Frameworks/WavPack/WavPack.xcodeproj; sourceTree = SOURCE_ROOT; };
32DBCF630370AF2F00C91783 /* WavPack_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WavPack_Prefix.pch; sourceTree = "<group>"; }; 32DBCF630370AF2F00C91783 /* WavPack_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WavPack_Prefix.pch; sourceTree = "<group>"; };
834A42AA287AEFC300EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
83747BE62862D8D60021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747BE62862D8D60021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
83849133180819EB00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 83849133180819EB00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* WavPack.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WavPack.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B6048680CD000E48DA /* WavPack.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WavPack.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
@ -105,6 +106,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42AA287AEFC300EB9D9B /* AudioChunk.h */,
83849133180819EB00E7332D /* Logging.h */, 83849133180819EB00E7332D /* Logging.h */,
177FCF940B90C9450011C3B5 /* Plugin.h */, 177FCF940B90C9450011C3B5 /* Plugin.h */,
1745C4D50B90C42500A6768C /* WavPackDecoder.h */, 1745C4D50B90C42500A6768C /* WavPackDecoder.h */,

View File

@ -196,7 +196,12 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) {
return n; return n;
} }
*/ */
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
int32_t frames = 1024;
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
uint32_t sample; uint32_t sample;
int32_t audioSample; int32_t audioSample;
uint32_t samplesRead; uint32_t samplesRead;
@ -204,6 +209,10 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) {
int16_t *alias16; int16_t *alias16;
int32_t *alias32; int32_t *alias32;
const size_t bufferSize = frames * [chunk format].mBytesPerFrame;
uint8_t buffer[bufferSize];
void *buf = (void *)buffer;
size_t newSize = frames * sizeof(int32_t) * channels; size_t newSize = frames * sizeof(int32_t) * channels;
if(!inputBuffer || newSize > inputBufferSize) { if(!inputBuffer || newSize > inputBufferSize) {
inputBuffer = realloc(inputBuffer, inputBufferSize = newSize); inputBuffer = realloc(inputBuffer, inputBufferSize = newSize);
@ -248,7 +257,9 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) {
ALog(@"Unsupported sample size: %d", bitsPerSample); ALog(@"Unsupported sample size: %d", bitsPerSample);
} }
return samplesRead; [chunk assignSamples:buffer frameCount:samplesRead];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {

View File

@ -208,9 +208,18 @@ const int masterVol = 0x10000; // Fixed point 16.16
return @{}; return @{};
} }
- (int)readAudio:(void*)buf frames:(UInt32)frames { - (AudioChunk*)readAudio {
if([self trackEnded]) if([self trackEnded])
return 0; return nil;
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk* chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
int frames = 1024;
const size_t bytesPerFrame = [chunk format].mBytesPerFrame;
uint8_t buffer[frames * bytesPerFrame];
void* buf = (void*)buffer;
BOOL repeatOne = IsRepeatOneSet(); BOOL repeatOne = IsRepeatOneSet();
uint32_t maxLoops = repeatOne ? 0 : (uint32_t)loopCount; uint32_t maxLoops = repeatOne ? 0 : (uint32_t)loopCount;
@ -238,7 +247,9 @@ const int masterVol = 0x10000; // Fixed point 16.16
framesDone += framesToDo; framesDone += framesToDo;
} }
return framesDone; [chunk assignSamples:buffer frameCount:framesDone];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {

View File

@ -40,6 +40,7 @@
83489C602782F39D00BDCEA2 /* libvgm-player.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libvgm-player.a"; path = "../../ThirdParty/libvgm/lib/libvgm-player.a"; sourceTree = "<group>"; }; 83489C602782F39D00BDCEA2 /* libvgm-player.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libvgm-player.a"; path = "../../ThirdParty/libvgm/lib/libvgm-player.a"; sourceTree = "<group>"; };
83489C652782F74800BDCEA2 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 83489C652782F74800BDCEA2 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
83489C672782F74E00BDCEA2 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; }; 83489C672782F74E00BDCEA2 /* libiconv.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libiconv.tbd; path = usr/lib/libiconv.tbd; sourceTree = SDKROOT; };
834A42AC287AF18E00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
835C888F22CC1883001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 835C888F22CC1883001B4B3F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83747C312862DBE80021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C312862DBE80021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
8384912E1808175400E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 8384912E1808175400E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
@ -102,6 +103,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42AC287AF18E00EB9D9B /* AudioChunk.h */,
17C8F33B0CBED3BE008D969D /* libvgmContainer.h */, 17C8F33B0CBED3BE008D969D /* libvgmContainer.h */,
17C8F33C0CBED3BE008D969D /* libvgmContainer.mm */, 17C8F33C0CBED3BE008D969D /* libvgmContainer.mm */,
17C8F33D0CBED3BE008D969D /* libvgmDecoder.h */, 17C8F33D0CBED3BE008D969D /* libvgmDecoder.h */,

View File

@ -62,7 +62,7 @@ static const char *extListStr[] = { ".str", NULL };
- (sid_file_container *)init { - (sid_file_container *)init {
if((self = [super init])) { if((self = [super init])) {
lock = [[NSLock alloc] init]; lock = [[NSLock alloc] init];
list = [[NSMutableDictionary alloc] initWithCapacity:0]; list = [[NSMutableDictionary alloc] init];
} }
return self; return self;
} }
@ -275,59 +275,54 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
return @{}; return @{};
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
int total = 0; int total = 0;
int16_t *sampleBuffer = (int16_t *)buf; id audioChunkClass = NSClassFromString(@"AudioChunk");
while(total < frames) { AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
int framesToRender = 1024;
if(framesToRender > frames)
framesToRender = frames;
int rendered = engine->play(sampleBuffer + total * n_channels, framesToRender * n_channels) / n_channels;
if(rendered <= 0) int16_t buffer[1024 * n_channels];
break;
if(n_channels == 2) { int framesToRender = 1024;
for(int i = 0, j = rendered * 2; i < j; i += 2) { int rendered = engine->play(buffer, framesToRender * n_channels) / n_channels;
int16_t *sample = sampleBuffer + total * 2 + i;
int mid = (int)(sample[0] + sample[1]) / 2; if(rendered <= 0)
int side = (int)(sample[0] - sample[1]) / 4; return nil;
sample[0] = mid + side;
sample[1] = mid - side; if(n_channels == 2) {
} for(int i = 0, j = rendered * 2; i < j; i += 2) {
int16_t *sample = buffer + total * 2 + i;
int mid = (int)(sample[0] + sample[1]) / 2;
int side = (int)(sample[0] - sample[1]) / 4;
sample[0] = mid + side;
sample[1] = mid - side;
} }
renderedTotal += rendered;
if(!IsRepeatOneSet() && renderedTotal >= length) {
int16_t *sampleBuf = (int16_t *)buf + total * n_channels;
long fadeEnd = fadeRemain - rendered;
if(fadeEnd < 0)
fadeEnd = 0;
float fadePosf = (float)fadeRemain / (float)fadeTotal;
const float fadeStep = 1.0f / (float)fadeTotal;
for(long fadePos = fadeRemain; fadePos > fadeEnd; --fadePos, fadePosf -= fadeStep) {
long offset = (fadeRemain - fadePos) * n_channels;
float sampleLeft = sampleBuf[offset + 0];
sampleLeft *= fadePosf;
sampleBuf[offset + 0] = (int16_t)sampleLeft;
if(n_channels == 2) {
float sampleRight = sampleBuf[offset + 1];
sampleRight *= fadePosf;
sampleBuf[offset + 1] = (int16_t)sampleRight;
}
}
rendered = (int)(fadeRemain - fadeEnd);
fadeRemain = fadeEnd;
}
total += rendered;
if(rendered < framesToRender)
break;
} }
return total; if(!IsRepeatOneSet() && renderedTotal >= length) {
int16_t *sampleBuf = buffer;
long fadeEnd = fadeRemain - rendered;
if(fadeEnd < 0)
fadeEnd = 0;
float fadePosf = (float)fadeRemain / (float)fadeTotal;
const float fadeStep = 1.0f / (float)fadeTotal;
for(long fadePos = fadeRemain; fadePos > fadeEnd; --fadePos, fadePosf -= fadeStep) {
long offset = (fadeRemain - fadePos) * n_channels;
float sampleLeft = sampleBuf[offset + 0];
sampleLeft *= fadePosf;
sampleBuf[offset + 0] = (int16_t)sampleLeft;
if(n_channels == 2) {
float sampleRight = sampleBuf[offset + 1];
sampleRight *= fadePosf;
sampleBuf[offset + 1] = (int16_t)sampleRight;
}
}
rendered = (int)(fadeRemain - fadeEnd);
fadeRemain = fadeEnd;
}
[chunk assignSamples:buffer frameCount:rendered];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {

View File

@ -52,6 +52,7 @@
8314D80D1A35658C00EEE8E6 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../../Utils/Logging.h; sourceTree = "<group>"; }; 8314D80D1A35658C00EEE8E6 /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../../Utils/Logging.h; sourceTree = "<group>"; };
8314D80E1A3565AC00EEE8E6 /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../../Playlist/PlaylistController.h; sourceTree = "<group>"; }; 8314D80E1A3565AC00EEE8E6 /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../../Playlist/PlaylistController.h; sourceTree = "<group>"; };
833A8996286FF2E30022E036 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 833A8996286FF2E30022E036 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
834A42A6287AEAAB00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
836F5BEA1A357915002730CC /* roms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = roms.cpp; sourceTree = SOURCE_ROOT; }; 836F5BEA1A357915002730CC /* roms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = roms.cpp; sourceTree = SOURCE_ROOT; };
836F5BEB1A357915002730CC /* roms.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = roms.hpp; sourceTree = SOURCE_ROOT; }; 836F5BEB1A357915002730CC /* roms.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = roms.hpp; sourceTree = SOURCE_ROOT; };
83747BFF2862DA420021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747BFF2862DA420021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
@ -92,6 +93,7 @@
8314D6331A354DFE00EEE8E6 /* sidplay */ = { 8314D6331A354DFE00EEE8E6 /* sidplay */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
834A42A6287AEAAB00EB9D9B /* AudioChunk.h */,
836F5BEA1A357915002730CC /* roms.cpp */, 836F5BEA1A357915002730CC /* roms.cpp */,
836F5BEB1A357915002730CC /* roms.hpp */, 836F5BEB1A357915002730CC /* roms.hpp */,
8314D80E1A3565AC00EEE8E6 /* PlaylistController.h */, 8314D80E1A3565AC00EEE8E6 /* PlaylistController.h */,

View File

@ -52,6 +52,7 @@
833F68491CDBCAC000AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F68491CDBCAC000AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
8340888B1F6F604A00DCD404 /* VGMMetadataReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VGMMetadataReader.m; sourceTree = "<group>"; }; 8340888B1F6F604A00DCD404 /* VGMMetadataReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VGMMetadataReader.m; sourceTree = "<group>"; };
8340888D1F6F604B00DCD404 /* VGMMetadataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VGMMetadataReader.h; sourceTree = "<group>"; }; 8340888D1F6F604B00DCD404 /* VGMMetadataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VGMMetadataReader.h; sourceTree = "<group>"; };
834A42A8287AEDFB00EB9D9B /* AudioChunk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioChunk.h; path = ../../../Audio/Chain/AudioChunk.h; sourceTree = "<group>"; };
835D241E235AB318009A1251 /* VGMPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VGMPropertiesReader.m; sourceTree = "<group>"; }; 835D241E235AB318009A1251 /* VGMPropertiesReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VGMPropertiesReader.m; sourceTree = "<group>"; };
835D241F235AB319009A1251 /* VGMPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VGMPropertiesReader.h; sourceTree = "<group>"; }; 835D241F235AB319009A1251 /* VGMPropertiesReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VGMPropertiesReader.h; sourceTree = "<group>"; };
836F6B1018BDB80D0095E648 /* vgmstream.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = vgmstream.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 836F6B1018BDB80D0095E648 /* vgmstream.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = vgmstream.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
@ -141,6 +142,7 @@
836F705A18BDC40E0095E648 /* VGMDecoder.h */, 836F705A18BDC40E0095E648 /* VGMDecoder.h */,
836F705B18BDC40E0095E648 /* VGMDecoder.m */, 836F705B18BDC40E0095E648 /* VGMDecoder.m */,
83AA5D2F1F6E301B0020821C /* Logging.h */, 83AA5D2F1F6E301B0020821C /* Logging.h */,
834A42A8287AEDFB00EB9D9B /* AudioChunk.h */,
836F706018BDC84D0095E648 /* Plugin.h */, 836F706018BDC84D0095E648 /* Plugin.h */,
836F6B1A18BDB80D0095E648 /* Supporting Files */, 836F6B1A18BDB80D0095E648 /* Supporting Files */,
); );

View File

@ -311,10 +311,17 @@ static NSString *get_description_tag(const char *description, const char *tag, c
return @{}; return @{};
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (AudioChunk *)readAudio {
UInt32 frames = 1024;
UInt32 framesMax = frames; UInt32 framesMax = frames;
UInt32 framesDone = 0; UInt32 framesDone = 0;
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
int16_t buffer[1024 * channels];
void *buf = (void *)buffer;
if(canPlayForever) { if(canPlayForever) {
BOOL repeatone = IsRepeatOneSet(); BOOL repeatone = IsRepeatOneSet();
@ -354,7 +361,9 @@ static NSString *get_description_tag(const char *description, const char *tag, c
frames -= frames_to_do; frames -= frames_to_do;
} }
return framesDone; [chunk assignSamples:buffer frameCount:framesDone];
return chunk;
} }
- (long)seek:(long)frame { - (long)seek:(long)frame {