Compare commits

..

4 commits

Author SHA1 Message Date
Christopher Snowhill
6b23590ac8 Play Control: Previous track now also restarts
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
If the current track has played for more than 5 seconds, previous track
now restarts the current track, instead of jumping back to the previous
track.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-26 20:10:18 -07:00
Christopher Snowhill
2282538c42 Bug Fix: Fix inserting empty chunks on track ends
This code did not check the number of samples in a packet before adding
it to the output buffer, which apparently had the potential to cause the
output code to emit up to 512 samples of silence between tracks. This,
as one can guess, is a bad thing, and causes noticeable gapping between
tracks.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-26 20:10:13 -07:00
Christopher Snowhill
73951d6fe7 Bug Fix: Fix output logging, switch log method
Output logging, a debugging feature that is only enabled at build time
if I need to chase down some audio mixing or output bug, was not logging
anything at all. Change to use Cocoa file writing methods, and actually
implement the output writer function again.

This code is left disabled 99% of the time anyway, and especially in
release builds. Like the node logging code elsewhere, it has the
potential to be very noisy and consume massive amounts of disk space.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-26 20:10:08 -07:00
Christopher Snowhill
8c019c7302 Bug Fix: Include soxr latency in memory allocation
This should be included, for safety purposes, in case the rounding up to
the nearest multiple of 256 samples doesn't bump the buffer size enough.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-03-26 20:10:03 -07:00
4 changed files with 21 additions and 13 deletions

View file

@ -356,8 +356,12 @@ NSDictionary *makeRGInfo(PlaylistEntry *pe) {
} }
- (IBAction)prev:(id)sender { - (IBAction)prev:(id)sender {
double pos = [audioPlayer amountPlayed];
if(pos < 5.0) {
if([playlistController prev] == NO) if([playlistController prev] == NO)
return; return;
}
[self playEntry:[playlistController currentEntry]]; [self playEntry:[playlistController currentEntry]];
} }

View file

@ -269,6 +269,7 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
size_t inputSamples = ioNumberPackets / floatFormat.mBytesPerPacket; size_t inputSamples = ioNumberPackets / floatFormat.mBytesPerPacket;
ioNumberPackets = (UInt32)inputSamples; ioNumberPackets = (UInt32)inputSamples;
ioNumberPackets = (UInt32)ceil((float)ioNumberPackets * sampleRatio); ioNumberPackets = (UInt32)ceil((float)ioNumberPackets * sampleRatio);
ioNumberPackets += soxr_delay(soxr);
ioNumberPackets = (ioNumberPackets + 255) & ~255; ioNumberPackets = (ioNumberPackets + 255) & ~255;
size_t newSize = ioNumberPackets * floatFormat.mBytesPerPacket; size_t newSize = ioNumberPackets * floatFormat.mBytesPerPacket;
@ -285,7 +286,6 @@ void scale_by_volume(float *buffer, size_t count, float volume) {
size_t outputDone = 0; size_t outputDone = 0;
if(!skipResampler) { if(!skipResampler) {
ioNumberPackets += soxr_delay(soxr);
soxr_process(soxr, (float *)(((uint8_t *)inputBuffer) + inpOffset), inputSamples, &inputDone, floatBuffer, ioNumberPackets, &outputDone); soxr_process(soxr, (float *)(((uint8_t *)inputBuffer) + inpOffset), inputSamples, &inputDone, floatBuffer, ioNumberPackets, &outputDone);
if(latencyEatenPost) { if(latencyEatenPost) {

View file

@ -28,9 +28,6 @@ using std::atomic_long;
#import <CogAudio/HeadphoneFilter.h> #import <CogAudio/HeadphoneFilter.h>
//#define OUTPUT_LOG //#define OUTPUT_LOG
#ifdef OUTPUT_LOG
#import <stdio.h>
#endif
@class OutputNode; @class OutputNode;
@ -102,7 +99,7 @@ using std::atomic_long;
ChunkList *outputBuffer; ChunkList *outputBuffer;
#ifdef OUTPUT_LOG #ifdef OUTPUT_LOG
FILE *_logFile; NSFileHandle *_logFile;
#endif #endif
} }

View file

@ -19,6 +19,10 @@
#import <CogAudio/VisualizationController.h> #import <CogAudio/VisualizationController.h>
#ifdef OUTPUT_LOG
#import <NSFileHandle+CreateFile.h>
#endif
extern void scale_by_volume(float *buffer, size_t count, float volume); extern void scale_by_volume(float *buffer, size_t count, float volume);
static NSString *CogPlaybackDidBeginNotificiation = @"CogPlaybackDidBeginNotificiation"; static NSString *CogPlaybackDidBeginNotificiation = @"CogPlaybackDidBeginNotificiation";
@ -146,7 +150,7 @@ static void *kOutputCoreAudioContext = &kOutputCoreAudioContext;
#ifdef OUTPUT_LOG #ifdef OUTPUT_LOG
NSString *logName = [NSTemporaryDirectory() stringByAppendingPathComponent:@"CogAudioLog.raw"]; NSString *logName = [NSTemporaryDirectory() stringByAppendingPathComponent:@"CogAudioLog.raw"];
_logFile = fopen([logName UTF8String], "wb"); _logFile = [NSFileHandle fileHandleForWritingAtPath:logName createFile:YES];
#endif #endif
} }
@ -621,9 +625,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
AudioChunk *chunk = [self renderInput:512]; AudioChunk *chunk = [self renderInput:512];
size_t frameCount = 0; size_t frameCount = 0;
if(chunk) { if(chunk && (frameCount = [chunk frameCount])) {
frameCount = [chunk frameCount];
[outputLock lock]; [outputLock lock];
[outputBuffer addChunk:chunk]; [outputBuffer addChunk:chunk];
[outputLock unlock]; [outputLock unlock];
@ -648,7 +650,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
__block NSMutableArray *faders = self->fadedBuffers; __block NSMutableArray *faders = self->fadedBuffers;
#ifdef OUTPUT_LOG #ifdef OUTPUT_LOG
__block FILE *logFile = _logFile; __block NSFileHandle *logFile = _logFile;
#endif #endif
_au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags *_Nonnull actionFlags, const AudioTimeStamp *_Nonnull timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList *_Nonnull inputData) { _au.outputProvider = ^AUAudioUnitStatus(AudioUnitRenderActionFlags *_Nonnull actionFlags, const AudioTimeStamp *_Nonnull timestamp, AUAudioFrameCount frameCount, NSInteger inputBusNumber, AudioBufferList *_Nonnull inputData) {
@ -742,6 +744,11 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
scale_by_volume(outSamples, frameCount * channels, volumeScale * _self->volume); scale_by_volume(outSamples, frameCount * channels, volumeScale * _self->volume);
[_self updateLatency:secondsRendered]; [_self updateLatency:secondsRendered];
#ifdef OUTPUT_LOG
NSData *outData = [NSData dataWithBytes:outSamples length:frameCount * format->mBytesPerPacket];
[logFile writeData:outData];
#endif
} }
#ifdef _DEBUG #ifdef _DEBUG
@ -924,7 +931,7 @@ current_device_listener(AudioObjectID inObjectID, UInt32 inNumberAddresses, cons
} }
#ifdef OUTPUT_LOG #ifdef OUTPUT_LOG
if(_logFile) { if(_logFile) {
fclose(_logFile); [_logFile closeFile];
_logFile = NULL; _logFile = NULL;
} }
#endif #endif