2010-08-11 31 views
1

我想要生成自定義DTMF鈴聲並在iPhone上播放。 爲了做到這一點,我創建並分配了一個自定義音調(ptr)的內存緩衝區。 現在我想創建一個NSData對象,用內存緩衝區初始化,並使用initWithData:error:instance方法將它傳遞給AVAudioPlayer。使用DTMF生成音調並使用AVAudioPlayer播放

我寫了下面的代碼,但是當我按下「Play」按鈕時,它崩潰了。

#import "AudioPlayerViewController.h" 
#include <stdlib.h> 
#include <math.h> 
#define SIZE 10 
#define LENGTH 65535 
const int PLAYBACKFREQ = 44100; 
const float PI2 = 3.14159265359f * 2; 
const int freq1 = 697; 
const int freq2 = 1209; 



@implementation AudioPlayerViewController 

@synthesize playButton, stopButton; 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
// Allocate space for an array with ten elements of type int. 
int *ptr = malloc(SIZE * sizeof(int)); 
if (ptr == NULL) NSLog(@"Error: Memory buffer could not be allocated."); 
else NSLog(@"Allocation succeeded."); 

// The formula for the tone, the content of the buffer. 
for(int i=0; i<SIZE; i++) ptr[i] = (sin(i*(PI2*(PLAYBACKFREQ/freq1))) + sin(i* (PI2*(PLAYBACKFREQ/freq2)))) * 16383; 
NSData *myData = [[NSData alloc] initWithBytesNoCopy:ptr length:SIZE]; 
free(ptr); 
ptr = NULL; 
audioPlayer = [[AVAudioPlayer alloc] initWithData:myData error:&error]; 
audioPlayer.numberOfLoops = -1; 
} 
-(IBAction) playAudio: (id) sender { 
    if (audioPlayer == nil) NSLog([error description]);    
    else [audioPlayer play]; 
} 
-(IBAction) stopAudio: (id) sender { [audioPlayer stop]; } 

- (void)dealloc { 
    [audioPlayer release]; 
    [myData release]; 
    [super dealloc]; 
} 

@end 

在本文檔中,方法initWithBytesNoCopy的說明寫着:

A buffer containing data for the new object. bytes must point to a memory block allocated with malloc.

所以我已經做到了這一點,但它不工作。

任何形式的幫助將不勝感激!

+1

您需要展開「它不起作用」。 – 2010-08-11 10:18:22

+0

一切工作正常,直到我按下一個按鈕「播放」調用方法playAudio。該按鈕變爲藍色,Xcode退出我的應用程序 – Sagiftw 2010-08-11 10:22:00

+0

Xcode不會「退出您的應用程序」 - 您可能以某種方式崩潰 - 在調試器下運行的內容會告訴您什麼? – 2010-08-11 10:26:17

回答

2

你創建一個NSData而不復制數據,然後你釋放數據,所以NSData現在有一個懸掛指針。刪除free(ptr);行並再次嘗試。當它完成後,NSData將自行釋放數據。

+0

我試過這樣做,但它沒有幫助。 – Sagiftw 2010-08-11 11:34:13

+0

第二件令人懷疑的事情是,你正在給AVAudioPlayer原始數據,它可能不知道如何解釋。音頻文件通常有一個描述採樣率,採樣格式等的頭文件。您可以通過添加一個假頭文件來解決這個問題,例如一個非常簡單的WAV頭文件。不過,您可能需要將int轉換爲16位值。 – Hollance 2010-08-11 13:23:03

+0

這是一個演示項目,演示如何執行此操作:http://github.com/hollance/AVBufferPlayer – Hollance 2010-08-15 16:24:32

相關問題