以数值显示 SPL 级别,而不是改变颜色强度
Posted
技术标签:
【中文标题】以数值显示 SPL 级别,而不是改变颜色强度【英文标题】:Display SPL level in numeric value rather than varying colour intensity 【发布时间】:2017-03-14 02:53:55 【问题描述】:我正在尝试为 ios 中的 uni 项目开发 SPL 计,我一直在关注有关如何获取音频输入和显示输入电平的在线教程,但是本教程将输入显示为不同强度的颜色和也处于 RMS 值,而不是峰值。我发现了与此相关的两个先前的帖子,但是它们的信息量不足以提供帮助,并且作为堆栈溢出的新手,我无法就所提供的答案寻求进一步的支持。
Previous Post 1
Previous Post 2
我一直在关注的项目教程是在 Objective-C 而不是 Swift 中运行的,因为它是一个旧的视频集合,但是它(几乎)可以满足我的需要,所以在我理解之前没有尝试更改为 swift我在做什么以及为什么要这样做。
这是录音和输入电平监控的完整代码:
//Lynda.Com Tutorial Project
#import "ViewController.h"
@import AudioToolbox;
@import AVFoundation;
#define kOutputBus 0
#define kInputBus 1
@interface ViewController ()
@property (nonatomic,weak) IBOutlet UIView *indicatorView;
@end
@implementation ViewController
static AudioComponentInstance audioUnit;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setupAudio];
- (void) setupAudio
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
AudioComponent comp = AudioComponentFindNext(NULL, &desc);
OSStatus status = AudioComponentInstanceNew(comp, &audioUnit);
if (status != noErr)
NSAssert(status == noErr,@"Error");
AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100.00;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 1;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerFrame = audioFormat.mChannelsPerFrame * sizeof(SInt16);
audioFormat.mBytesPerPacket = audioFormat.mFramesPerPacket * audioFormat.mBytesPerFrame;
UInt32 flag = 1;
status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag));
if (status != noErr)
NSAssert(status == noErr,@"Error");
flag = 0;
status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag));
if (status != noErr)
NSAssert(status == noErr,@"Error");
status = AudioUnitSetProperty(audioUnit , kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kInputBus, &audioFormat, sizeof(audioFormat));
if (status != noErr)
NSAssert(status == noErr,@"Error");
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = recordingCallback;
callbackStruct.inputProcRefCon = (__bridge void*)self;
status = AudioUnitSetProperty(audioUnit , kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, kInputBus, &callbackStruct, sizeof(callbackStruct));
if (status != noErr)
NSAssert(status == noErr,@"Error");
status = AudioUnitInitialize(audioUnit);
if (status != noErr)
NSAssert(status == noErr,@"Error");
static OSStatus recordingCallback(
void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData
)
AudioBuffer buffer;
buffer.mNumberChannels = 1;
buffer.mDataByteSize = inNumberFrames * sizeof(SInt16);
buffer.mData = malloc(buffer.mDataByteSize);
AudioBufferList bufferList;
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0] = buffer;
OSStatus status = AudioUnitRender(audioUnit , ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, &bufferList);
if (status != noErr)
printf("Error\n");
return -1;
SInt16 *frameBuffer = buffer.mData;
double totalAmplitude = 0;
for (int i = 0; i < inNumberFrames; i++)
//printf("%i\n",frameBuffer[i]);
totalAmplitude += frameBuffer[i] * frameBuffer[i];
totalAmplitude /= inNumberFrames;
totalAmplitude = sqrt(totalAmplitude);
float alphaFloat = totalAmplitude / (float)SHRT_MAX * 2;
dispatch_async(dispatch_get_main_queue(), ^
ViewController *viewController = (__bridge ViewController*)inRefCon;
viewController.indicatorView.backgroundColor = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:alphaFloat];
);
return noErr;
- (IBAction)recordButtonPressed:(id)sender
NSError *error;
[[AVAudioSession sharedInstance] setActive:YES error:&error];
if (error != nil)
NSAssert(error == nil, @"Error");
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:&error];
if (error != nil)
NSAssert(error == nil, @"Error");
[[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted)
if (granted)
OSStatus status = AudioOutputUnitStart(audioUnit);
if (status != noErr)
NSAssert(status == noErr,@"Error");
else
NSAssert(NO, @"Error");
];
- (IBAction)stopButtonPressed:(id)sender
OSStatus status = AudioOutputUnitStop(audioUnit);
if (status != noErr)
NSAssert(status == noErr,@"Error");
NSError *error;
[[AVAudioSession sharedInstance] setActive:NO error:&error];
if (error != nil)
NSAssert(error == nil, @"Error");
self.indicatorView.backgroundColor = [UIColor clearColor];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
- (void) dealloc
OSStatus status = AudioComponentInstanceDispose(audioUnit);
if (status != noErr)
NSAssert(status == noErr,@"Error");
@end
我需要帮助理解的是,因为我相信这里的这段代码:
dispatch_async(dispatch_get_main_queue(), ^
ViewController *viewController = (__bridge ViewController*)inRefCon;
viewController.indicatorView.backgroundColor = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:alphaFloat];
这是 UIView 被告知显示不同强度的红色的地方,我想要将其更改为不同的数字。
RMS 到 dBSPL 的值不是问题,它在正在运行的应用程序中的红色框的位置显示为不断变化的值,我真的可以通过一些帮助来做,所有帮助都非常感谢提前!
谢谢,
克里斯
【问题讨论】:
【参考方案1】:您要显示的值在变量 alphaFloat 中。你需要给你的 ViewController 添加一个 UILabel 属性,你可以称之为dBSPLView。然后在 viewController.indicatorView.backgroundColor 被改变的地方你会做这样的事情:
viewController.dBSPLView.text = [NSString stringWithFormat:@"%f", alphaFloat];
【讨论】:
以上是关于以数值显示 SPL 级别,而不是改变颜色强度的主要内容,如果未能解决你的问题,请参考以下文章
#003366;#FFFFFF;#000000请问以上这些颜色代码,的含义?
如何改变 Qcustomplot 中曲线颜色相对于 x 轴的强度?