IOS进阶之AudioToolBox.framework

1.AudioToolbox概述

通过AudioToolbox框架,可以将短声音注册到system sound服务上,被注册到system sound服务上的声音称之为 system sounds。它必须满足下面几个条件。
(1).播放的时间不能超过30秒
(2).数据必须是 PCM或者IMA4流格式
(3).必须被打包成下面三个格式之一:Core Audio Format (.caf), Waveform audio (.wav), 或者 Audio Interchange File (.aiff)
声音文件必须放到设备的本地文件夹下面。通过AudioServicesCreateSystemSoundID方法注册这个声音文件.

2.AudioToolbox使用

#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>

typedef void (^ZTypewriteEffectBlock)(void);

@interface ZTypewriteEffectLabel : UILabel
{
    SystemSoundID  soundID;
}

/** Z
 *	设置单个字打印间隔时间,默认 0.3 秒
 */
@property (nonatomic) NSTimeInterval typewriteTimeInterval;

/** Z
 *	开始打印的位置索引,默认为0,即从头开始
 */
@property (nonatomic) int currentIndex;

/** Z
 *	输入字体的颜色
 */
@property (nonatomic, strong) UIColor *typewriteEffectColor;

/** Z
 *	是否有打印的声音,默认为 YES
 */
@property (nonatomic) BOOL hasSound;

/** Z
 *	打印完成后的回调block
 */
@property (nonatomic, copy) ZTypewriteEffectBlock typewriteEffectBlock;

/** Z
 *  开始打印
 */
-(void)startTypewrite;

@end

#import "ZTypewriteEffectLabel.h"

@implementation ZTypewriteEffectLabel

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.hasSound = NO;
        self.typewriteTimeInterval = 0.3;
    }
    return self;
}

-(void)startTypewrite
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"typewriter" ofType:@"wav"];
    
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &soundID);
    
    [NSTimer scheduledTimerWithTimeInterval:self.typewriteTimeInterval target:self selector:@selector(outPutWord:) userInfo:nil repeats:YES];
}

-(void)outPutWord:(id)atimer
{
    if (self.text.length == self.currentIndex) {
       [atimer invalidate];
        atimer = nil;
        self.typewriteEffectBlock();
    }else{
        self.currentIndex++;
        NSDictionary *dic = @{NSForegroundColorAttributeName: self.typewriteEffectColor};
        NSMutableAttributedString *mutStr = [[NSMutableAttributedString alloc] initWithString:self.text];
        [mutStr addAttributes:dic range:NSMakeRange(0, self.currentIndex)];
        [self setAttributedText:mutStr];
        
        if (self.hasSound==YES)
            AudioServicesPlaySystemSound (soundID);
        
            else
                
                AudioServicesPlaySystemSound (0);
    }
}

运行效果这样的


以下转载:http://blog.csdn.net/ch_soft/article/details/7381976

AudioToolbox这个库是C的接口,偏向于底层,用于在线流媒体音乐的播放,可以调用该库的相关接口自己封装一个在线播放器类,AudioStreamer是老外封装的一个播放器类,有兴趣的朋友可以研究下。 

      其实IOS库中有两个可以播放在线音乐的播放器类,AVPlayer和MPMusicPlayerController 
这两个做简单的播放还不错,但是如果要做专业的音乐播放项目,功能还不够强大,例如:边听边存、断点续传、播放事件等等都无法满足。一下是以前做的笔记,仅供参考 

播放流程图: 
 

数据结构及接口说明: 


