Updated WavPack decoder with hybrid correction file support.

CQTexperiment
Christopher Snowhill 2016-11-03 22:43:37 -07:00
parent 5a3e8005ea
commit 7d806ce452
2 changed files with 74 additions and 39 deletions

View File

@ -13,12 +13,25 @@
#import <WavPack/wavpack.h> #import <WavPack/wavpack.h>
@interface WavPackReader : NSObject
{
id<CogSource> source;
}
- (id)initWithSource:(id<CogSource>)s;
- (void)setSource:(id<CogSource>)s;
- (id<CogSource>)source;
@end
@interface WavPackDecoder : NSObject <CogDecoder> @interface WavPackDecoder : NSObject <CogDecoder>
{ {
WavpackContext *wpc; WavpackContext *wpc;
WavpackStreamReader reader; WavpackStreamReader reader;
id<CogSource> source; WavPackReader *wv;
WavPackReader *wvc;
int bitsPerSample; int bitsPerSample;
int channels; int channels;
@ -28,7 +41,4 @@
long totalFrames; long totalFrames;
} }
- (void)setSource:(id<CogSource>)s;
- (id<CogSource>)source;
@end @end

View File

@ -10,42 +10,64 @@
#import "Logging.h" #import "Logging.h"
@implementation WavPackReader
- (id)initWithSource:(id<CogSource>)s
{
self = [super init];
if (self)
{
source = s;
}
return self;
}
- (void)setSource:(id<CogSource>)s
{
source = s;
}
- (id<CogSource>)source
{
return source;
}
@end
@implementation WavPackDecoder @implementation WavPackDecoder
int32_t ReadBytesProc(void *ds, void *data, int32_t bcount) int32_t ReadBytesProc(void *ds, void *data, int32_t bcount)
{ {
WavPackDecoder *decoder = (__bridge WavPackDecoder *)ds; WavPackReader *wv = (__bridge WavPackReader *)ds;
return (int32_t) [[decoder source] read:data amount:bcount]; return (int32_t) [[wv source] read:data amount:bcount];
} }
uint32_t GetPosProc(void *ds) uint32_t GetPosProc(void *ds)
{ {
WavPackDecoder *decoder = (__bridge WavPackDecoder *)ds; WavPackReader *wv = (__bridge WavPackReader *)ds;
return (uint32_t) [[decoder source] tell]; return (uint32_t) [[wv source] tell];
} }
int SetPosAbsProc(void *ds, uint32_t pos) int SetPosAbsProc(void *ds, uint32_t pos)
{ {
WavPackDecoder *decoder = (__bridge WavPackDecoder *)ds; WavPackReader *wv = (__bridge WavPackReader *)ds;
return ([[decoder source] seek:pos whence:SEEK_SET] ? 0: -1); return ([[wv source] seek:pos whence:SEEK_SET] ? 0: -1);
} }
int SetPosRelProc(void *ds, int32_t delta, int mode) int SetPosRelProc(void *ds, int32_t delta, int mode)
{ {
WavPackDecoder *decoder = (__bridge WavPackDecoder *)ds; WavPackReader *wv = (__bridge WavPackReader *)ds;
return ([[decoder source] seek:delta whence:mode] ? 0: -1); return ([[wv source] seek:delta whence:mode] ? 0: -1);
} }
int PushBackByteProc(void *ds, int c) int PushBackByteProc(void *ds, int c)
{ {
WavPackDecoder *decoder = (__bridge WavPackDecoder *)ds; WavPackReader *wv = (__bridge WavPackReader *)ds;
if ([[decoder source] seekable]) { if ([[wv source] seekable]) {
[[decoder source] seek:-1 whence:SEEK_CUR]; [[wv source] seek:-1 whence:SEEK_CUR];
return c; return c;
} }
@ -56,15 +78,15 @@ int PushBackByteProc(void *ds, int c)
uint32_t GetLengthProc(void *ds) uint32_t GetLengthProc(void *ds)
{ {
WavPackDecoder *decoder = (__bridge WavPackDecoder *)ds; WavPackReader *wv = (__bridge WavPackReader *)ds;
if ([[decoder source] seekable]) { if ([[wv source] seekable]) {
long currentPos = [[decoder source] tell]; long currentPos = [[wv source] tell];
[[decoder source] seek:0 whence:SEEK_END]; [[wv source] seek:0 whence:SEEK_END];
long size = [[decoder source] tell]; long size = [[wv source] tell];
[[decoder source] seek:currentPos whence:SEEK_SET]; [[wv source] seek:currentPos whence:SEEK_SET];
return (uint32_t) size; return (uint32_t) size;
} }
@ -75,9 +97,9 @@ uint32_t GetLengthProc(void *ds)
int CanSeekProc(void *ds) int CanSeekProc(void *ds)
{ {
WavPackDecoder *decoder = (__bridge WavPackDecoder *)ds; WavPackReader *wv = (__bridge WavPackReader *)ds;
return [[decoder source] seekable]; return [[wv source] seekable];
} }
int32_t WriteBytesProc(void *ds, void *data, int32_t bcount) int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
@ -99,9 +121,22 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
{ {
int open_flags = 0; int open_flags = 0;
char error[80]; char error[80];
[self setSource:s];
wv = [[WavPackReader alloc] initWithSource:s];
id audioSourceClass = NSClassFromString(@"AudioSource");
NSURL *wvcurl = [[s url] URLByDeletingPathExtension];
wvcurl = [wvcurl URLByAppendingPathExtension:@"wvc"];
id<CogSource> wvcsrc = [audioSourceClass audioSourceForURL:wvcurl];
if ([wvcsrc open:wvcurl])
{
wvc = [[WavPackReader alloc] initWithSource:wvcsrc];
}
else
{
wvc = nil;
}
reader.read_bytes = ReadBytesProc; reader.read_bytes = ReadBytesProc;
reader.get_pos = GetPosProc; reader.get_pos = GetPosProc;
reader.set_pos_abs = SetPosAbsProc; reader.set_pos_abs = SetPosAbsProc;
@ -113,8 +148,7 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
open_flags |= OPEN_DSD_AS_PCM | OPEN_ALT_TYPES; open_flags |= OPEN_DSD_AS_PCM | OPEN_ALT_TYPES;
//No corrections file (WVC) support at the moment. wpc = WavpackOpenFileInputEx(&reader, (__bridge void *)(wv), (__bridge void *)(wvc), error, open_flags, 0);
wpc = WavpackOpenFileInputEx(&reader, (__bridge void *)(self), NULL, error, open_flags, 0);
if (!wpc) { if (!wpc) {
DLog(@"Unable to open file.."); DLog(@"Unable to open file..");
return NO; return NO;
@ -227,7 +261,8 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
WavpackCloseFile(wpc); WavpackCloseFile(wpc);
wpc = NULL; wpc = NULL;
} }
source = nil; wvc = nil;
wv = nil;
} }
- (void)dealloc - (void)dealloc
@ -235,16 +270,6 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
[self close]; [self close];
} }
- (void)setSource:(id<CogSource>)s
{
source = s;
}
- (id<CogSource>)source
{
return source;
}
- (NSDictionary *)properties - (NSDictionary *)properties
{ {
return [NSDictionary dictionaryWithObjectsAndKeys: return [NSDictionary dictionaryWithObjectsAndKeys:
@ -254,7 +279,7 @@ int32_t WriteBytesProc(void *ds, void *data, int32_t bcount)
[NSNumber numberWithFloat:frequency],@"sampleRate", [NSNumber numberWithFloat:frequency],@"sampleRate",
[NSNumber numberWithBool:floatingPoint],@"floatingPoint", [NSNumber numberWithBool:floatingPoint],@"floatingPoint",
[NSNumber numberWithDouble:totalFrames],@"totalFrames", [NSNumber numberWithDouble:totalFrames],@"totalFrames",
[NSNumber numberWithBool:[source seekable]], @"seekable", [NSNumber numberWithBool:[[wv source] seekable]], @"seekable",
@"little",@"endian", @"little",@"endian",
nil]; nil];
} }