在objective-c中生成莫尔斯电码风格的音调
我有一个课程,可以让我用音频单位播放音调,我想做的是让学生在我向学生发送短语或字母时播放莫尔斯电码 我该怎么办?我希望有人能给我指出正确的方向。我在下面包含了音调生成器.h和.m文件在objective-c中生成莫尔斯电码风格的音调,objective-c,Objective C,我有一个课程,可以让我用音频单位播放音调,我想做的是让学生在我向学生发送短语或字母时播放莫尔斯电码 我该怎么办?我希望有人能给我指出正确的方向。我在下面包含了音调生成器.h和.m文件 // // Singer.h // musiculesdev // // Created by Dylan on 2/20/09. // Copyright 2009 __MyCompanyName__. All rights reserved. // #import <Foundation
//
// 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
//
//歌手h
//音乐节
//
//由迪伦于2009年2月20日创作。
//版权所有2009年uu MyCompanyName uuu。版权所有。
//
#进口
#进口
@接口:NSObject{
音频元件;恒定音频单元;
}
-(void)initAudio;//把这个放在init里?
-(无效)开始;
-(无效)停止;
-(iAction)开机:(id)发送方;
@结束
//
//歌手m
//音乐节
//
//由迪伦于2009年2月20日创作。
//版权所有2009年uu MyCompanyName uuu。版权所有。
//
#进口
#进口
#输入“Singer.h”
#定义kOutputBus 0
#定义kSampleRate 44100
//44100.0f
#定义kWaveform(M_PI*2.0f/kSampleRate)
@执行歌手
OSStatus回放回调(无效*inRefCon,
AudioUnitRenderActionFlags*ioActionFlags,
常量音频时间戳*inTimeStamp,
UInt32 InBunsNumber,
UInt32数字帧,
音频缓冲列表*ioData){
//Singer*me=(Singer*)在Refcon中;
静态int相位=0;
对于(UInt32 i=0;imNumberBuffers;i++){
int samples=ioData->mBuffers[i].mDataByteSize/sizeof(SInt16);
16个数值[样本];
浮波;
对于(int j=0;j waves*=32500/4;//您需要能够生成特定持续时间的音调,由特定持续时间的静音分隔。只要您有这两个构建块,您就可以发送摩尔斯电码:
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
单位的长度
决定莫尔斯电码的整体速度。例如,从50毫秒开始
音调应该是适当频率的纯正弦波,例如400 Hz。静音可以是包含所有零的备用缓冲区。这样,您可以使用相同的API“播放”音调和静音,而不必担心定时/同步等问题。为什么不简单地使用两个音频文件,一个用于短音(
)和一个长音(-
)?感谢回复垫,当我开始工作时,我想做的是每分钟有不同的单词速度,这意味着制作多个短音和长音的音频文件。尽管我会记住这一点,如果我不能在飞行中生成音调谢谢回复保罗,我如何让音调播放50分钟ms这会涉及使用NSTimer还是有更好的方法?@user551353:只需创建一个适当长度的缓冲区,例如,对于50毫秒@44.1 kHz采样率,您需要44100*0.05=2205个样本。短划线缓冲区将是6615个样本。对于一个单元和三个单元静默缓冲区也是如此。然后将它们串在一起,即继续呼叫您r使用新缓冲区播放API,并让异步播放处理其余部分。谢谢Paul,我将对此进行一次播放。@PaulR,尝试在此处执行相同的操作,但使用RenderOne aka PlaybackCallback(AudioUnit的输入过程)似乎有问题你有任何链接/示例吗?我在NSThread sleep中获得了很好的结果,但我似乎无法克服令人讨厌的弹出(单击)效果用它。@zaitsman:试着发布一个新问题,并将其标记为morse
,信号处理
和iOS
——我相信至少有一个普通用户已经为iOS编写了morse码应用程序,所以如果你能引起他的注意,你应该得到一些好的指导。(我知道莫尔斯和DSP、音频编程等,但对iOS知之甚少。)