FLAC: Move libFLAC decoder to higher priority than any potential system decoder, support arbitrary sample bit depths

CQTexperiment
Christopher Snowhill 2021-12-11 00:22:19 -08:00
parent ed8a5763ab
commit 00f1e0957c
4 changed files with 40 additions and 7 deletions

View File

@ -49,7 +49,7 @@
int bitsPerSample = [[properties objectForKey:@"bitsPerSample"] intValue]; int bitsPerSample = [[properties objectForKey:@"bitsPerSample"] intValue];
int channels = [[properties objectForKey:@"channels"] intValue]; int channels = [[properties objectForKey:@"channels"] intValue];
bytesPerFrame = (bitsPerSample / 8) * channels; bytesPerFrame = ((bitsPerSample + 7) / 8) * channels;
shouldContinue = YES; shouldContinue = YES;
shouldSeek = NO; shouldSeek = NO;
@ -66,7 +66,7 @@
int bitsPerSample = [[properties objectForKey:@"bitsPerSample"] intValue]; int bitsPerSample = [[properties objectForKey:@"bitsPerSample"] intValue];
int channels = [[properties objectForKey:@"channels"] intValue]; int channels = [[properties objectForKey:@"channels"] intValue];
bytesPerFrame = (bitsPerSample / 8) * channels; bytesPerFrame = ((bitsPerSample + 7) / 8) * channels;
[self registerObservers]; [self registerObservers];

View File

@ -42,7 +42,7 @@ AudioStreamBasicDescription propertiesToASBD(NSDictionary *properties)
asbd.mBitsPerChannel = [[properties objectForKey:@"bitsPerSample"] intValue]; asbd.mBitsPerChannel = [[properties objectForKey:@"bitsPerSample"] intValue];
asbd.mChannelsPerFrame = [[properties objectForKey:@"channels"] intValue];; asbd.mChannelsPerFrame = [[properties objectForKey:@"channels"] intValue];;
asbd.mBytesPerFrame = (asbd.mBitsPerChannel/8)*asbd.mChannelsPerFrame; asbd.mBytesPerFrame = ((asbd.mBitsPerChannel+7)/8)*asbd.mChannelsPerFrame;
asbd.mFramesPerPacket = 1; asbd.mFramesPerPacket = 1;
asbd.mBytesPerPacket = asbd.mBytesPerFrame * asbd.mFramesPerPacket; asbd.mBytesPerPacket = asbd.mBytesPerFrame * asbd.mFramesPerPacket;

View File

@ -10,7 +10,7 @@
#import "FLAC/all.h" #import "FLAC/all.h"
#define SAMPLES_PER_WRITE 512 #define SAMPLES_PER_WRITE 512
#define FLAC__MAX_SUPPORTED_CHANNELS 2 #define FLAC__MAX_SUPPORTED_CHANNELS 8
#define SAMPLE_blockBuffer_SIZE ((FLAC__MAX_BLOCK_SIZE + SAMPLES_PER_WRITE) * FLAC__MAX_SUPPORTED_CHANNELS * (24/8)) #define SAMPLE_blockBuffer_SIZE ((FLAC__MAX_BLOCK_SIZE + SAMPLES_PER_WRITE) * FLAC__MAX_SUPPORTED_CHANNELS * (24/8))
#import "Plugin.h" #import "Plugin.h"
@ -30,6 +30,8 @@
float frequency; float frequency;
long totalFrames; long totalFrames;
long fileSize;
BOOL hasStreamInfo; BOOL hasStreamInfo;
} }
@ -39,6 +41,8 @@
- (void)setEndOfStream:(BOOL)eos; - (void)setEndOfStream:(BOOL)eos;
- (BOOL)endOfStream; - (BOOL)endOfStream;
- (void)setSize:(long)size;
- (FLAC__StreamDecoder *)decoder; - (FLAC__StreamDecoder *)decoder;
- (char *)blockBuffer; - (char *)blockBuffer;
- (int)blockBufferFrames; - (int)blockBufferFrames;

View File

@ -140,7 +140,22 @@ FLAC__StreamDecoderWriteStatus WriteCallback(const FLAC__StreamDecoder *decoder,
} }
} }
default: default:
ALog(@"Error, unsupported sample size."); // Time for some nearest byte padding up to 32
alias8 = blockBuffer;
int sampleSize = frame->header.bits_per_sample;
int sampleBit;
for(sample = 0; sample < frame->header.blocksize; ++sample) {
for(channel = 0; channel < frame->header.channels; ++channel) {
int32_t sampleExtended = sampleblockBuffer[channel][sample];
for(sampleBit = sampleSize - 8; sampleBit >= -8; sampleBit -= 8) {
if (sampleBit >= 0)
*alias8++ = (uint8_t)((sampleExtended >> sampleBit) & 0xFF);
else
*alias8++ = (uint8_t)((sampleExtended << -sampleBit) & 0xFF);
}
}
}
break;
} }
[flacDecoder setBlockBufferFrames:frame->header.blocksize]; [flacDecoder setBlockBufferFrames:frame->header.blocksize];
@ -178,6 +193,14 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
- (BOOL)open:(id<CogSource>)s - (BOOL)open:(id<CogSource>)s
{ {
[self setSource:s]; [self setSource:s];
[self setSize:0];
if ([s seekable])
{
[s seek:0 whence:SEEK_END];
[self setSize:[s tell]];
[s seek:0 whence:SEEK_SET];
}
decoder = FLAC__stream_decoder_new(); decoder = FLAC__stream_decoder_new();
if (decoder == NULL) if (decoder == NULL)
@ -208,7 +231,7 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
- (int)readAudio:(void *)buffer frames:(UInt32)frames - (int)readAudio:(void *)buffer frames:(UInt32)frames
{ {
int framesRead = 0; int framesRead = 0;
int bytesPerFrame = (bitsPerSample/8) * channels; int bytesPerFrame = ((bitsPerSample+7)/8) * channels;
while (framesRead < frames) while (framesRead < frames)
{ {
if (blockBufferFrames == 0) if (blockBufferFrames == 0)
@ -309,6 +332,11 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
return endOfStream; return endOfStream;
} }
- (void)setSize:(long)size
{
fileSize = size;
}
- (NSDictionary *)properties - (NSDictionary *)properties
{ {
return [NSDictionary dictionaryWithObjectsAndKeys: return [NSDictionary dictionaryWithObjectsAndKeys:
@ -317,6 +345,7 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
[NSNumber numberWithFloat:frequency],@"sampleRate", [NSNumber numberWithFloat:frequency],@"sampleRate",
[NSNumber numberWithDouble:totalFrames],@"totalFrames", [NSNumber numberWithDouble:totalFrames],@"totalFrames",
[NSNumber numberWithBool:[source seekable]], @"seekable", [NSNumber numberWithBool:[source seekable]], @"seekable",
[NSNumber numberWithInt:fileSize ? (fileSize * 8 / ((totalFrames + (frequency / 2)) / frequency)) / 1000 : 0], @"bitrate",
@"FLAC",@"codec", @"FLAC",@"codec",
@"big",@"endian", @"big",@"endian",
nil]; nil];
@ -334,7 +363,7 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
+ (float)priority + (float)priority
{ {
return 1.0; return 2.0;
} }
@end @end