Move most large stack using buffers to the heap
This should solve most potential future stack overflows. Signed-off-by: Christopher Snowhill <kode54@gmail.com>xcode15
parent
e330c64f43
commit
c612994cb2
|
@ -20,6 +20,7 @@
|
||||||
double srate;
|
double srate;
|
||||||
uint32_t channelCount;
|
uint32_t channelCount;
|
||||||
uint32_t channelConfig;
|
uint32_t channelConfig;
|
||||||
|
float tempBuffer[4096 * 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithSampleRate:(double)srate;
|
- (id)initWithSampleRate:(double)srate;
|
||||||
|
|
|
@ -129,7 +129,6 @@ struct freesurround_params {
|
||||||
freesurround_params *_params = (freesurround_params *)params;
|
freesurround_params *_params = (freesurround_params *)params;
|
||||||
freesurround_decoder *_decoder = (freesurround_decoder *)decoder;
|
freesurround_decoder *_decoder = (freesurround_decoder *)decoder;
|
||||||
|
|
||||||
float tempInput[4096 * 2];
|
|
||||||
uint32_t zeroCount = 0;
|
uint32_t zeroCount = 0;
|
||||||
|
|
||||||
if(count > 4096) {
|
if(count > 4096) {
|
||||||
|
@ -138,9 +137,9 @@ struct freesurround_params {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(count < 4096) {
|
if(count < 4096) {
|
||||||
cblas_scopy(count * 2, samplesIn, 1, &tempInput[0], 1);
|
cblas_scopy(count * 2, samplesIn, 1, &tempBuffer[0], 1);
|
||||||
vDSP_vclr(&tempInput[count * 2], 1, (4096 - count) * 2);
|
vDSP_vclr(&tempBuffer[count * 2], 1, (4096 - count) * 2);
|
||||||
samplesIn = &tempInput[0];
|
samplesIn = &tempBuffer[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
float *src = _decoder->decode(samplesIn);
|
float *src = _decoder->decode(samplesIn);
|
||||||
|
|
|
@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
double latency;
|
double latency;
|
||||||
float *visAudio;
|
float *visAudio;
|
||||||
int visAudioCursor, visAudioSize;
|
int visAudioCursor, visAudioSize;
|
||||||
|
float *visAudioTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (VisualizationController *)sharedController;
|
+ (VisualizationController *)sharedController;
|
||||||
|
|
|
@ -28,6 +28,10 @@ static VisualizationController *_sharedController = nil;
|
||||||
if(self) {
|
if(self) {
|
||||||
visAudio = NULL;
|
visAudio = NULL;
|
||||||
latency = 0;
|
latency = 0;
|
||||||
|
visAudioTemp = (float *) calloc(sizeof(float), 4096);
|
||||||
|
if(!visAudioTemp) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -89,8 +93,7 @@ static VisualizationController *_sharedController = nil;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float tempPCM[4096];
|
if(!outPCM) outPCM = &visAudioTemp[0];
|
||||||
if(!outPCM) outPCM = &tempPCM[0];
|
|
||||||
|
|
||||||
@synchronized(self) {
|
@synchronized(self) {
|
||||||
if(!sampleRate) {
|
if(!sampleRate) {
|
||||||
|
|
|
@ -30,17 +30,19 @@ Unpack::Unpack(ComprDataIO *DataIO)
|
||||||
|
|
||||||
void Unpack::init_tables()
|
void Unpack::init_tables()
|
||||||
{
|
{
|
||||||
ComprDataIO IOTemp;
|
ComprDataIO *IOTemp = new ComprDataIO;
|
||||||
Unpack Temp(&IOTemp);
|
Unpack *Temp = new Unpack(IOTemp);
|
||||||
// Perform initialization, which should be done only once for all files.
|
// Perform initialization, which should be done only once for all files.
|
||||||
// It prevents crash if first DoUnpack call is later made with wrong
|
// It prevents crash if first DoUnpack call is later made with wrong
|
||||||
// (true) 'Solid' value.
|
// (true) 'Solid' value.
|
||||||
Temp.UnpInitData(false);
|
Temp->UnpInitData(false);
|
||||||
#ifndef SFX_MODULE
|
#ifndef SFX_MODULE
|
||||||
// RAR 1.5 decompression initialization
|
// RAR 1.5 decompression initialization
|
||||||
Temp.UnpInitData15(false);
|
Temp->UnpInitData15(false);
|
||||||
Temp.InitHuff();
|
Temp->InitHuff();
|
||||||
#endif
|
#endif
|
||||||
|
delete Temp;
|
||||||
|
delete IOTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@ extern gme_err_t readCallback(void* data, void* out, int count);
|
||||||
long length;
|
long length;
|
||||||
long fade;
|
long fade;
|
||||||
NSString* codec;
|
NSString* codec;
|
||||||
|
|
||||||
|
int16_t sampleBuffer[1024 * 2];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setSource:(id<CogSource>)s;
|
- (void)setSource:(id<CogSource>)s;
|
||||||
|
|
|
@ -176,8 +176,7 @@ gme_err_t readCallback(void *data, void *out, int count) {
|
||||||
|
|
||||||
- (AudioChunk *)readAudio {
|
- (AudioChunk *)readAudio {
|
||||||
int frames = 1024;
|
int frames = 1024;
|
||||||
int16_t buffer[frames * 2];
|
void *buf = (void *)sampleBuffer;
|
||||||
void *buf = (void *)buffer;
|
|
||||||
|
|
||||||
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
||||||
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
||||||
|
@ -199,7 +198,7 @@ gme_err_t readCallback(void *data, void *out, int count) {
|
||||||
//(From gme.txt) If track length, then use it. If loop length, play for intro + loop * 2. Otherwise, default to 2.5 minutes
|
//(From gme.txt) If track length, then use it. If loop length, play for intro + loop * 2. Otherwise, default to 2.5 minutes
|
||||||
// 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];
|
[chunk assignSamples:sampleBuffer frameCount:numSamples];
|
||||||
|
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,5 +24,7 @@
|
||||||
long framesFade;
|
long framesFade;
|
||||||
long framesRead;
|
long framesRead;
|
||||||
long framesInBuffer;
|
long framesInBuffer;
|
||||||
|
|
||||||
|
float sampleBuffer[1024 * 2];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#import "PlaylistController.h"
|
#import "PlaylistController.h"
|
||||||
|
|
||||||
|
#import <Accelerate/Accelerate.h>
|
||||||
|
|
||||||
static void oneTimeInit(void) {
|
static void oneTimeInit(void) {
|
||||||
static BOOL initialized = NO;
|
static BOOL initialized = NO;
|
||||||
if(!initialized) {
|
if(!initialized) {
|
||||||
|
@ -109,8 +111,7 @@ static void oneTimeInit(void) {
|
||||||
|
|
||||||
- (AudioChunk *)readAudio {
|
- (AudioChunk *)readAudio {
|
||||||
int frames = 1024;
|
int frames = 1024;
|
||||||
float buffer[frames * 2];
|
void *buf = (void *)sampleBuffer;
|
||||||
void *buf = (void *)buffer;
|
|
||||||
|
|
||||||
BOOL repeatone = IsRepeatOneSet();
|
BOOL repeatone = IsRepeatOneSet();
|
||||||
|
|
||||||
|
@ -124,11 +125,9 @@ static void oneTimeInit(void) {
|
||||||
int framesToCopy = frames - total;
|
int framesToCopy = frames - total;
|
||||||
if(framesToCopy > framesInBuffer)
|
if(framesToCopy > framesInBuffer)
|
||||||
framesToCopy = (int)framesInBuffer;
|
framesToCopy = (int)framesInBuffer;
|
||||||
for(int i = 0; i < framesToCopy; ++i) {
|
vDSP_vflt32(&buffer[0], 1, &outbuffer[0], 1, framesToCopy * 2);
|
||||||
outbuffer[0] = buffer[i * 2 + 0] * (1.0f / 16777216.0f);
|
float scale = 16777216.0f;
|
||||||
outbuffer[1] = buffer[i * 2 + 1] * (1.0f / 16777216.0f);
|
vDSP_vsdiv(&outbuffer[0], 1, &scale, &outbuffer[0], 1, framesToCopy * 2);
|
||||||
outbuffer += 2;
|
|
||||||
}
|
|
||||||
framesInBuffer -= framesToCopy;
|
framesInBuffer -= framesToCopy;
|
||||||
total += framesToCopy;
|
total += framesToCopy;
|
||||||
if(framesInBuffer) {
|
if(framesInBuffer) {
|
||||||
|
@ -163,7 +162,7 @@ static void oneTimeInit(void) {
|
||||||
|
|
||||||
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
||||||
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
||||||
[chunk assignSamples:buffer frameCount:total];
|
[chunk assignSamples:sampleBuffer frameCount:total];
|
||||||
|
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,29 +74,36 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)scanFile {
|
- (BOOL)scanFile {
|
||||||
struct mad_stream stream;
|
struct mad_stream *stream;
|
||||||
struct mad_frame frame;
|
struct mad_frame *frame;
|
||||||
|
|
||||||
|
stream = (struct mad_stream *) calloc(sizeof(struct mad_stream), 1);
|
||||||
|
frame = (struct mad_frame *) calloc(sizeof(struct mad_frame), 1);
|
||||||
|
if(!stream || !frame) {
|
||||||
|
ALog(@"Out of memory!");
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
long framesDecoded = 0;
|
long framesDecoded = 0;
|
||||||
int samplesPerMPEGFrame = 0;
|
int samplesPerMPEGFrame = 0;
|
||||||
|
|
||||||
int id3_length = 0;
|
int id3_length = 0;
|
||||||
|
|
||||||
mad_stream_init(&stream);
|
mad_stream_init(stream);
|
||||||
mad_frame_init(&frame);
|
mad_frame_init(frame);
|
||||||
|
|
||||||
[_source seek:0 whence:SEEK_END];
|
[_source seek:0 whence:SEEK_END];
|
||||||
_fileSize = [_source tell];
|
_fileSize = [_source tell];
|
||||||
[_source seek:0 whence:SEEK_SET];
|
[_source seek:0 whence:SEEK_SET];
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
[self bufferRefill:&stream];
|
[self bufferRefill:stream];
|
||||||
|
|
||||||
if(mad_frame_decode(&frame, &stream) == -1) {
|
if(mad_frame_decode(frame, stream) == -1) {
|
||||||
if(MAD_RECOVERABLE(stream.error)) {
|
if(MAD_RECOVERABLE(stream->error)) {
|
||||||
// Prevent ID3 tags from reporting recoverable frame errors
|
// Prevent ID3 tags from reporting recoverable frame errors
|
||||||
const uint8_t *buffer = stream.this_frame;
|
const uint8_t *buffer = stream->this_frame;
|
||||||
unsigned long buflen = stream.bufend - stream.this_frame;
|
unsigned long buflen = stream->bufend - stream->this_frame;
|
||||||
|
|
||||||
if(10 <= buflen && 0x49 == buffer[0] && 0x44 == buffer[1] && 0x33 == buffer[2]) {
|
if(10 <= buflen && 0x49 == buffer[0] && 0x44 == buffer[1] && 0x33 == buffer[2]) {
|
||||||
id3_length = (((buffer[6] & 0x7F) << (3 * 7)) | ((buffer[7] & 0x7F) << (2 * 7)) |
|
id3_length = (((buffer[6] & 0x7F) << (3 * 7)) | ((buffer[7] & 0x7F) << (2 * 7)) |
|
||||||
|
@ -108,7 +115,7 @@
|
||||||
id3_length += 10;
|
id3_length += 10;
|
||||||
|
|
||||||
void *tagBuffer = malloc(id3_length);
|
void *tagBuffer = malloc(id3_length);
|
||||||
if(!tagBuffer) return NO;
|
if(!tagBuffer) goto error;
|
||||||
|
|
||||||
memcpy(tagBuffer, &buffer[0], MIN(buflen, id3_length));
|
memcpy(tagBuffer, &buffer[0], MIN(buflen, id3_length));
|
||||||
|
|
||||||
|
@ -116,18 +123,18 @@
|
||||||
long tagRead = MIN(buflen, id3_length);
|
long tagRead = MIN(buflen, id3_length);
|
||||||
|
|
||||||
while(bufleft > 0) {
|
while(bufleft > 0) {
|
||||||
stream.error = MAD_ERROR_BUFLEN;
|
stream->error = MAD_ERROR_BUFLEN;
|
||||||
stream.next_frame = NULL;
|
stream->next_frame = NULL;
|
||||||
[self bufferRefill:&stream];
|
[self bufferRefill:stream];
|
||||||
buffer = stream.this_frame;
|
buffer = stream->this_frame;
|
||||||
buflen = stream.bufend - stream.this_frame;
|
buflen = stream->bufend - stream->this_frame;
|
||||||
memcpy(tagBuffer + tagRead, buffer, MIN(buflen, bufleft));
|
memcpy(tagBuffer + tagRead, buffer, MIN(buflen, bufleft));
|
||||||
tagRead += MIN(buflen, bufleft);
|
tagRead += MIN(buflen, bufleft);
|
||||||
bufleft -= buflen;
|
bufleft -= buflen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bufleft < 0) {
|
if(bufleft < 0) {
|
||||||
mad_stream_skip(&stream, buflen + bufleft);
|
mad_stream_skip(stream, buflen + bufleft);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct id3_tag *tag = id3_tag_parse(tagBuffer, id3_length);
|
struct id3_tag *tag = id3_tag_parse(tagBuffer, id3_length);
|
||||||
|
@ -180,14 +187,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
free(tagBuffer);
|
free(tagBuffer);
|
||||||
} else if(stream.error == MAD_ERROR_BADDATAPTR) {
|
} else if(stream->error == MAD_ERROR_BADDATAPTR) {
|
||||||
goto framedecoded;
|
goto framedecoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
} else if(stream.error == MAD_ERROR_BUFLEN && inputEOF) {
|
} else if(stream->error == MAD_ERROR_BUFLEN && inputEOF) {
|
||||||
break;
|
break;
|
||||||
} else if(stream.error == MAD_ERROR_BUFLEN) {
|
} else if(stream->error == MAD_ERROR_BUFLEN) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
// DLog(@"Unrecoverable error: %s", mad_stream_errorstr(&stream));
|
// DLog(@"Unrecoverable error: %s", mad_stream_errorstr(&stream));
|
||||||
|
@ -198,11 +205,11 @@
|
||||||
framesDecoded++;
|
framesDecoded++;
|
||||||
|
|
||||||
if(framesDecoded == 1) {
|
if(framesDecoded == 1) {
|
||||||
sampleRate = frame.header.samplerate;
|
sampleRate = frame->header.samplerate;
|
||||||
channels = MAD_NCHANNELS(&frame.header);
|
channels = MAD_NCHANNELS(&frame->header);
|
||||||
|
|
||||||
if(MAD_FLAG_LSF_EXT & frame.header.flags || MAD_FLAG_MPEG_2_5_EXT & frame.header.flags) {
|
if(MAD_FLAG_LSF_EXT & frame->header.flags || MAD_FLAG_MPEG_2_5_EXT & frame->header.flags) {
|
||||||
switch(frame.header.layer) {
|
switch(frame->header.layer) {
|
||||||
case MAD_LAYER_I:
|
case MAD_LAYER_I:
|
||||||
samplesPerMPEGFrame = 384;
|
samplesPerMPEGFrame = 384;
|
||||||
layer = 1;
|
layer = 1;
|
||||||
|
@ -217,7 +224,7 @@
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(frame.header.layer) {
|
switch(frame->header.layer) {
|
||||||
case MAD_LAYER_I:
|
case MAD_LAYER_I:
|
||||||
samplesPerMPEGFrame = 384;
|
samplesPerMPEGFrame = 384;
|
||||||
layer = 1;
|
layer = 1;
|
||||||
|
@ -235,16 +242,16 @@
|
||||||
|
|
||||||
if(layer != 3) continue;
|
if(layer != 3) continue;
|
||||||
|
|
||||||
const size_t ancillaryBitsRemaining = (stream.next_frame - stream.this_frame) * 8;
|
const size_t ancillaryBitsRemaining = (stream->next_frame - stream->this_frame) * 8;
|
||||||
|
|
||||||
static const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
|
static const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
|
||||||
|
|
||||||
const int64_t xing_offset = xing_offtbl[!!(MAD_FLAG_LSF_EXT & frame.header.flags || MAD_FLAG_MPEG_2_5_EXT & frame.header.flags)][channels == 1] + 4; // Plus MPEG header
|
const int64_t xing_offset = xing_offtbl[!!(MAD_FLAG_LSF_EXT & frame->header.flags || MAD_FLAG_MPEG_2_5_EXT & frame->header.flags)][channels == 1] + 4; // Plus MPEG header
|
||||||
|
|
||||||
size_t ancBitsRemainingXing = ancillaryBitsRemaining - xing_offset * 8;
|
size_t ancBitsRemainingXing = ancillaryBitsRemaining - xing_offset * 8;
|
||||||
|
|
||||||
if(ancBitsRemainingXing >= 32) {
|
if(ancBitsRemainingXing >= 32) {
|
||||||
const uint8_t *ptr = stream.this_frame + xing_offset;
|
const uint8_t *ptr = stream->this_frame + xing_offset;
|
||||||
struct mad_bitptr bitptr;
|
struct mad_bitptr bitptr;
|
||||||
|
|
||||||
mad_bit_init(&bitptr, ptr);
|
mad_bit_init(&bitptr, ptr);
|
||||||
|
@ -374,7 +381,7 @@
|
||||||
size_t ancBitsRemainingVBRI = ancillaryBitsRemaining - vbri_offset * 8;
|
size_t ancBitsRemainingVBRI = ancillaryBitsRemaining - vbri_offset * 8;
|
||||||
|
|
||||||
if(ancBitsRemainingVBRI >= 32) {
|
if(ancBitsRemainingVBRI >= 32) {
|
||||||
const uint8_t *ptr = stream.this_frame + vbri_offset;
|
const uint8_t *ptr = stream->this_frame + vbri_offset;
|
||||||
struct mad_bitptr bitptr;
|
struct mad_bitptr bitptr;
|
||||||
mad_bit_init(&bitptr, ptr);
|
mad_bit_init(&bitptr, ptr);
|
||||||
|
|
||||||
|
@ -407,22 +414,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't commit division by zero on bad files
|
// Don't commit division by zero on bad files
|
||||||
if(stream.next_frame == stream.this_frame) {
|
if(stream->next_frame == stream->this_frame) {
|
||||||
return NO;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_foundiTunSMPB && !_foundXingHeader && !_foundVBRIHeader) {
|
if(!_foundiTunSMPB && !_foundXingHeader && !_foundVBRIHeader) {
|
||||||
// Now do CBR estimation instead of full file scanning
|
// Now do CBR estimation instead of full file scanning
|
||||||
size_t frameCount = (_fileSize - id3_length) / (stream.next_frame - stream.this_frame);
|
size_t frameCount = (_fileSize - id3_length) / (stream->next_frame - stream->this_frame);
|
||||||
mad_timer_t duration = frame.header.duration;
|
mad_timer_t duration = frame->header.duration;
|
||||||
mad_timer_multiply(&duration, frameCount);
|
mad_timer_multiply(&duration, frameCount);
|
||||||
totalFrames = mad_timer_count(duration, sampleRate);
|
totalFrames = mad_timer_count(duration, sampleRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
bitrate = ((double)((_fileSize - id3_length) * 8) / 1000.0) * (sampleRate / (double)totalFrames);
|
bitrate = ((double)((_fileSize - id3_length) * 8) / 1000.0) * (sampleRate / (double)totalFrames);
|
||||||
|
|
||||||
mad_frame_finish(&frame);
|
mad_frame_finish(frame);
|
||||||
mad_stream_finish(&stream);
|
mad_stream_finish(stream);
|
||||||
|
|
||||||
|
free(frame);
|
||||||
|
free(stream);
|
||||||
|
|
||||||
[_source seek:0 whence:SEEK_SET];
|
[_source seek:0 whence:SEEK_SET];
|
||||||
inputEOF = NO;
|
inputEOF = NO;
|
||||||
|
@ -430,6 +440,17 @@
|
||||||
DLog(@"Mad properties: %@", [self properties]);
|
DLog(@"Mad properties: %@", [self properties]);
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if(frame) {
|
||||||
|
mad_frame_finish(frame);
|
||||||
|
free(frame);
|
||||||
|
}
|
||||||
|
if(stream) {
|
||||||
|
mad_stream_finish(stream);
|
||||||
|
free(stream);
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)open:(id<CogSource>)source {
|
- (BOOL)open:(id<CogSource>)source {
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
char buffer[MPC_FRAME_LENGTH * 4];
|
char buffer[MPC_FRAME_LENGTH * 4];
|
||||||
int bufferFrames;
|
int bufferFrames;
|
||||||
|
|
||||||
|
MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH];
|
||||||
|
float floatBuffer[1024 * 2];
|
||||||
|
|
||||||
int bitrate;
|
int bitrate;
|
||||||
float frequency;
|
float frequency;
|
||||||
long totalFrames;
|
long totalFrames;
|
||||||
|
|
|
@ -110,11 +110,8 @@ mpc_bool_t CanSeekProc(mpc_reader *p_reader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
- (AudioChunk *)readAudio {
|
- (AudioChunk *)readAudio {
|
||||||
MPC_SAMPLE_FORMAT sampleBuffer[MPC_DECODER_BUFFER_LENGTH];
|
|
||||||
|
|
||||||
int frames = 1024;
|
int frames = 1024;
|
||||||
float buffer[frames * 2];
|
void *buf = (void *)floatBuffer;
|
||||||
void *buf = (void *)buffer;
|
|
||||||
|
|
||||||
int framesRead = 0;
|
int framesRead = 0;
|
||||||
int bytesPerFrame = sizeof(float) * 2; // bitsPerSample == 32, channels == 2
|
int bytesPerFrame = sizeof(float) * 2; // bitsPerSample == 32, channels == 2
|
||||||
|
@ -156,7 +153,7 @@ mpc_bool_t CanSeekProc(mpc_reader *p_reader) {
|
||||||
|
|
||||||
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
||||||
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
||||||
[chunk assignSamples:buffer frameCount:framesRead];
|
[chunk assignSamples:floatBuffer frameCount:framesRead];
|
||||||
|
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
long length;
|
long length;
|
||||||
long remain;
|
long remain;
|
||||||
|
|
||||||
|
float *buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setSource:(id<CogSource>)s;
|
- (void)setSource:(id<CogSource>)s;
|
||||||
|
|
|
@ -28,6 +28,12 @@ enum { channels = 2 };
|
||||||
length = seconds * sample_rate;
|
length = seconds * sample_rate;
|
||||||
remain = length;
|
remain = length;
|
||||||
|
|
||||||
|
buffer = (float *) calloc(sizeof(float), 1024 * channels);
|
||||||
|
if(!buffer) {
|
||||||
|
ALog(@"Out of memory!");
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
[self willChangeValueForKey:@"properties"];
|
[self willChangeValueForKey:@"properties"];
|
||||||
[self didChangeValueForKey:@"properties"];
|
[self didChangeValueForKey:@"properties"];
|
||||||
|
|
||||||
|
@ -52,23 +58,17 @@ enum { channels = 2 };
|
||||||
|
|
||||||
- (AudioChunk *)readAudio {
|
- (AudioChunk *)readAudio {
|
||||||
int frames = 1024;
|
int frames = 1024;
|
||||||
float buffer[frames * channels];
|
|
||||||
void *buf = (void *)buffer;
|
|
||||||
|
|
||||||
int total = frames;
|
|
||||||
|
|
||||||
if(!IsRepeatOneSet()) {
|
if(!IsRepeatOneSet()) {
|
||||||
if(total > remain)
|
if(frames > remain)
|
||||||
total = (int)remain;
|
frames = (int)remain;
|
||||||
|
|
||||||
remain -= total;
|
remain -= frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(buf, 0, sizeof(float) * total * channels);
|
|
||||||
|
|
||||||
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
id audioChunkClass = NSClassFromString(@"AudioChunk");
|
||||||
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
|
||||||
[chunk assignSamples:buffer frameCount:total];
|
[chunk assignSamples:buffer frameCount:frames];
|
||||||
|
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ extern NSString *CogPlaybackDidStopNotficiation;
|
||||||
NSColor *borderColor;
|
NSColor *borderColor;
|
||||||
ddb_analyzer_t _analyzer;
|
ddb_analyzer_t _analyzer;
|
||||||
ddb_analyzer_draw_data_t _draw_data;
|
ddb_analyzer_draw_data_t _draw_data;
|
||||||
|
|
||||||
|
float visAudio[4096], visFFT[2048];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -368,8 +370,6 @@ extern NSString *CogPlaybackDidStopNotficiation;
|
||||||
_analyzer.view_width = self.bounds.size.width;
|
_analyzer.view_width = self.bounds.size.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
float visAudio[4096], visFFT[2048];
|
|
||||||
|
|
||||||
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:0];
|
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:0];
|
||||||
|
|
||||||
ddb_analyzer_process(&_analyzer, [self->visController readSampleRate] / 2.0, 1, visFFT, 2048);
|
ddb_analyzer_process(&_analyzer, [self->visController readSampleRate] / 2.0, 1, visFFT, 2048);
|
||||||
|
|
|
@ -42,6 +42,8 @@ extern NSString *CogPlaybackDidStopNotficiation;
|
||||||
SCNVector3 cameraEulerAngles2d;
|
SCNVector3 cameraEulerAngles2d;
|
||||||
SCNVector3 cameraPosition3d;
|
SCNVector3 cameraPosition3d;
|
||||||
SCNVector3 cameraEulerAngles3d;
|
SCNVector3 cameraEulerAngles3d;
|
||||||
|
|
||||||
|
float visAudio[4096], visFFT[2048];
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -274,8 +276,6 @@ extern NSString *CogPlaybackDidStopNotficiation;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float visAudio[4096], visFFT[2048];
|
|
||||||
|
|
||||||
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:0];
|
[self->visController copyVisPCM:&visAudio[0] visFFT:&visFFT[0] latencyOffset:0];
|
||||||
|
|
||||||
ddb_analyzer_process(&_analyzer, [self->visController readSampleRate] / 2.0, 1, visFFT, 2048);
|
ddb_analyzer_process(&_analyzer, [self->visController readSampleRate] / 2.0, 1, visFFT, 2048);
|
||||||
|
|
Loading…
Reference in New Issue