Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Otchet_kursovaya_SISPI.docx
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
825 Кб
Скачать
☆

4. Код программы

#import "ToneGeneratorViewController.h"

#import <AudioToolbox/AudioToolbox.h>

#import "SettingsModel.h"

OSStatus RenderTone(

void *inRefCon,

AudioUnitRenderActionFlags *ioActionFlags,

const AudioTimeStamp *inTimeStamp,

UInt32 inBusNumber,

UInt32 inNumberFrames,

AudioBufferList *ioData)

{

const double amplitude = 1;

ToneGeneratorViewController *viewController = (ToneGeneratorViewController *)inRefCon;

double theta = viewController->theta;

double theta_increment = 2.0 * M_PI * viewController->frequency / viewController->sampleRate;

const int channel = 0;

Float32 *buffer = (Float32 *)ioData->mBuffers[channel].mData;

for (UInt32 frame = 0; frame < inNumberFrames; frame++)

{

if ([viewController.model factor]) {

buffer[frame] = sin(theta) * amplitude;

theta += theta_increment;

if (theta > 2.0 * M_PI)

{

theta -= 2.0 * M_PI;

}

} else {

buffer[frame] = 0;

theta = 0;

}

}

viewController->theta = theta;

return noErr;

}

void ToneInterruptionListener(void *inClientData, UInt32 inInterruptionState)

{

ToneGeneratorViewController *viewController = (ToneGeneratorViewController *)inClientData;

[viewController stop];

}

@interface ToneGeneratorViewController()

@property (retain) UITabBarItem *tabBarItem;

@end

@implementation ToneGeneratorViewController

@synthesize model;

@synthesize frequencySlider, playButton, frequencyLabel, speedLabel, speedSlider;

@synthesize tabBarItem;

- (MorseModel *)model {

if (!model) {

model = [[MorseModel alloc] init];

model.dotsInPauseBetweenSymbols = 3;

model.dotsInPauseBetweenGroups = 7;

model.controller = self;

model.morseCode = [SettingsModel dictionary];

}

return model;

}

- (void)setup {

self.title = @"Morse Generator";

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"Back"

style:UIBarButtonItemStylePlain target:nil action:nil];

self.navigationItem.backBarButtonItem = backButton;

[backButton release];

}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {

if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {

[self setup];

}

return self;

}

- (void)awakeFromNib {

[self setup];

}

- (IBAction)frequencyChanged:(UISlider *)slider {

frequency = slider.value;

self.frequencyLabel.text = [NSString stringWithFormat:@"%4.0f Hz", frequency];

[SettingsModel setFrequency:frequency];

}

- (IBAction)speedChanged:(UISlider *)slider {

int newSpeed = slider.value;

self.model.speed = newSpeed;

self.speedLabel.text = [NSString stringWithFormat:@"%d WPM", newSpeed];

[SettingsModel setSpeed:newSpeed];

}

- (void)createToneUnit

{

AudioComponentDescription defaultOutputDescription;

defaultOutputDescription.componentType = kAudioUnitType_Output;

defaultOutputDescription.componentSubType = kAudioUnitSubType_RemoteIO;

defaultOutputDescription.componentManufacturer = kAudioUnitManufacturer_Apple;

defaultOutputDescription.componentFlags = 0;

defaultOutputDescription.componentFlagsMask = 0;

AudioComponent defaultOutput = AudioComponentFindNext(NULL, &defaultOutputDescription);

NSAssert(defaultOutput, @"Can't find default output");

OSErr err = AudioComponentInstanceNew(defaultOutput, &toneUnit);

NSAssert1(toneUnit, @"Error creating unit: %ld", err);

AURenderCallbackStruct input;

input.inputProc = RenderTone;

input.inputProcRefCon = self;

err = AudioUnitSetProperty(toneUnit,

kAudioUnitProperty_SetRenderCallback,

kAudioUnitScope_Input,

0,

&input,

sizeof(input));

NSAssert1(err == noErr, @"Error setting callback: %ld", err);

const int four_bytes_per_float = 4;

const int eight_bits_per_byte = 8;

AudioStreamBasicDescription streamFormat;

streamFormat.mSampleRate = sampleRate;

streamFormat.mFormatID = kAudioFormatLinearPCM;

streamFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kAudioFormatFlagIsNonInterleaved;

streamFormat.mBytesPerPacket = four_bytes_per_float;

streamFormat.mFramesPerPacket = 1;

streamFormat.mBytesPerFrame = four_bytes_per_float;

streamFormat.mChannelsPerFrame = 1;

streamFormat.mBitsPerChannel = four_bytes_per_float * eight_bits_per_byte;

err = AudioUnitSetProperty (toneUnit,

kAudioUnitProperty_StreamFormat,

kAudioUnitScope_Input,

0,

&streamFormat,

sizeof(AudioStreamBasicDescription));

NSAssert1(err == noErr, @"Error setting stream format: %ld", err);

}

