Audio: Make chunk merging abortable

The merge function should be able to tell when the caller has no audio
left to process, such as on end of stream.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-02-13 13:51:46 -08:00
parent f3132e0061
commit d3778f92fc
3 changed files with 17 additions and 7 deletions

View file

@ -76,8 +76,8 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)peekTimestamp:(nonnull double *)timestamp timeRatio:(nonnull double *)timeRatio; - (BOOL)peekTimestamp:(nonnull double *)timestamp timeRatio:(nonnull double *)timeRatio;
// Helpers // Helpers
- (AudioChunk *)removeAndMergeSamples:(size_t)maxFrameCount; - (AudioChunk *)removeAndMergeSamples:(size_t)maxFrameCount callBlock:(BOOL(NS_NOESCAPE ^ _Nonnull)(void))block;
- (AudioChunk *)removeAndMergeSamplesAsFloat32:(size_t)maxFrameCount; - (AudioChunk *)removeAndMergeSamplesAsFloat32:(size_t)maxFrameCount callBlock:(BOOL(NS_NOESCAPE ^ _Nonnull)(void))block;
@end @end

View file

@ -556,7 +556,7 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
} }
} }
- (AudioChunk *)removeAndMergeSamples:(size_t)maxFrameCount { - (AudioChunk *)removeAndMergeSamples:(size_t)maxFrameCount callBlock:(BOOL(NS_NOESCAPE ^ _Nonnull)(void))block {
if(stopping) { if(stopping) {
return [[AudioChunk alloc] init]; return [[AudioChunk alloc] init];
} }
@ -585,6 +585,9 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
AudioStreamBasicDescription newFormat; AudioStreamBasicDescription newFormat;
uint32_t newChannelConfig; uint32_t newChannelConfig;
if(![self peekFormat:&newFormat channelConfig:&newChannelConfig]) { if(![self peekFormat:&newFormat channelConfig:&newChannelConfig]) {
if(block()) {
break;
}
usleep(500); usleep(500);
continue; continue;
} }
@ -602,6 +605,9 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
chunk = [self removeSamples:maxFrameCount - totalFrameCount]; chunk = [self removeSamples:maxFrameCount - totalFrameCount];
if(!chunk || ![chunk frameCount]) { if(!chunk || ![chunk frameCount]) {
if(block()) {
break;
}
usleep(500); usleep(500);
continue; continue;
} }
@ -627,8 +633,8 @@ static void convert_be_to_le(uint8_t *buffer, size_t bitsPerSample, size_t bytes
return outputChunk; return outputChunk;
} }
- (AudioChunk *)removeAndMergeSamplesAsFloat32:(size_t)maxFrameCount { - (AudioChunk *)removeAndMergeSamplesAsFloat32:(size_t)maxFrameCount callBlock:(BOOL(NS_NOESCAPE ^ _Nonnull)(void))block {
AudioChunk *ret = [self removeAndMergeSamples:maxFrameCount]; AudioChunk *ret = [self removeAndMergeSamples:maxFrameCount callBlock:block];
return [self convertChunk:ret]; return [self convertChunk:ret];
} }

View file

@ -264,7 +264,9 @@
AudioChunk *ret; AudioChunk *ret;
@autoreleasepool { @autoreleasepool {
ret = [[previousNode buffer] removeAndMergeSamples:maxFrames]; ret = [[previousNode buffer] removeAndMergeSamples:maxFrames callBlock:^BOOL{
return [[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES;
}];
} }
if([ret frameCount]) { if([ret frameCount]) {
@ -299,7 +301,9 @@
AudioChunk *ret; AudioChunk *ret;
@autoreleasepool { @autoreleasepool {
ret = [[previousNode buffer] removeAndMergeSamplesAsFloat32:maxFrames]; ret = [[previousNode buffer] removeAndMergeSamplesAsFloat32:maxFrames callBlock:^BOOL{
return [[previousNode buffer] isEmpty] && [previousNode endOfStream] == YES;
}];
} }
if([ret frameCount]) { if([ret frameCount]) {