Compare commits
2 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
e805e4740c | |
|
|
484285df84 |
|
|
@ -27,6 +27,7 @@
|
||||||
A17FFB6318A0028300BAA7FF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A17FFB6218A0028300BAA7FF /* AudioToolbox.framework */; };
|
A17FFB6318A0028300BAA7FF /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A17FFB6218A0028300BAA7FF /* AudioToolbox.framework */; };
|
||||||
A17FFB6918A002E400BAA7FF /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1F5E491189EB3F20070B03F /* AVFoundation.framework */; };
|
A17FFB6918A002E400BAA7FF /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1F5E491189EB3F20070B03F /* AVFoundation.framework */; };
|
||||||
A1EBEE64188DE34500681B04 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */; };
|
A1EBEE64188DE34500681B04 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */; };
|
||||||
|
A1F3410A1908185900CA7755 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1F341091908185900CA7755 /* Accelerate.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
|
@ -65,6 +66,7 @@
|
||||||
A142571C18907861005F0129 /* airplane.aac */ = {isa = PBXFileReference; lastKnownFileType = file; path = airplane.aac; sourceTree = "<group>"; };
|
A142571C18907861005F0129 /* airplane.aac */ = {isa = PBXFileReference; lastKnownFileType = file; path = airplane.aac; sourceTree = "<group>"; };
|
||||||
A17FFB6218A0028300BAA7FF /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
A17FFB6218A0028300BAA7FF /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||||
A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
|
A1EBEE63188DE34500681B04 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; };
|
||||||
|
A1F341091908185900CA7755 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||||
A1F5E48F189EB3CB0070B03F /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
A1F5E48F189EB3CB0070B03F /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
|
||||||
A1F5E491189EB3F20070B03F /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
|
A1F5E491189EB3F20070B03F /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
@ -74,6 +76,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
A1F3410A1908185900CA7755 /* Accelerate.framework in Frameworks */,
|
||||||
A17FFB6918A002E400BAA7FF /* AVFoundation.framework in Frameworks */,
|
A17FFB6918A002E400BAA7FF /* AVFoundation.framework in Frameworks */,
|
||||||
A17FFB6318A0028300BAA7FF /* AudioToolbox.framework in Frameworks */,
|
A17FFB6318A0028300BAA7FF /* AudioToolbox.framework in Frameworks */,
|
||||||
A1EBEE64188DE34500681B04 /* SystemConfiguration.framework in Frameworks */,
|
A1EBEE64188DE34500681B04 /* SystemConfiguration.framework in Frameworks */,
|
||||||
|
|
@ -119,6 +122,7 @@
|
||||||
A1115933188D686000641365 /* Frameworks */ = {
|
A1115933188D686000641365 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A1F341091908185900CA7755 /* Accelerate.framework */,
|
||||||
A17FFB6218A0028300BAA7FF /* AudioToolbox.framework */,
|
A17FFB6218A0028300BAA7FF /* AudioToolbox.framework */,
|
||||||
A1F5E491189EB3F20070B03F /* AVFoundation.framework */,
|
A1F5E491189EB3F20070B03F /* AVFoundation.framework */,
|
||||||
A1F5E48F189EB3CB0070B03F /* AudioUnit.framework */,
|
A1F5E48F189EB3CB0070B03F /* AudioUnit.framework */,
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,9 @@
|
||||||
///
|
///
|
||||||
|
|
||||||
@interface AudioPlayerView()
|
@interface AudioPlayerView()
|
||||||
|
{
|
||||||
|
NSMutableArray* meters;
|
||||||
|
}
|
||||||
-(void) setupTimer;
|
-(void) setupTimer;
|
||||||
-(void) updateControls;
|
-(void) updateControls;
|
||||||
@end
|
@end
|
||||||
|
|
@ -55,6 +58,8 @@
|
||||||
{
|
{
|
||||||
self.audioPlayer = audioPlayerIn;
|
self.audioPlayer = audioPlayerIn;
|
||||||
|
|
||||||
|
self.audioPlayer.spectrumAnalyzerEnabled = YES;
|
||||||
|
|
||||||
CGSize size = CGSizeMake(220, 50);
|
CGSize size = CGSizeMake(220, 50);
|
||||||
|
|
||||||
playFromHTTPButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
playFromHTTPButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||||
|
|
@ -114,9 +119,23 @@
|
||||||
|
|
||||||
statusLabel.textAlignment = NSTextAlignmentCenter;
|
statusLabel.textAlignment = NSTextAlignmentCenter;
|
||||||
|
|
||||||
|
meters = [[NSMutableArray alloc] init];
|
||||||
|
|
||||||
meter = [[UIView alloc] initWithFrame:CGRectMake(0, 450, 0, 20)];
|
meter = [[UIView alloc] initWithFrame:CGRectMake(0, 450, 0, 20)];
|
||||||
|
|
||||||
meter.backgroundColor = [UIColor greenColor];
|
meter.backgroundColor = [UIColor greenColor];
|
||||||
|
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
UIView* freqMeter = [[UIView alloc] initWithFrame:CGRectMake(i, self.bounds.size.height, 1, 0)];
|
||||||
|
|
||||||
|
freqMeter.backgroundColor = [UIColor blueColor];
|
||||||
|
|
||||||
|
[self addSubview:freqMeter];
|
||||||
|
[meters addObject:freqMeter];
|
||||||
|
|
||||||
|
[self sendSubviewToBack:freqMeter];
|
||||||
|
}
|
||||||
|
|
||||||
[self addSubview:slider];
|
[self addSubview:slider];
|
||||||
[self addSubview:playButton];
|
[self addSubview:playButton];
|
||||||
|
|
@ -193,9 +212,18 @@
|
||||||
|
|
||||||
statusLabel.text = audioPlayer.state == STKAudioPlayerStateBuffering ? @"buffering" : @"";
|
statusLabel.text = audioPlayer.state == STKAudioPlayerStateBuffering ? @"buffering" : @"";
|
||||||
|
|
||||||
CGFloat newWidth = 320 * (([audioPlayer averagePowerInDecibelsForChannel:1] + 60) / 60);
|
CGFloat newWidth = 320 * (([audioPlayer testPowerWithIndex:100] + 96) / 96);
|
||||||
|
|
||||||
meter.frame = CGRectMake(0, 460, newWidth, 20);
|
meter.frame = CGRectMake(0, 460, newWidth, 20);
|
||||||
|
|
||||||
|
for (int i = 0; i < 256; i++)
|
||||||
|
{
|
||||||
|
UIView* freqMeter = [meters objectAtIndex:i];
|
||||||
|
|
||||||
|
CGFloat height = 200 * (([audioPlayer testPowerWithIndex:i] + 96) / 96);
|
||||||
|
|
||||||
|
freqMeter.frame = CGRectMake(freqMeter.frame.origin.x, self.bounds.size.height - height, 1, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void) playFromHTTPButtonTouched
|
-(void) playFromHTTPButtonTouched
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@
|
||||||
A1E7C503188D5E550010896F /* STKDataSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FA188D5E550010896F /* STKDataSourceWrapper.m */; };
|
A1E7C503188D5E550010896F /* STKDataSourceWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FA188D5E550010896F /* STKDataSourceWrapper.m */; };
|
||||||
A1E7C504188D5E550010896F /* STKHTTPDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FC188D5E550010896F /* STKHTTPDataSource.m */; };
|
A1E7C504188D5E550010896F /* STKHTTPDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FC188D5E550010896F /* STKHTTPDataSource.m */; };
|
||||||
A1E7C505188D5E550010896F /* STKLocalFileDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */; };
|
A1E7C505188D5E550010896F /* STKLocalFileDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */; };
|
||||||
|
A1F341041908183300CA7755 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1F341031908183300CA7755 /* Accelerate.framework */; };
|
||||||
|
A1F341081908183A00CA7755 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1F341071908183A00CA7755 /* Accelerate.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
|
@ -125,6 +127,8 @@
|
||||||
A1E7C4FD188D5E550010896F /* STKLocalFileDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKLocalFileDataSource.h; sourceTree = "<group>"; };
|
A1E7C4FD188D5E550010896F /* STKLocalFileDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STKLocalFileDataSource.h; sourceTree = "<group>"; };
|
||||||
A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKLocalFileDataSource.m; sourceTree = "<group>"; };
|
A1E7C4FE188D5E550010896F /* STKLocalFileDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STKLocalFileDataSource.m; sourceTree = "<group>"; };
|
||||||
A1E7C507188D62D20010896F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
A1E7C507188D62D20010896F /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
|
||||||
|
A1F341031908183300CA7755 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
|
||||||
|
A1F341071908183A00CA7755 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/System/Library/Frameworks/Accelerate.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
|
@ -132,6 +136,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
A1F341081908183A00CA7755 /* Accelerate.framework in Frameworks */,
|
||||||
A1A4996B189E744400E2A2E2 /* Cocoa.framework in Frameworks */,
|
A1A4996B189E744400E2A2E2 /* Cocoa.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|
@ -150,6 +155,7 @@
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
A1F341041908183300CA7755 /* Accelerate.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|
@ -248,6 +254,8 @@
|
||||||
A1E7C4CA188D57F50010896F /* Frameworks */ = {
|
A1E7C4CA188D57F50010896F /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
A1F341071908183A00CA7755 /* Accelerate.framework */,
|
||||||
|
A1F341031908183300CA7755 /* Accelerate.framework */,
|
||||||
A1A499F6189E79EA00E2A2E2 /* AudioToolbox.framework */,
|
A1A499F6189E79EA00E2A2E2 /* AudioToolbox.framework */,
|
||||||
A1C9767618981BFE0057F881 /* AudioUnit.framework */,
|
A1C9767618981BFE0057F881 /* AudioUnit.framework */,
|
||||||
A1E7C507188D62D20010896F /* UIKit.framework */,
|
A1E7C507188D62D20010896F /* UIKit.framework */,
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,8 @@ typedef void(^STKFrameFilter)(UInt32 channelsPerFrame, UInt32 bytesPerFrame, UIn
|
||||||
@property (readwrite) BOOL meteringEnabled;
|
@property (readwrite) BOOL meteringEnabled;
|
||||||
/// Enables or disables the EQ
|
/// Enables or disables the EQ
|
||||||
@property (readwrite) BOOL equalizerEnabled;
|
@property (readwrite) BOOL equalizerEnabled;
|
||||||
|
/// Enables or disables the spectrum analyzer (fft)
|
||||||
|
@property (readwrite) BOOL spectrumAnalyzerEnabled;
|
||||||
/// Returns an array of STKFrameFilterEntry objects representing the filters currently in use
|
/// Returns an array of STKFrameFilterEntry objects representing the filters currently in use
|
||||||
@property (readonly) NSArray* frameFilters;
|
@property (readonly) NSArray* frameFilters;
|
||||||
/// Returns the items pending to be played (includes buffering and upcoming items but does not include the current item)
|
/// Returns the items pending to be played (includes buffering and upcoming items but does not include the current item)
|
||||||
|
|
@ -263,4 +265,6 @@ typedef void(^STKFrameFilter)(UInt32 channelsPerFrame, UInt32 bytesPerFrame, UIn
|
||||||
/// Sets the gain value (from -96 low to +24 high) for an equalizer band (0 based index)
|
/// Sets the gain value (from -96 low to +24 high) for an equalizer band (0 based index)
|
||||||
-(void) setGain:(float)gain forEqualizerBand:(int)bandIndex;
|
-(void) setGain:(float)gain forEqualizerBand:(int)bandIndex;
|
||||||
|
|
||||||
|
-(float) testPowerWithIndex:(int)index;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@
|
||||||
#import "STKQueueEntry.h"
|
#import "STKQueueEntry.h"
|
||||||
#import "NSMutableArray+STKAudioPlayer.h"
|
#import "NSMutableArray+STKAudioPlayer.h"
|
||||||
#import "libkern/OSAtomic.h"
|
#import "libkern/OSAtomic.h"
|
||||||
|
#include <Accelerate/Accelerate.h>
|
||||||
#import <float.h>
|
#import <float.h>
|
||||||
|
|
||||||
#ifndef DBL_MAX
|
#ifndef DBL_MAX
|
||||||
|
|
@ -189,6 +190,7 @@ static AudioStreamBasicDescription canonicalAudioStreamBasicDescription;
|
||||||
BOOL meteringEnabled;
|
BOOL meteringEnabled;
|
||||||
BOOL equalizerOn;
|
BOOL equalizerOn;
|
||||||
BOOL equalizerEnabled;
|
BOOL equalizerEnabled;
|
||||||
|
BOOL spectrumAnalyzerEnabled;
|
||||||
STKAudioPlayerOptions options;
|
STKAudioPlayerOptions options;
|
||||||
|
|
||||||
NSMutableArray* converterNodes;
|
NSMutableArray* converterNodes;
|
||||||
|
|
@ -253,6 +255,14 @@ static AudioStreamBasicDescription canonicalAudioStreamBasicDescription;
|
||||||
pthread_mutex_t mainThreadSyncCallMutex;
|
pthread_mutex_t mainThreadSyncCallMutex;
|
||||||
pthread_cond_t mainThreadSyncCallReadyCondition;
|
pthread_cond_t mainThreadSyncCallReadyCondition;
|
||||||
|
|
||||||
|
float* window;
|
||||||
|
float* obtainedReal;
|
||||||
|
float* originalReal;
|
||||||
|
int fftStride;
|
||||||
|
|
||||||
|
FFTSetup setupReal;
|
||||||
|
DSPSplitComplex fftInput;
|
||||||
|
|
||||||
volatile BOOL waiting;
|
volatile BOOL waiting;
|
||||||
volatile double requestedSeekTime;
|
volatile double requestedSeekTime;
|
||||||
volatile BOOL disposeWasRequested;
|
volatile BOOL disposeWasRequested;
|
||||||
|
|
@ -470,6 +480,7 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn
|
||||||
|
|
||||||
self->volume = 1.0;
|
self->volume = 1.0;
|
||||||
self->equalizerEnabled = optionsIn.equalizerBandFrequencies[0] != 0;
|
self->equalizerEnabled = optionsIn.equalizerBandFrequencies[0] != 0;
|
||||||
|
self->spectrumAnalyzerEnabled = NO;
|
||||||
|
|
||||||
PopulateOptionsWithDefault(&options);
|
PopulateOptionsWithDefault(&options);
|
||||||
|
|
||||||
|
|
@ -578,6 +589,9 @@ static void AudioFileStreamPacketsProc(void* clientData, UInt32 numberBytes, UIn
|
||||||
pthread_cond_destroy(&mainThreadSyncCallReadyCondition);
|
pthread_cond_destroy(&mainThreadSyncCallReadyCondition);
|
||||||
|
|
||||||
free(readBuffer);
|
free(readBuffer);
|
||||||
|
free(originalReal);
|
||||||
|
free(obtainedReal);
|
||||||
|
free(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void) startSystemBackgroundTask
|
-(void) startSystemBackgroundTask
|
||||||
|
|
@ -2912,6 +2926,115 @@ static OSStatus OutputRenderCallback(void* inRefCon, AudioUnitRenderActionFlags*
|
||||||
return averagePowerDb[channelNumber];
|
return averagePowerDb[channelNumber];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(BOOL) spectrumAnalyzerEnabled
|
||||||
|
{
|
||||||
|
return self->spectrumAnalyzerEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) setSpectrumAnalyzerEnabled:(BOOL)value
|
||||||
|
{
|
||||||
|
if (self->spectrumAnalyzerEnabled == value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->spectrumAnalyzerEnabled = value;
|
||||||
|
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
[self removeFrameFilterWithName:@"STKSpectrumAnalyzerFilter"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!obtainedReal)
|
||||||
|
{
|
||||||
|
int maxSamples = 4096;
|
||||||
|
int log2n = log2f(maxSamples);
|
||||||
|
int n = 1 << log2n;
|
||||||
|
|
||||||
|
fftStride = 1;
|
||||||
|
int nOver2 = maxSamples / 2;
|
||||||
|
|
||||||
|
fftInput.realp = (float*)calloc(nOver2, sizeof(float));
|
||||||
|
fftInput.imagp =(float*)calloc(nOver2, sizeof(float));
|
||||||
|
|
||||||
|
obtainedReal = (float*)calloc(n, sizeof(float));
|
||||||
|
originalReal = (float*)calloc(n, sizeof(float));
|
||||||
|
window = (float*)calloc(maxSamples, sizeof(float));
|
||||||
|
|
||||||
|
vDSP_blkman_window(window, maxSamples, 0);
|
||||||
|
|
||||||
|
setupReal = vDSP_create_fftsetup(log2n, FFT_RADIX2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[self appendFrameFilterWithName:@"STKSpectrumAnalyzerFilter" block:^(UInt32 channelsPerFrame, UInt32 bytesPerFrame, UInt32 frameCount, void* frames)
|
||||||
|
{
|
||||||
|
int log2n = log2f(frameCount);
|
||||||
|
int n = 1 << log2n;
|
||||||
|
int nOver2 = frameCount / 2;
|
||||||
|
SInt16* samples16 = (SInt16*)frames;
|
||||||
|
SInt32* samples32 = (SInt32*)frames;
|
||||||
|
|
||||||
|
if (bytesPerFrame / channelsPerFrame == 2)
|
||||||
|
{
|
||||||
|
for (int i = 0, j = 0; i < frameCount * channelsPerFrame; i+= channelsPerFrame, j += 2)
|
||||||
|
{
|
||||||
|
originalReal[j] = samples16[i] / 32768.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (bytesPerFrame / channelsPerFrame == 4)
|
||||||
|
{
|
||||||
|
for (int i = 0, j = 0; i < frameCount * channelsPerFrame; i+= channelsPerFrame, j+= 2)
|
||||||
|
{
|
||||||
|
originalReal[j] = samples32[i] / 32768.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vDSP_hann_window(window, n, 0);
|
||||||
|
vDSP_vmul(originalReal, 2, window, 1, originalReal, 2, n);
|
||||||
|
|
||||||
|
vDSP_ctoz((COMPLEX*)originalReal, 2, &fftInput, 1, nOver2);
|
||||||
|
vDSP_fft_zrip(setupReal, &fftInput, fftStride, log2n, FFT_FORWARD);
|
||||||
|
|
||||||
|
float one = 1;
|
||||||
|
|
||||||
|
float scale = (float)1.0 / (2 * n);
|
||||||
|
vDSP_vsmul(fftInput.realp, 1, &scale, fftInput.realp, 1, nOver2);
|
||||||
|
vDSP_vsmul(fftInput.imagp, 1, &scale, fftInput.imagp, 1, nOver2);
|
||||||
|
|
||||||
|
pthread_mutex_lock(&self->playerMutex);
|
||||||
|
|
||||||
|
vDSP_zvmags(&fftInput, 1, obtainedReal, 1, nOver2);
|
||||||
|
vDSP_vdbcon(obtainedReal, 1, &one, obtainedReal, 1, nOver2, 0);
|
||||||
|
|
||||||
|
float vmin = -96;
|
||||||
|
float vmax = 0;
|
||||||
|
|
||||||
|
vDSP_vclip(obtainedReal, 1, &vmin, &vmax, obtainedReal, 1, nOver2);
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&self->playerMutex);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(float) testPowerWithIndex:(int)index
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&self->playerMutex);
|
||||||
|
|
||||||
|
if (!obtainedReal)
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&self->playerMutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float retval = obtainedReal[index];
|
||||||
|
|
||||||
|
pthread_mutex_unlock(&self->playerMutex);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
-(BOOL) meteringEnabled
|
-(BOOL) meteringEnabled
|
||||||
{
|
{
|
||||||
return self->meteringEnabled;
|
return self->meteringEnabled;
|
||||||
|
|
@ -2941,11 +3064,12 @@ static OSStatus OutputRenderCallback(void* inRefCon, AudioUnitRenderActionFlags*
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self->meteringEnabled = value;
|
||||||
|
|
||||||
if (!value)
|
if (!value)
|
||||||
{
|
{
|
||||||
[self removeFrameFilterWithName:@"STKMeteringFilter"];
|
[self removeFrameFilterWithName:@"STKMeteringFilter"];
|
||||||
self->meteringEnabled = NO;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue