2011-09-04 241 views
1

我有一个类,将让我使用音频设备播放音,我希望能够做的是有类游戏莫尔斯电码的风格,当我发类短语或字母。在Objective-C生成莫尔斯电码的风格色调

如何,我会去吗?我希望有人能指出我正确的方向。我已经包括音频发生器h和.m文件下面

// 
// Singer.h 
// musiculesdev 
// 
// Created by Dylan on 2/20/09. 
// Copyright 2009 __MyCompanyName__. All rights reserved. 
// 

#import <Foundation/Foundation.h> 
#import <AudioUnit/AudioUnit.h> 



@interface Singer : NSObject { 


    AudioComponentInstance audioUnit; 

} 


-(void)initAudio; // put this in init? 


-(void)start; 
-(void)stop; 
-(IBAction)turnOnSound:(id)sender; 

@end 


// 
// Singer.m 
// musiculesdev 
// 
// Created by Dylan on 2/20/09. 
// Copyright 2009 __MyCompanyName__. All rights reserved. 
// 

#import <AudioUnit/AudioUnit.h> 
#import <math.h> 

#import "Singer.h" 

#define kOutputBus 0 
#define kSampleRate 44100 
//44100.0f 
#define kWaveform (M_PI * 2.0f/kSampleRate) 


@implementation Singer 


OSStatus playbackCallback(void *inRefCon, 
          AudioUnitRenderActionFlags *ioActionFlags, 
          const AudioTimeStamp *inTimeStamp, 
          UInt32 inBusNumber, 
          UInt32 inNumberFrames, 
          AudioBufferList *ioData) {  

    //Singer *me = (Singer *)inRefCon; 

    static int phase = 0; 

    for(UInt32 i = 0; i < ioData->mNumberBuffers; i++) { 

     int samples = ioData->mBuffers[i].mDataByteSize/sizeof(SInt16); 

     SInt16 values[samples]; 

     float waves; 

     for(int j = 0; j < samples; j++) { 


      waves = 0; 


      waves += sin(kWaveform * 261.63f * phase); 
      waves += sin(kWaveform * 120.0f * phase); 
      waves += sin(kWaveform * 1760.3f * phase); 
      waves += sin(kWaveform * 880.0f * phase);    

      waves *= 32500/4; // <--------- make sure to divide by how many waves you're stacking 

      values[j] = (SInt16)waves; 
      values[j] += values[j]<<16; 

      phase++; 

     } 

     memcpy(ioData->mBuffers[i].mData, values, samples * sizeof(SInt16)); 

    } 


    return noErr; 

} 

-(IBAction)turnOnSound:(id)sender { 
    Singer *singer = [[Singer alloc] init]; 

    [singer start]; 
} 


-(id)init { 
    NSLog(@"In the singer init!!"); 
    if(self = [super init]) { 

     [self initAudio]; 

    } 

    return self; 

} 

-(void)initAudio { 

    OSStatus status; 

    AudioComponentDescription desc; 
    desc.componentType = kAudioUnitType_Output; 
    desc.componentSubType = kAudioUnitSubType_RemoteIO; 
    desc.componentFlags = 0; 
    desc.componentFlagsMask = 0; 
    desc.componentManufacturer = kAudioUnitManufacturer_Apple; 

    AudioComponent outputComponent = AudioComponentFindNext(NULL, &desc); 

    status = AudioComponentInstanceNew(outputComponent, &audioUnit); 

    UInt32 flag = 1; 
    status = AudioUnitSetProperty(audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag)); 

    AudioStreamBasicDescription audioFormat; 
    audioFormat.mSampleRate = kSampleRate; 
    audioFormat.mFormatID = kAudioFormatLinearPCM; 
    audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 
    audioFormat.mFramesPerPacket = 1; 
    audioFormat.mChannelsPerFrame = 1; 
    audioFormat.mBitsPerChannel = 16; 
    audioFormat.mBytesPerPacket = 2; 
    audioFormat.mBytesPerFrame = 2; 

    status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &audioFormat, sizeof(audioFormat)); 

    AURenderCallbackStruct callbackStruct; 
    callbackStruct.inputProc = playbackCallback; 
    callbackStruct.inputProcRefCon = self; 

    status = AudioUnitSetProperty(audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &callbackStruct, sizeof(callbackStruct)); 

    status = AudioUnitInitialize(audioUnit); 

} 

-(void)start { 

    OSStatus status; 

    status = AudioOutputUnitStart(audioUnit); 

} 

-(void)stop { 

    OSStatus status; 

    status = AudioOutputUnitStop(audioUnit); 

} 

-(void)dealloc { 

    AudioUnitUninitialize(audioUnit); 

    [super dealloc]; 

} 

@end 
+1

为什么不能简单地用两个音频文件,一个是短调('.')和一个长音('-')? – 2011-09-04 09:39:54

+0

感谢您的回复马特,我想要做什么,当我得到这个工作是有能力有不同的话每分钟的速度这将意味着制作多个音频文件的短和长音。虽然我会牢记这一点,如果我不能动态生成的色调 – user551353

回答

2

你需要能够生成特定时间的色调,通过特定时间的沉默分开。只要你有这两个积木,你可以发送莫尔斯电码:

dot = 1 unit 
dash = 3 units 
space between dots/dashes within a letter = 1 unit 
space between letters = 3 units 
space between words = 5 units 

unit的长度决定了莫尔斯电码的整体速度。从例如50毫秒。

音调应该只是在适当的频率,例如纯正弦波400赫兹。沉默可以是一个包含所有零的备用缓冲区。这样,你可以“玩”无论是色调,并使用相同的API沉默,而不用担心定时/同步等

+1

感谢您的答复保罗,我怎么会得到基调50ms的发挥将这一涉及使用一个NSTimer,或是否有更好的办法? – user551353

+1

@ user551353:只需创建适当长度的缓冲区,例如对于50 ms @ 44.1 kHz采样率,您需要44100 * 0.05 = 2205个采样。破折号缓冲器将是6615个样本。同一个单位和三个单位静音缓冲区。然后,将这些字符串串起来,即继续使用新缓冲区调用您的播放API,并让其余的异步播放处理。 –

+0

谢谢保罗,我会和你一起玩。 – user551353