2011-09-04 106 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