C代码   收藏代码
  1.     •   数据类型  
  2. 1.AudioFileStreamID             文件流  
  3. 2.AudioQueueRef                     播放队列   
  4. 3.AudioStreamBasicDescription   格式化音频数据  
  5. 4.AudioQueueBufferRef             数据缓冲  
  6.   
  7.     •   回调函数  
  8. 1.AudioFileStream_PacketsProc       解析音频数据回调  
  9. 2.AudioSessionInterruptionListener  音频会话被打断  
  10. 3.AudioQueueOutputCallback          一个AudioQueueBufferRef播放完  
  11.   
  12.     •   主要函数  
  13. 0.AudioSessionInitialize (NULL, NULL, AudioSessionInterruptionListener, self);  
  14. 初始化音频会话  
  15.   
  16. 1.AudioFileStreamOpen(  
  17.                         (void*)self,                            
  18.                         &AudioFileStreamPropertyListenerProc,   
  19.                         &AudioFileStreamPacketsProc,            
  20.                         0,                                      
  21.                         &audio_file_stream);              
  22. 建立一个文件流AudioFileStreamID,传输解析的数据  
  23.   
  24. 2.AudioFileStreamParseBytes(  
  25.                           audio_file_stream,  
  26.                           datalen,  
  27.                           [data bytes],  
  28.                           kAudioFileStreamProperty_FileFormat);   
  29. 解析音频数据  
  30.   
  31. 3.AudioQueueNewOutput(&audio_format, AudioQueueOutputCallback, (void*)self, [[NSRunLoop currentRunLoop] getCFRunLoop], kCFRunLoopCommonModes, 0, &audio_queue);  
  32. 创建音频队列AudioQueueRef  
  33.   
  34. 4.AudioQueueAllocateBuffer(queue, [data length], &buffer);  
  35. 创建音频缓冲数据AudioQueueBufferRef  
  36.   
  37. 5.AudioQueueEnqueueBuffer(queue, buffer, num_packets, packet_descriptions);  
  38. 把缓冲数据排队加入到AudioQueueRef等待播放  
  39.   
  40. 6.AudioQueueStart(audio_queue, nil);    播放  
  41. 7.AudioQueueStop(audio_queue, true);  
  42.  AudioQueuePause(audio_queue);          停止、暂停  
  43.   
  44.     •   断点续传  
  45. 1。在http请求头中设置数据的请求范围,请求头中都是key-value成对  
  46.     key:Range           value:bytes=0-1000  
  47.     [request setValue:range  forHTTPHeaderField:@"Range"];  
  48. 可以实现,a.网络断开后再连接能继续从原来的断点下载  
  49.             b.可以实现播放进度可随便拉动  


首先获得文件路径:CFURLCreateFromFileSystemRepresentation函数获取

打开音频文件: AudioFileOpenURL 取得 OSStatue
获得音频文件属性: AudioFileGetProperty
取得音频文件数据: AudioFileReadPackets
初始化 AudioComponentDescription 参数设置,为初始化 AudioComponent 做准备 , 利用 AudioComponentInstanceNew 创建一个 Audio component instance ,并通过 AudioUnitSetProperty 设置其属性。
通过 AURenderCallbackStruct 创建一个回调函数并通过 AudioUnitSetProperty 设置其回调属性。
最后进行 AudioUnitInitialize 进行初始化完毕操作。

通过AudioOutputUnitStart进行播放,AudioOutputUnitStop进行暂停。


AudioToolbox.framework框架学习


AudioFile类

一个c编程接口,使用AudioFile可以从内存或硬盘中读取或写入多种格式的音频数据。


AudioFileStream类

提供了一个借口,用来解析流音频文件。

功能:从网络中读取数据流,把数据流解析成音频文件。

音频文件流是不容易获取的。当需要从stream中读取data时,以前的data可能已无法使用,而新的data还没有到达,而从网络中获取的data可能还包含packets数据。为了解析audio stream,parser必须记着已经获取的数据,等待剩余的数据。

缓冲区是在哪设置的?


//创建一个new stream parse

            AudioFileStreamOpen(self, AudioFileStream_PropertyListenerProc inPropertyListenerProc, AudioFileStream_PacketsProc inPacketsProc, AudioFileTypeID inFileTypeHint, AudioFileStreamID *outAudioFileStream);

            

