iOS 내에서 uni 프로젝트 용 SPL 미터를 개발하려고하고 있는데, 오디오 입력을 받고 입력 레벨을 표시하는 방법에 대한 온라인 자습서를 따라 왔습니다. 튜토리얼에서는 입력 값을 다양한 색상의 강도로 표시하고 피크가 아닌 RMS 값으로 표시합니다. 나는 이것에 관련된 두 개의 이전 게시물을 찾았지만 도움이 될만한 정보는 아니며 오버플로 스택에 초보자가되어 제공된 답변에 대한 추가 지원을 요청할 수 없습니다.다양한 컬러 강도 대신 숫자 값으로 SPL 레벨을 표시합니다.
나는 그것이 오래된 비디오 모음으로 오브젝티브 C보다는 스위프트에서 실행되는 다음 한 프로젝트 튜토리얼 그러나 내가이 정도에 필요 (거의) 무엇을 내가하고있는 일과 내가하는 일을 이해할 때까지는 신속하게 변하려하지 않았다. 여기
는 녹음 및 입력 레벨 모니터링을위한 전체 코드입니다 ://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에 다양한 강도의 빨간색을 표시하라는 메시지가 표시되는 경우이를 원하는 숫자로 변경해야합니다.
dBSPL 값에 대한 RMS는 문제가 아니며 실행중인 응용 프로그램 내에서 빨간색 상자 대신 지속적으로 값이 변하는 것으로 표시되어 모든 도움이 정말 도움이 될 수 있습니다. 전진!
감사합니다,
크리스
이렇게 트릭을 만들었습니다. 정말 고마워요! – ChrisBearBaker