- (void)stop {

if (isRunning) {

isRunning = NO;

isPaused = NO;

AudioOutputUnitStop(toneUnit);

[playButton setTitle:NSLocalizedString(@"Play", nil) forState:0];

[self.model reset];

}

}

- (IBAction)stopPlay:(UIButton *)sender {

[self stop];

}

- (IBAction)playAgain:(UIButton *)sender {

[self stopPlay:sender];

NSRunLoop* myRunLoop = [NSRunLoop currentRunLoop];

NSDate* futureDate = [NSDate dateWithTimeIntervalSinceNow:0.4];

NSTimer* myTimer = [[NSTimer alloc] initWithFireDate:futureDate

interval:0.1

target:self

selector:@selector(togglePlay:)

userInfo:nil

repeats:NO];

[myRunLoop addTimer:myTimer forMode:NSDefaultRunLoopMode];

[myTimer release];

}

- (IBAction)togglePlay:(UIButton *)selectedButton

{

if (!isRunning) {

isRunning = YES;

[self.model calculateData:SIZE];

isPaused = YES;

}

if (isPaused) {

if ([SettingsModel textChanged]) {

[self.model reset];

self.model.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"MorseText"];

[self.model calculateData:SIZE];

[SettingsModel setTextChanged:NO];

}

isPaused = NO;

OSErr err = AudioOutputUnitStart(toneUnit);

NSAssert1(err == noErr, @"Error starting unit: %ld", err);

[playButton setTitle:NSLocalizedString(@"Pause", nil) forState:0];

} else {

isPaused = YES;

AudioOutputUnitStop(toneUnit);

[playButton setTitle:NSLocalizedString(@"Play", nil) forState:0];

}

}

- (void)viewDidLoad {

[super viewDidLoad];

self.speedSlider.value = [SettingsModel speed];

[self speedChanged:self.speedSlider];

self.frequencySlider.value = [SettingsModel frequency];

[self frequencyChanged:self.frequencySlider];

sampleRate = 44100;

OSStatus result = AudioSessionInitialize(NULL, NULL, ToneInterruptionListener, self);

if (result == kAudioSessionNoError)

{

UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;

AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);

}

AudioSessionSetActive(true);

[self createToneUnit];

dispatch_queue_t initQueue = dispatch_queue_create("Init toneUnit", NULL);

dispatch_async(initQueue, ^{

OSErr err = AudioUnitInitialize(toneUnit);

NSAssert1(err == noErr, @"Error initializing unit: %ld", err);

});

if (self.textChanged) {

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

NSArray *morseText = [MorseModel getMorseText:[defaults objectForKey:@"VisibleText"]

withDictionary:[SettingsModel dictionary]];

self.model.text = morseText;

self.textChanged = NO;

[defaults setObject:morseText forKey:@"MorseText"];

[defaults synchronize];

} else {

self.model.text = [[NSUserDefaults standardUserDefaults] objectForKey:@"MorseText"];

}

}

- (void)viewWillAppear:(BOOL)animated {

[super viewWillAppear:animated];

}

- (void)viewDidUnload {

self.frequencyLabel = nil;

self.playButton = nil;

self.frequencySlider = nil;

self.speedLabel = nil;

self.speedSlider = nil;

AudioUnitUninitialize(toneUnit);

AudioComponentInstanceDispose(toneUnit);

toneUnit = nil;

AudioSessionSetActive(false);

}

// Override to allow orientations other than the default portrait orientation.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

// Return YES for supported orientations.

return YES;

}

- (void)dealloc {

[model release];

[super dealloc];

}

@end

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]