[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;
- (id)init;
- (id)initWithProperties:(NSDictionary *)properties;
- (void)assignSamples:(const void *)data frameCount:(size_t)count;
@ -88,6 +89,7 @@ enum {
- (BOOL)isEmpty;
- (size_t)frameCount;
- (void)setFrameCount:(size_t)count; // For truncation only
- (double)duration;

View File

@ -7,6 +7,8 @@
#import "AudioChunk.h"
#import "CoreAudioUtils.h"
@implementation AudioChunk
- (id)init {
@ -21,6 +23,18 @@
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[] = {
0,
AudioConfigMono,
@ -156,6 +170,16 @@ static const uint32_t AudioChannelConfigTable[] = {
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 {
if(formatAssigned) {
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 {
char writeBuf[CHUNK_SIZE];
// 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,
// and returns 0 samples when it has nothing more to process at the end of stream.
while([self shouldContinue] == YES) {
int amountConverted;
AudioChunk *chunk = nil;
while(paused) {
usleep(500);
}
@autoreleasepool {
amountConverted = [self convert:writeBuf amount:CHUNK_SIZE];
chunk = [self convert];
}
if(!amountConverted) {
if(paused) {
continue;
} else if(streamFormatChanged) {
[self cleanUp];
[self setupWithInputFormat:newInputFormat withInputConfig:newInputChannelConfig isLossless:rememberedLossless];
continue;
} else
break;
if(!chunk) {
continue;
}
@autoreleasepool {
[self writeChunk:chunk];
chunk = nil;
}
if(streamFormatChanged) {
[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;
int amountReadFromFC;
int amountRead = 0;
@ -472,7 +470,7 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
tryagain:
if(stopping || [self shouldContinue] == NO) {
convertEntered = NO;
return amountRead;
return nil;
}
amountReadFromFC = 0;
@ -543,7 +541,7 @@ tryagain:
if(!bytesReadFromInput) {
convertEntered = NO;
return amountRead;
return nil;
}
if(bytesReadFromInput && isBigEndian) {
@ -703,19 +701,22 @@ tryagain:
if(floatOffset == floatSize)
goto tryagain;
ioNumberPackets = (amount - amountRead);
if(ioNumberPackets > (floatSize - floatOffset))
ioNumberPackets = (UInt32)(floatSize - floatOffset);
ioNumberPackets = (UInt32)(floatSize - floatOffset);
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;
amountRead += ioNumberPackets;
convertEntered = NO;
return amountRead;
return chunk;
}
- (void)observeValueForKeyPath:(NSString *)keyPath

View File

@ -142,10 +142,6 @@ static void *kInputNodeContext = &kInputNodeContext;
}
- (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 seekError = NO;
@ -165,7 +161,6 @@ static void *kInputNodeContext = &kInputNodeContext;
ConverterNode *converter = [bufferChain converter];
DLog(@"SEEKING! Resetting Buffer");
amountInBuffer = 0;
// This resets the converter's buffer
[self resetBuffer];
[converter resetBuffer];
@ -174,7 +169,9 @@ static void *kInputNodeContext = &kInputNodeContext;
DLog(@"Reset buffer!");
DLog(@"SEEKING!");
seekError = [decoder seek:seekFrame] < 0;
@autoreleasepool {
seekError = [decoder seek:seekFrame] < 0;
}
shouldSeek = NO;
DLog(@"Seeked! Resetting Buffer");
@ -185,44 +182,39 @@ static void *kInputNodeContext = &kInputNodeContext;
}
}
if(amountInBuffer < CHUNK_SIZE) {
int framesToRead = CHUNK_SIZE - amountInBuffer;
int framesRead;
AudioChunk *chunk;
@autoreleasepool {
chunk = [decoder readAudio];
}
if(chunk) {
@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) {
amountInBuffer += framesRead;
bytesInBuffer += framesRead * bytesPerFrame;
[self writeData:inputBuffer amount:bytesInBuffer];
amountInBuffer = 0;
bytesInBuffer = 0;
// 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 {
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];
}
// 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;
}
break;
}
}
}
@ -230,8 +222,6 @@ static void *kInputNodeContext = &kInputNodeContext;
if(shouldClose)
[decoder close];
free(inputBuffer);
[exitAtTheEndOfTheStream signal];
DLog("Input node thread stopping");

View File

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

View File

@ -25,7 +25,7 @@
buffer = [[ChunkList alloc] initWithMaximumDuration:3.0];
semaphore = [[Semaphore alloc] init];
accessLock = [[NSRecursiveLock alloc] init];
accessLock = [[NSLock alloc] init];
initialBufferFilled = NO;
@ -91,6 +91,35 @@
[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.
- (void)process {
}

View File

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

View File

@ -1,5 +1,7 @@
// Plugins! HOORAY!
#import "AudioChunk.h"
@protocol CogSource <NSObject>
+ (NSArray *)schemes; // http, file, etc
@ -42,7 +44,7 @@
- (NSDictionary *)properties;
- (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;
- (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>"; };
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>"; };
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>"; };
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>"; };
@ -1227,6 +1228,7 @@
177EC0110B8BC2CF0000BC8C /* Utils */ = {
isa = PBXGroup;
children = (
834A42C4287B01B600EB9D9B /* AudioChunk.h */,
8384912518080F2D00E7332D /* Logging.h */,
07E18DF10D62B38400BB0E11 /* NSArray+ShuffleUtils.h */,
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>"; };
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>"; };
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>"; };
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>"; };
@ -74,6 +75,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42AF287AF34300EB9D9B /* AudioChunk.h */,
838491281808135500E7332D /* Logging.h */,
8E8D423C0CBB0FF600135C1B /* Plugin.h */,
8E8D42350CBB0F9800135C1B /* APLDecoder.h */,

View File

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

View File

@ -52,6 +52,7 @@
/* Begin PBXFileReference section */
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>"; };
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>"; };
@ -123,6 +124,7 @@
83D3C5F5201C674D005564CB /* AdPlug */ = {
isa = PBXGroup;
children = (
834A42AE287AF27A00EB9D9B /* AudioChunk.h */,
83D3C667201C7020005564CB /* adplug.db */,
83D3C657201C6E24005564CB /* AdPlugContainer.h */,
83D3C654201C6E24005564CB /* AdPlugContainer.mm */,

View File

@ -103,7 +103,14 @@ static CAdPlugDatabase *g_database = NULL;
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;
bool dont_loop = !IsRepeatOneSet();
if(dont_loop && current_pos + frames > length)
@ -128,7 +135,9 @@ static CAdPlugDatabase *g_database = NULL;
total += samples_now;
}
return total;
[chunk assignSamples:buffer frameCount:total];
return chunk;
}
- (long)seek:(long)frame {

View File

@ -33,6 +33,7 @@
/* Begin PBXFileReference section */
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>"; };
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>"; };
@ -105,6 +106,7 @@
8359FF2017FEF35C0060F3ED /* ArchiveSource */ = {
isa = PBXGroup;
children = (
834A42B0287AF4BF00EB9D9B /* AudioChunk.h */,
8307D31A286070EA000FF8EB /* SandboxBroker.h */,
8384913518081BA000E7332D /* Logging.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>"; };
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>"; };
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>"; };
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; };
@ -77,6 +78,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42B1287AF4D900EB9D9B /* AudioChunk.h */,
83849129180813E800E7332D /* Logging.h */,
177FCFCA0B90C9A10011C3B5 /* Plugin.h */,
17C93E720B8FF192008627D6 /* CoreAudioDecoder.h */,

View File

@ -306,25 +306,33 @@ static SInt64 getSizeProc(void *clientData) {
return YES;
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
OSStatus err;
AudioBufferList bufferList;
UInt32 frameCount;
int frames = 1024;
size_t bytesPerFrame = channels * (bitsPerSample / 8);
uint8_t buffer[frames * bytesPerFrame];
// Set up the AudioBufferList
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = channels;
bufferList.mBuffers[0].mData = buf;
bufferList.mBuffers[0].mData = buffer;
bufferList.mBuffers[0].mDataByteSize = frames * channels * (bitsPerSample / 8);
// Read a chunk of PCM input (converted from whatever format)
frameCount = frames;
err = ExtAudioFileRead(_in, &frameCount, &bufferList);
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 {

View File

@ -24,6 +24,7 @@
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>"; };
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>"; };
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>"; };
@ -89,6 +90,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42B2287AF59900EB9D9B /* AudioChunk.h */,
839DA7D3274A2FD4001B18E5 /* NSDictionary+Merge.h */,
839DA7D0274A2EA9001B18E5 /* AudioMetadataReader.h */,
8384912A180814D900E7332D /* Logging.h */,

View File

@ -309,25 +309,32 @@ static void *kCueSheetDecoderContext = &kCueSheetDecoderContext;
return framePosition - trackStart;
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
if(!seekedToStart) {
[self seek:0];
}
int frames = INT_MAX;
if(!noFragment && framePosition + frames > trackEnd) {
frames = (UInt32)(trackEnd - framePosition);
}
if(!frames) {
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 {

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>"; };
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>"; };
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; };
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; };
@ -145,6 +146,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42B3287AF65000EB9D9B /* AudioChunk.h */,
8356BD1A27B3D06F0074E50C /* HTTPSource.h */,
8356BCEA27B37DA40074E50C /* TagLibID3v2Reader.h */,
8356BCE827B37C6F0074E50C /* NSDictionary+Merge.h */,

View File

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

View File

@ -471,13 +471,10 @@ static uint8_t reverse_bits[0x100];
metadataUpdated = NO;
[self updateMetadata];
prebufferedAudio = 0;
prebufferedAudioData = NULL;
prebufferedChunk = nil;
if(attachedPicIndex >= 0) {
int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8);
prebufferedAudioData = malloc(1024 * frameSize);
[self readAudio:prebufferedAudioData frames:1024];
prebufferedChunk = [self readAudio];
}
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) {
[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 bytesToRead = frames * frameSize;
int bytesRead = 0;
if(prebufferedAudio) {
// A bit of ignored read-ahead to support embedded artwork
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;
uint8_t buffer[bytesToRead];
void *buf = (void *)buffer;
int dataSize = 0;
@ -909,7 +907,11 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
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 {
@ -918,7 +920,7 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
seekedToStart = YES;
prebufferedAudio = 0;
prebufferedChunk = nil;
if(frame >= 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>"; };
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>"; };
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>"; };
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>"; };
@ -91,6 +92,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42AD287AF25600EB9D9B /* AudioChunk.h */,
8307D31B2860722C000FF8EB /* SandboxBroker.h */,
17ADB4080B979A8A00257CA2 /* Plugin.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>"; };
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>"; };
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>"; };
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>"; };
@ -92,6 +93,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42B4287AF7AA00EB9D9B /* AudioChunk.h */,
8301C145287805F500651A6E /* NSDictionary+Merge.h */,
8301C146287805F500651A6E /* NSDictionary+Merge.m */,
83AA660A27B7DAE40098D4B8 /* cuesheet.m */,

View File

@ -361,39 +361,23 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
return YES;
}
- (int)readAudio:(void *)buffer frames:(UInt32)frames {
int framesRead = 0;
while(framesRead < frames) {
if(blockBufferFrames == 0) {
if(framesRead) {
break;
}
- (AudioChunk *)readAudio {
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = nil;
if(FLAC__stream_decoder_get_state(decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) {
break;
}
if(FLAC__stream_decoder_get_state(decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) {
return nil;
}
if(!FLAC__stream_decoder_process_single(decoder)) {
break;
}
}
if(!FLAC__stream_decoder_process_single(decoder)) {
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;
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);
}
blockBufferFrames = 0;
}
if(![source seekable]) {
@ -429,7 +413,7 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
}
}
return framesRead;
return chunk;
}
- (void)close {

View File

@ -63,6 +63,7 @@
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>"; };
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>"; };
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>"; };
@ -119,6 +120,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42B5287AF8FE00EB9D9B /* AudioChunk.h */,
17C8F33B0CBED3BE008D969D /* GameContainer.h */,
17C8F33C0CBED3BE008D969D /* GameContainer.m */,
17C8F33D0CBED3BE008D969D /* GameDecoder.h */,

View File

@ -174,11 +174,18 @@ gme_err_t readCallback(void *data, void *out, int count) {
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
if(gme_track_ended(emu)) {
return 0;
return nil;
}
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.
//(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 {

View File

@ -32,6 +32,7 @@
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; };
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; };
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>"; };
@ -87,6 +88,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42B9287AFAB500EB9D9B /* AudioChunk.h */,
8384912F1808180000E7332D /* Logging.h */,
17ADB6340B97A8B400257CA2 /* Plugin.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>"; };
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>"; };
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; };
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; };
@ -311,6 +312,7 @@
8360EEED17F92AC8005208A4 /* HighlyComplete */ = {
isa = PBXGroup;
children = (
834A42B6287AF99600EB9D9B /* AudioChunk.h */,
83AA660827B7CCB00098D4B8 /* Logging.h */,
83FAF8A318ADD27F00057CAF /* PlaylistController.h */,
8324C584181513A10046F78F /* circular_buffer.h */,

View File

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

View File

@ -49,6 +49,7 @@
/* Begin PBXFileReference section */
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>"; };
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; };
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; };
@ -122,6 +123,7 @@
836FB5361820538700B3AD2D /* Hively */ = {
isa = PBXGroup;
children = (
834A42B8287AFA3600EB9D9B /* AudioChunk.h */,
831C7F6918ADD73F00CE4A69 /* PlaylistController.h */,
836FB5A31820557E00B3AD2D /* Plugin.h */,
836FB59A1820556F00B3AD2D /* HVLDecoder.h */,

View File

@ -107,7 +107,11 @@ static void oneTimeInit(void) {
return @{};
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
int frames = 1024;
float buffer[frames * 2];
void *buf = (void *)buffer;
BOOL repeatone = IsRepeatOneSet();
if(!repeatone && framesRead >= totalFrames)
@ -157,7 +161,11 @@ static void oneTimeInit(void) {
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 {

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>"; };
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>"; };
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>"; };
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>"; };
@ -75,6 +76,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42BA287AFAEF00EB9D9B /* AudioChunk.h */,
83849130180818B100E7332D /* Logging.h */,
8E8D401B0CBAFEF200135C1B /* Plugin.h */,
8E8D40270CBAFF4300135C1B /* M3uContainer.h */,

View File

@ -15,6 +15,7 @@
/* End PBXBuildFile 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; };
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>"; };
@ -48,6 +49,7 @@
children = (
83747C262862DB9F0021245F /* Xcode-config */,
83F97B6628600F9300A70B97 /* ThirdParty */,
834A42BB287AFB0700EB9D9B /* AudioChunk.h */,
8372C93A27C786DD00E250C9 /* HTTPSource.h */,
8372C93927C7866B00E250C9 /* Logging.h */,
8372C93827C7865A00E250C9 /* Plugin.h */,

View File

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

View File

@ -99,6 +99,7 @@
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>"; };
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>"; };
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>"; };
@ -306,6 +307,7 @@
83B06690180D5668008E3612 /* MIDI */ = {
isa = PBXGroup;
children = (
834A42BC287AFC7F00EB9D9B /* AudioChunk.h */,
8307D31E28607377000FF8EB /* SandboxBroker.h */,
831E2A9127B4B2FA006F1C86 /* json */,
831E2A7D27B4B2B2006F1C86 /* BASS */,

View File

@ -276,14 +276,14 @@ static OSType getOSType(const char *in_) {
return YES;
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
BOOL repeatone = IsRepeatOneSet();
long localFramesLength = framesLength;
long localTotalFrames = totalFrames;
if(!player) {
if(![self initDecoder])
return -1;
return nil;
}
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;
}
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)
return 0;
@ -315,7 +318,7 @@ static OSType getOSType(const char *in_) {
long fadeEnd = (framesRead + frames > localTotalFrames) ? localTotalFrames : (framesRead + frames);
long fadePos;
float *buff = (float *)buf;
float *buff = buffer;
float fadeScale = (float)(framesFade - (fadeStart - localFramesLength)) / framesFade;
float fadeStep = 1.0 / (float)framesFade;
@ -337,13 +340,17 @@ static OSType getOSType(const char *in_) {
}
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 {
if(!player) {
float temp[2];
if([self readAudio:temp frames:1] < 1)
if(![self readAudio])
return -1;
}

View File

@ -51,6 +51,7 @@
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; };
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>"; };
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; };
@ -105,6 +106,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42BD287AFD0D00EB9D9B /* AudioChunk.h */,
838491311808190400E7332D /* Logging.h */,
8E2B8B4A0B9B48D000F2D9E8 /* Plugin.h */,
170333090B8FB64500327265 /* MusepackDecoder.h */,

View File

@ -109,11 +109,15 @@ mpc_bool_t CanSeekProc(mpc_reader *p_reader) {
return YES;
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH];
int frames = 1024;
float buffer[frames * 2];
void *buf = (void *)buffer;
int framesRead = 0;
int bytesPerFrame = sizeof(float) * 2; // bitsPerSample == 16, channels == 2
int bytesPerFrame = sizeof(float) * 2; // bitsPerSample == 32, channels == 2
while(framesRead < frames) {
// Fill from buffer, going by bufferFrames
// 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 {

View File

@ -48,6 +48,7 @@
/* Begin PBXFileReference section */
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>"; };
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>"; };
@ -124,6 +125,7 @@
83E5FE6A1FFF003900659F0F /* Classes */ = {
isa = PBXGroup;
children = (
834A42BE287AFDC300EB9D9B /* AudioChunk.h */,
83E5FE6B1FFF004D00659F0F /* Logging.h */,
83E5FE761FFF076F00659F0F /* PlaylistController.h */,
83E5FE6C1FFF006400659F0F /* Plugin.h */,

View File

@ -112,9 +112,13 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
return @{};
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
mod->set_repeat_count(IsRepeatOneSet() ? -1 : 0);
int frames = 1024;
float buffer[frames * 2];
void *buf = (void *)buffer;
int total = 0;
while(total < frames) {
int framesToRender = 1024;
@ -131,7 +135,11 @@ static void g_push_archive_extensions(std::vector<std::string> &list) {
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 {

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 total = 0;
@ -236,7 +236,10 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
[self updateMetadata];
}
int frames = 1024;
int size = frames * channels;
float buffer[size];
void *buf = (void *)buffer;
do {
float *out = ((float *)buf) + total;
@ -265,7 +268,11 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
[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 {

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>"; };
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>"; };
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>"; };
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>"; };
@ -114,6 +115,7 @@
8375B04517FFEA400092A79F /* Opus */ = {
isa = PBXGroup;
children = (
834A42BF287AFE2600EB9D9B /* AudioChunk.h */,
83186314285CEC91001422CC /* NSDictionary+Merge.h */,
83186315285CEC91001422CC /* NSDictionary+Merge.m */,
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>"; };
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>"; };
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>"; };
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>"; };
@ -75,6 +76,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42C0287AFEB100EB9D9B /* AudioChunk.h */,
838491321808193F00E7332D /* Logging.h */,
8E8D41A50CBB0CBE00135C1B /* Plugin.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; };
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>"; };
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>"; };
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>"; };
@ -104,6 +105,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42A9287AEF1300EB9D9B /* AudioChunk.h */,
177FCFAC0B90C96B0011C3B5 /* Plugin.h */,
1745C42B0B90C1DC00A6768C /* ShortenDecoder.h */,
1745C42C0B90C1DC00A6768C /* ShortenDecoder.mm */,

View File

@ -41,16 +41,25 @@
return YES;
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
long frames = 1024;
long bytesPerFrame = channels * (bitsPerSample / 8);
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.
do {
amountRead = decoder->read(buf, frames * bytesPerFrame);
} while(amountRead == -1);
return (int)(amountRead / bytesPerFrame);
[chunk assignSamples:buf frameCount:amountRead / bytesPerFrame];
return chunk;
}
- (long)seek:(long)sample {

View File

@ -12,6 +12,7 @@
/* End PBXBuildFile 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>"; };
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>"; };
@ -64,6 +65,7 @@
83F9D7E91A884B44007ABEC2 /* SilenceDecoder */ = {
isa = PBXGroup;
children = (
834A42C1287AFED700EB9D9B /* AudioChunk.h */,
83F9D8091A884CB5007ABEC2 /* Logging.h */,
83F9D8081A884C93007ABEC2 /* Plugin.h */,
83F9D8041A884C23007ABEC2 /* PlaylistController.h */,

View File

@ -50,7 +50,11 @@ enum { channels = 2 };
return @{};
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
int frames = 1024;
float buffer[frames * channels];
void *buf = (void *)buffer;
int total = frames;
if(!IsRepeatOneSet()) {
@ -62,7 +66,11 @@ enum { channels = 2 };
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 {

View File

@ -12,6 +12,7 @@
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, ); }; };
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 */; };
8356BCE627B377C20074E50C /* TagLibID3v2Reader.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8356BCE427B377C20074E50C /* TagLibID3v2Reader.mm */; };
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; };
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>"; };
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>"; };
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>"; };
@ -115,6 +117,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42C2287AFF5E00EB9D9B /* AudioChunk.h */,
8307D31C286072BF000FF8EB /* SandboxBroker.h */,
8384913918081FFC00E7332D /* Logging.h */,
07CACE890ED1AD1000C0F1E8 /* TagLibMetadataWriter.h */,
@ -188,6 +191,7 @@
buildActionMask = 2147483647;
files = (
8384913A18081FFC00E7332D /* Logging.h in Headers */,
834A42C3287AFF5E00EB9D9B /* AudioChunk.h in Headers */,
8307D31D286072BF000FF8EB /* SandboxBroker.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 total = 0;
int frames = 1024;
if(currentSection != lastSection) {
vorbis_info *vi;
@ -218,6 +219,12 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
[self updateMetadata];
}
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
float buffer[frames * channels];
void *buf = (void *)buffer;
do {
lastSection = currentSection;
float **pcm;
@ -247,7 +254,9 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
[self updateIcyMetadata];
return total;
[chunk assignSamples:buffer frameCount:total];
return chunk;
}
- (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>"; };
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>"; };
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>"; };
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>"; };
@ -92,6 +93,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42AB287AF0B000EB9D9B /* AudioChunk.h */,
83186311285CEBD2001422CC /* NSDictionary+Merge.h */,
83186312285CEBD2001422CC /* NSDictionary+Merge.m */,
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; };
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>"; };
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>"; };
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; };
@ -105,6 +106,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42AA287AEFC300EB9D9B /* AudioChunk.h */,
83849133180819EB00E7332D /* Logging.h */,
177FCF940B90C9450011C3B5 /* Plugin.h */,
1745C4D50B90C42500A6768C /* WavPackDecoder.h */,

View File

@ -196,7 +196,12 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) {
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;
int32_t audioSample;
uint32_t samplesRead;
@ -204,6 +209,10 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) {
int16_t *alias16;
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;
if(!inputBuffer || newSize > inputBufferSize) {
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);
}
return samplesRead;
[chunk assignSamples:buffer frameCount:samplesRead];
return chunk;
}
- (long)seek:(long)frame {

View File

@ -208,9 +208,18 @@ const int masterVol = 0x10000; // Fixed point 16.16
return @{};
}
- (int)readAudio:(void*)buf frames:(UInt32)frames {
- (AudioChunk*)readAudio {
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();
uint32_t maxLoops = repeatOne ? 0 : (uint32_t)loopCount;
@ -238,7 +247,9 @@ const int masterVol = 0x10000; // Fixed point 16.16
framesDone += framesToDo;
}
return framesDone;
[chunk assignSamples:buffer frameCount:framesDone];
return chunk;
}
- (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>"; };
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; };
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>"; };
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>"; };
@ -102,6 +103,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
834A42AC287AF18E00EB9D9B /* AudioChunk.h */,
17C8F33B0CBED3BE008D969D /* libvgmContainer.h */,
17C8F33C0CBED3BE008D969D /* libvgmContainer.mm */,
17C8F33D0CBED3BE008D969D /* libvgmDecoder.h */,

View File

@ -62,7 +62,7 @@ static const char *extListStr[] = { ".str", NULL };
- (sid_file_container *)init {
if((self = [super init])) {
lock = [[NSLock alloc] init];
list = [[NSMutableDictionary alloc] initWithCapacity:0];
list = [[NSMutableDictionary alloc] init];
}
return self;
}
@ -275,59 +275,54 @@ static void sidTuneLoader(const char *fileName, std::vector<uint8_t> &bufferRef)
return @{};
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
int total = 0;
int16_t *sampleBuffer = (int16_t *)buf;
while(total < frames) {
int framesToRender = 1024;
if(framesToRender > frames)
framesToRender = frames;
int rendered = engine->play(sampleBuffer + total * n_channels, framesToRender * n_channels) / n_channels;
id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
if(rendered <= 0)
break;
int16_t buffer[1024 * n_channels];
if(n_channels == 2) {
for(int i = 0, j = rendered * 2; i < j; i += 2) {
int16_t *sample = sampleBuffer + 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;
}
int framesToRender = 1024;
int rendered = engine->play(buffer, framesToRender * n_channels) / n_channels;
if(rendered <= 0)
return nil;
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 {

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>"; };
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; };
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; };
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>"; };
@ -92,6 +93,7 @@
8314D6331A354DFE00EEE8E6 /* sidplay */ = {
isa = PBXGroup;
children = (
834A42A6287AEAAB00EB9D9B /* AudioChunk.h */,
836F5BEA1A357915002730CC /* roms.cpp */,
836F5BEB1A357915002730CC /* roms.hpp */,
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>"; };
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>"; };
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>"; };
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; };
@ -141,6 +142,7 @@
836F705A18BDC40E0095E648 /* VGMDecoder.h */,
836F705B18BDC40E0095E648 /* VGMDecoder.m */,
83AA5D2F1F6E301B0020821C /* Logging.h */,
834A42A8287AEDFB00EB9D9B /* AudioChunk.h */,
836F706018BDC84D0095E648 /* Plugin.h */,
836F6B1A18BDB80D0095E648 /* Supporting Files */,
);

View File

@ -311,10 +311,17 @@ static NSString *get_description_tag(const char *description, const char *tag, c
return @{};
}
- (int)readAudio:(void *)buf frames:(UInt32)frames {
- (AudioChunk *)readAudio {
UInt32 frames = 1024;
UInt32 framesMax = frames;
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) {
BOOL repeatone = IsRepeatOneSet();
@ -354,7 +361,9 @@ static NSString *get_description_tag(const char *description, const char *tag, c
frames -= frames_to_do;
}
return framesDone;
[chunk assignSamples:buffer frameCount:framesDone];
return chunk;
}
- (long)seek:(long)frame {