//aquire some data

            AudioFileStreamParseBytes(<#AudioFileStreamID inAudioFileStream#>, <#UInt32 inDataByteSize#>, <#const void *inData#>, <#UInt32 inFlags#>);

            

//设置从流文件中读取data时的offset

            AudioFileStreamSeek(<#AudioFileStreamID inAudioFileStream#>, <#SInt64 inPacketOffset#>, <#SInt64 *outDataByteOffset#>, <#UInt32 *ioFlags#>);

  //获取完数据后,关闭该流对象

            AudioFileClose(<#AudioFileID inAudioFile#>)

            

AudioServices


AudioQueue

使用一个缓冲队列来存储data,用来播放或录音。播放或录音的时候,数据以流的形式操作,可以边获取数据变播放,或者边录音,边存储。

Resources:https://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html


AudioQueue

一个c编程接口,是Core Audio的一部分。功能:录音、播放音频。

AudioQueue类播放音频时,在内存中维护着一个buffer queue。只要buffer中有数据就可以播放,因此,一般使用AudioQueue对象来播放音频流,这样可以“边下载边播放”。

audioqueue中的方法都是静态方法,使用时传递进去的参数前缀是in,传递出来的参数前缀是out播放音频的方法:

AudioQueueNewOutput 

1、用来创建一个播放音频队列的对象AudioQueueRef,然后就是对该audioqueue对象进行操作。

2、用来添加一个回调方法AudioQueueOutputCallback,调用该方法时会返回一个audioqueue的buffer,该buffer中的数据已经被使用,需要在这个方法中填充新数据。

3、

AudioQueueEnqueueBuffer

想缓冲区中添加新的数据(数据一般从file或网络中获取)


AudioQueueAllocateBuffer

为一个audioqueue分配一个queueBuffer,每调用一次创建一个缓冲区,最后所有的缓冲区组成一个缓冲队列。

AudioQueueCreateTimeline

创建一个与audioqueue相关的时间轴。如果想要显示audio的时间,需要熟悉uyutimeLine相关的方法。



audioqueue的属性操作:

具体属性类型见官方文档:https://developer.apple.com/library/ios/#documentation/MusicAudio/Reference/AudioQueueReference/Reference/reference.html#//apple_ref/c/func/AudioQueueAddPropertyListener

AudioQueueSetProperty

用来设置某一个audioqueue对象的属性,具体属性以 kAudioQueueProperty_*开头

AudioQueueGetProperty 

获取audioqueue对象的某一个属性值。首先应该先调用AudioQueueGetPropertySize方法获取value的大小(byte形式)

AudioQueueAddPropertyListener

添加一个属性监听器。当一个audioqueue的对应属性值改变时,会回调这个监听器。


audioqueue的参数操作:

AudioQueueSetParameter

AudioQueueGetParameter

对参数的修改和获取,具体参数parameter包括:音量的调节、声道的调节、以及音量的渐变设置





NSFileHandle 用来从文件、socket中读取数据


CFReadStream 

用来读取一个字节流byte stream,该字节流可以来自于内存、一个文件、一个socket。在读bytes之前,流stream需要被打开。


CFWriteStream

用来写一个字节流



AudioStreamBasicDescription 

音频数据流格式的描述.Callback Method 回调函数,系统规定好了回调函数的参数,以及调用的地方,你只需要保证参数的格式正确,向函数里添加代码即可,函数的方法名称可以随便写,没有强制的规定。

AudioQueueNewOutput的第三个参数:inUserData 这是由用户来自定义的,数据的来源。只需要传递一个对象进去即可。使用,当系统自动调用回调函数MyAudioQueueOutputCallback或者MyAudioQueueInputCallback时候,返回的第一个参数inUserData就是你在AudioQueueNewOutput中设置的第三个参数。然后,你需要在回调函数中使用这个对象填充buffer(播放音频,当一个buffer为空时自动调用)或者读取buffer的数据(录音,当一个buffer满时自动调用)。


AudioFileStream_PropertyListenerProc

当在audio stream中找到一个property value后,回调该方法。

AudioFileStream_PacketsProc当在stream中找到audio data后回调该方法。


在参数中的in和out个代表的意思:in代表的是这个参数需要你在外面得到然后传递进去,在这个方法中要使用;out开头的参数表示这个参数是这个方法返回的值,你一般只需要定义一个引用,然后传递进去,执行完这个方法后,这个参数就实例化了。oh,my god!坑爹的苹果。



//====下载=====

CFReadStream

CFReadStreamClientCallBack回调函数在CFReadStreamSetClient中调用,是第三个参数。CFReadStreamClientCallBack只有在满足CFReadStreamSetClient中添加的streamEvents发生时才会别回调。

CFReadStreamScheduleWithRunLoop方法把stream加到一个线程中。然后,CFReadStreamSetClient在设置的东西就起作用了。当各种streamEvent发生时,client都会得到通知,client判断是否执行回调方法CFReadStreamClientCallBack。


AudioSession类

一个c接口,用来管理应用中audio的行为。

线程的操作,暂停后可能是县城就停止了。

对线程的操作  让某一个线程停下来。


参考阅读:

 

AudioToolbox之AudioQueue.h(二)Creating and Disposing of Audio Queues





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值