// // CCAudio.mm // CCFC // // Created by xichen on 11-12-18. // Copyright 2011 ccteam. All rights reserved. // #import "CCAudio.h" #import <AudioToolbox/AudioToolbox.h> @implementation CCAudio + (int)playSound:(NSString *)soundFullPath { SystemSoundID soundId; NSURL *filePath = [NSURL fileURLWithPath:soundFullPath isDirectory:NO]; OSStatus status = AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundId); if(status != 0) return status; AudioServicesPlaySystemSound(soundId); return status; } + (void)playSystemSound:(uint)sysSoundId { AudioServicesPlaySystemSound(sysSoundId); } + (void)playSystemKeyboardClick { AudioServicesPlaySystemSound(0x450); } @end void onBufferCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) { CCLocalAudioPlayer *player = (CCLocalAudioPlayer *)inUserData; UInt32 numBytes; UInt32 nPackets = player.numPacketsToRead; OSStatus status = AudioFileReadPackets(player.audioFile, false, &numBytes, inCompleteAQBuffer->mPacketDescriptions, player.currentPacket, &nPackets, inCompleteAQBuffer->mAudioData); if (status) printf("AudioFileReadPackets failed: %d", (int)status); if (nPackets > 0) { inCompleteAQBuffer->mAudioDataByteSize = numBytes; inCompleteAQBuffer->mPacketDescriptionCount = nPackets; status = AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, 0, NULL); if(status != 0) { printf("AudioQueueEnqueueBuffer failed: %d", (int)status); return; } player.currentPacket += nPackets; } else { status = AudioQueueStop(inAQ, false); if(status != 0) { printf("AudioQueueStop failed: %d", (int)status); return; } } } void isRunningProc(void *inUserData, AudioQueueRef inAQ, AudioQueuePropertyID inID) { CCLocalAudioPlayer *player = (CCLocalAudioPlayer *)inUserData; UInt32 size = 4; OSStatus status = AudioQueueGetProperty(inAQ, kAudioQueueProperty_IsRunning, &player->_isRunning, &size); if(status != 0) { printf("AudioQueueGetProperty failed: %d", (int)status); return; } if (!player.isRunning) [[NSNotificationCenter defaultCenter] postNotificationName:@"playbackQueueStopped" object:nil]; } @implementation CCLocalAudioPlayer @synthesize path = _path; @synthesize numPacketsToRead = _numPacketsToRead; @synthesize audioFile = _audioFile; @synthesize currentPacket = _currentPacket; @synthesize isRunning = _isRunning; - (void)calculateBytesForTime:(AudioStreamBasicDescription *)inDesc maxPacketSize:(UInt32)inMaxPacketSize seconds:(Float64)inSeconds outBufferSize:(UInt32 *)outBufferSize outNumPackets:(UInt32 *)outNumPackets { static const int maxBufferSize = 0x10000; // 64K static const int minBufferSize = 0x4000; // 16K if (inDesc->mFramesPerPacket) { Float64 numPacketsForTime = inDesc->mSampleRate / inDesc->mFramesPerPacket * inSeconds; *outBufferSize = numPacketsForTime * inMaxPacketSize; } else { *outBufferSize = maxBufferSize > inMaxPacketSize ? maxBufferSize : inMaxPacketSize; } if (*outBufferSize > maxBufferSize && *outBufferSize > inMaxPacketSize) *outBufferSize = maxBufferSize; else { if (*outBufferSize < minBufferSize) *outBufferSize = minBufferSize; } *outNumPackets = *outBufferSize / inMaxPacketSize; } - (id)initWithPath:(NSString *)path { self = [super init]; if(self) { self.path = path; _playStatus = CC_AP_PLAYING_STATUS_UNKOWN; } return self; } - (void)dealloc { [_path release]; if (_queue) { AudioQueueDispose(_queue, true); _queue = NULL; } if (_audioFile) { AudioFileClose(_audioFile); _audioFile = 0; } [super dealloc]; } //播放控制 - (OSStatus)play { char *cookie = NULL; AudioChannelLayout *acl = NULL; BOOL isFormatVBR; UInt32 size; _playStatus = CC_AP_PLAYING_STATUS_INITING; OSStatus status = AudioFileOpenURL((CFURLRef)[NSURL fileURLWithPath:_path] , kAudioFileReadPermission , 0 , &_audioFile); if(status != 0) goto end; size = sizeof(_dataFormat); status = AudioFileGetProperty(_audioFile, kAudioFilePropertyDataFormat, &size, &_dataFormat); if(status != 0) goto end; status = AudioQueueNewOutput(&_dataFormat, onBufferCallback, self, CFRunLoopGetCurrent(), kCFRunLoopCommonModes, 0, &_queue); if(status != 0) goto end; UInt32 bufferByteSize; UInt32 maxPacketSize; size = sizeof(maxPacketSize); status = AudioFileGetProperty(_audioFile, kAudioFilePropertyPacketSizeUpperBound, &size, &maxPacketSize); if(status != 0) goto end; [self calculateBytesForTime:&_dataFormat maxPacketSize:maxPacketSize seconds:0.5f outBufferSize:&bufferByteSize outNumPackets:&_numPacketsToRead]; size = sizeof(UInt32); status = AudioFileGetPropertyInfo (_audioFile, kAudioFilePropertyMagicCookieData, &size, NULL); if (!status && size) { cookie = new char [size]; status = AudioFileGetProperty (_audioFile, kAudioFilePropertyMagicCookieData, &size, cookie); if(status != 0) goto end; status = AudioQueueSetProperty(_queue, kAudioQueueProperty_MagicCookie, cookie, size); if(status != 0) goto end; delete []cookie; cookie = NULL; } status = AudioFileGetPropertyInfo(_audioFile, kAudioFilePropertyChannelLayout, &size, NULL); if (status != 0 && size > 0) { acl = (AudioChannelLayout *)malloc(size); status = AudioFileGetProperty(_audioFile, kAudioFilePropertyChannelLayout, &size, acl); if(status != 0) goto end; status = AudioQueueSetProperty(_queue, kAudioQueueProperty_ChannelLayout, acl, size); if(status != 0) goto end; free(acl); acl = NULL; } status = AudioQueueAddPropertyListener(_queue, kAudioQueueProperty_IsRunning, isRunningProc, self); if(status != 0) goto end; isFormatVBR = (_dataFormat.mBytesPerPacket == 0 || _dataFormat.mFramesPerPacket == 0); for (int i = 0; i < kNumberBuffers; ++i) { status = AudioQueueAllocateBufferWithPacketDescriptions(_queue, bufferByteSize, (isFormatVBR ? _numPacketsToRead : 0), &_buffers[i]); if(status != 0) goto end; } status = AudioQueueSetParameter(_queue, kAudioQueueParam_Volume, 1.0); if(status != 0) goto end; for (int i = 0; i < kNumberBuffers; ++i) { onBufferCallback(self, _queue, _buffers[i]); } _playStatus = CC_AP_PLAYING_STATUS_INIT_OK; status = AudioQueueStart(_queue, NULL); if(status == 0) _playStatus = CC_AP_PLAYING_STATUS_PLAYING; else { printf("CCAudio play failed\n"); } return status; end: printf("CCAudio play failed\n"); delete []cookie; free(acl); return status; } - (OSStatus)pause { OSStatus status = AudioQueuePause(_queue); if (status != 0) { printf("CCAudio pause failed\n"); } else { _playStatus = CC_AP_PLAYING_STATUS_PAUSED; } return status; } - (OSStatus)resume { OSStatus status = AudioQueueStart(_queue, NULL); if (status != 0) { printf("CCAudio resume failed\n"); } else { _playStatus = CC_AP_PLAYING_STATUS_PLAYING; } return status; } - (OSStatus)stop { OSStatus status = AudioQueueStop(_queue, true); if (status != 0) { printf("CCAudio stop failed\n"); } else { _playStatus = CC_AP_PLAYING_STATUS_STOPPED; } if (_queue) { AudioQueueDispose(_queue, true); _queue = NULL; } if (_audioFile) { AudioFileClose(_audioFile); _audioFile = 0; } memset(_buffers, 0, kNumberBuffers * sizeof(AudioQueueBufferRef)); _numPacketsToRead = 0; _currentPacket = 0; return status; } //音量控制 - (float)getVolume { return _volume; } - (OSStatus)setVolume:(float)newVolume { OSStatus status = AudioQueueSetParameter(_queue, kAudioQueueParam_Volume, newVolume); if(status != noErr) { return status; } _volume = newVolume; return noErr; } - (int)getDuration // 歌曲总时长,以秒为单位 { NSTimeInterval duration = 0; UInt32 size = sizeof(duration); OSStatus status; status = AudioFileGetProperty(_audioFile, kAudioFilePropertyEstimatedDuration, &size, &duration); if(status != noErr) { NSLog(@"****CCAudio getDuration error!"); return -1; } return (int)duration; } - (int)getCurrentPlayTime // 歌曲当前播放的时间 { int currentTime = -1; AudioTimeStamp queueTime; Boolean discontinuity; OSStatus status; status = AudioQueueGetCurrentTime(_queue, NULL, &queueTime, &discontinuity); if (status == noErr) { double temp = queueTime.mSampleTime / _dataFormat.mSampleRate; if (temp < 0.0) { temp = 0.0; } currentTime = (int)temp; } return currentTime; } - (BOOL)isPlaying // 返回是否处于播放状态 { return _playStatus == CC_AP_PLAYING_STATUS_PLAYING; } - (CCAudioPlayerPlayingStatus)getPlayStatus // 返回播放状态 { return _playStatus; } @end @interface CCRecorder(privateApi) - (void)setRecordPacket:(SInt64)newRecordPacket; - (BOOL)isRunning; @end // CCRecorder void inputBufferHandler(void * inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumPackets, const AudioStreamPacketDescription *inPacketDesc) { CCRecorder *recorder = (CCRecorder *)inUserData; if (inNumPackets > 0) { NSLog(@"CCRecorder inputBufferHandler: inNumPackets:%d", inNumPackets); AudioFileWritePackets([recorder getRecordFile], FALSE, inBuffer->mAudioDataByteSize, inPacketDesc, [recorder getRecordPacket], &inNumPackets, inBuffer->mAudioData); [recorder setRecordPacket:[recorder getRecordPacket] + inNumPackets]; } if ([recorder isRunning]) AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL); } @implementation CCRecorder @synthesize path = _path; - (id)initWithPath:(NSString *)path { self = [super init]; if(self) { self.path = path; } return self; } - (void)dealloc { [_path release]; AudioQueueDispose(_queue, true); AudioFileClose(_recordFile); [super dealloc]; } - (void)setupCommonAudioFormat:(UInt32)formatID { memset(&_mRecordFormat, 0, sizeof(_mRecordFormat)); UInt32 size = sizeof(_mRecordFormat.mSampleRate); AudioSessionGetProperty( kAudioSessionProperty_CurrentHardwareSampleRate, &size, &_mRecordFormat.mSampleRate); size = sizeof(_mRecordFormat.mChannelsPerFrame); AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareInputNumberChannels, &size, &_mRecordFormat.mChannelsPerFrame); _mRecordFormat.mFormatID = formatID; if (formatID == kAudioFormatLinearPCM) { _mRecordFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; _mRecordFormat.mBitsPerChannel = 16; _mRecordFormat.mBytesPerPacket = 2; _mRecordFormat.mChannelsPerFrame = 1; _mRecordFormat.mBytesPerFrame = (_mRecordFormat.mBitsPerChannel / 8) * _mRecordFormat.mChannelsPerFrame; _mRecordFormat.mFramesPerPacket = 1; _mRecordFormat.mSampleRate = 16000; } } - (void)setRecordToPCM { [self setupCommonAudioFormat:kAudioFormatLinearPCM]; } - (void)copyEncoderCookieToFile { UInt32 propertySize; OSStatus status = AudioQueueGetPropertySize(_queue, kAudioQueueProperty_MagicCookie, &propertySize); if (status == noErr && propertySize > 0) { Byte *magicCookie = new Byte[propertySize]; UInt32 magicCookieSize; AudioQueueGetProperty(_queue, kAudioQueueProperty_MagicCookie, magicCookie, &propertySize); magicCookieSize = propertySize; UInt32 willEatTheCookie = false; status = AudioFileGetPropertyInfo(_recordFile, kAudioFilePropertyMagicCookieData, NULL, &willEatTheCookie); if (status == noErr && willEatTheCookie) { status = AudioFileSetProperty(_recordFile, kAudioFilePropertyMagicCookieData, magicCookieSize, magicCookie); } delete[] magicCookie; } } - (int)computeRecordBufferSize:(const AudioStreamBasicDescription *)format seconds:(float)seconds { int packets, frames, bytes = 0; frames = (int)ceil(seconds * format->mSampleRate); if (format->mBytesPerFrame > 0) bytes = frames * format->mBytesPerFrame; else { UInt32 maxPacketSize; if (format->mBytesPerPacket > 0) maxPacketSize = format->mBytesPerPacket; else { UInt32 propertySize = sizeof(maxPacketSize); OSStatus status = AudioQueueGetProperty(_queue, kAudioQueueProperty_MaximumOutputPacketSize, &maxPacketSize, &propertySize); if(status != noErr) return 0; } if (format->mFramesPerPacket > 0) packets = frames / format->mFramesPerPacket; else packets = frames; if (packets == 0) packets = 1; bytes = packets * maxPacketSize; } return bytes; } - (OSStatus)start { OSStatus status; UInt32 size; status = AudioQueueNewInput( &_mRecordFormat, inputBufferHandler, self, NULL, NULL, 0, &_queue); if(status != noErr) return status; _mRecordPacket = 0; size = sizeof(_mRecordFormat); status = AudioQueueGetProperty(_queue, kAudioQueueProperty_StreamDescription, &_mRecordFormat, &size); if(status != noErr) return status; status = AudioFileCreateWithURL((CFURLRef)[NSURL fileURLWithPath:_path], kAudioFileCAFType, &_mRecordFormat, kAudioFileFlags_EraseFile, &_recordFile); if(status != noErr) return status; [self copyEncoderCookieToFile]; int bufferByteSize = [self computeRecordBufferSize:&_mRecordFormat seconds:0.5f]; for (int i = 0; i < kNumberBuffers; ++i) { status = AudioQueueAllocateBuffer(_queue, bufferByteSize, &_buffers[i]); if(status != noErr) return status; status = AudioQueueEnqueueBuffer(_queue, _buffers[i], 0, NULL); if(status != noErr) return status; } status = AudioQueueStart(_queue, NULL); if(status == noErr) _isRunning = TRUE; return status; } - (void)stop { AudioQueueStop(_queue, true); [self copyEncoderCookieToFile]; AudioQueueDispose(_queue, true); AudioFileClose(_recordFile); _isRunning = FALSE; } - (BOOL)isRunning { return _isRunning; } - (AudioFileID)getRecordFile { return _recordFile; } - (SInt64)getRecordPacket { return _mRecordPacket; } - (void)setRecordPacket:(SInt64)newRecordPacket { _mRecordPacket = newRecordPacket; } @end
googlecode链接地址(会有更新):http://code.google.com/p/iphone-common-codes-ccteam/source/browse/trunk/CCFC/files/CCAudio.mm
发表评论
-
iphone-common-codes-ccteam源代码 CCEncoding.h
2012-01-12 09:55 648// // CCEncoding.h // C ... -
iphone-common-codes-ccteam源代码 CCEmoji.m
2012-01-12 09:54 619// // CCEmoji.m // CCFC ... -
iphone-common-codes-ccteam源代码 CCEmoji.h
2012-01-12 09:53 665// // CCEmoji.h // CCFC ... -
iphone-common-codes-ccteam源代码 CCDylib.m
2012-01-12 09:52 651// // CCDylib.m // CCFC ... -
iphone-common-codes-ccteam源代码 CCDylib.h
2012-01-12 09:51 711// // CCDylib.h // CCFC ... -
iphone-common-codes-ccteam源代码 CCDepend.m
2012-01-11 10:17 646// // CCDepend.m // CCF ... -
iphone-common-codes-ccteam源代码 CCDepend.h
2012-01-11 10:17 694// // CCDepend.h // CCF ... -
iphone-common-codes-ccteam源代码 CCDelete.h
2012-01-11 10:15 637// // CCDelete.h // CCF ... -
iphone-common-codes-ccteam源代码 CCDelete.m
2012-01-11 10:14 676// // CCDelete.m // CCF ... -
iphone-common-codes-ccteam源代码 CCDebug.h
2012-01-11 10:14 659// // CCFileUtil.h // C ... -
iphone-common-codes-ccteam源代码 CCContact.m
2012-01-10 09:41 916// // CCContact.m // ... -
iphone-common-codes-ccteam源代码 CCConfig.m
2012-01-10 09:39 604// // CCConfig.m // CCF ... -
iphone-common-codes-ccteam源代码 CCConfig.h
2012-01-10 09:37 743// // CCConfig.h // CCF ... -
iphone-common-codes-ccteam源代码 CCCompile.m
2012-01-10 09:36 565// // CCCompile.m // CC ... -
iphone-common-codes-ccteam源代码 CCCompile.h
2012-01-08 10:48 572// // CCCompile.h // CC ... -
iphone-common-codes-ccteam源代码 CCCommon.m
2012-01-08 10:47 521// // CCCommon.m // CCF ... -
iphone-common-codes-ccteam源代码 CCCommon.h
2012-01-08 10:46 573// // CCCommon.h // CCF ... -
iphone-common-codes-ccteam源代码 CCCamera.m
2012-01-08 10:45 639// // CCCamera.m // CCF ... -
iphone-common-codes-ccteam源代码 CCCamera.h
2012-01-08 10:44 751// // CCCamera.h // CCF ... -
iphone-common-codes-ccteam源代码 CCCALayer.m
2012-01-07 10:13 598// // CCCALayer.m // CC ...
相关推荐
github-recovery-codes.txt
codes = """--..-- .-.-.- ----- .---- ..--- ...-- ....- ..... -.... --... ---.. ----. ..--.. .- -... -.-. -... . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .-- -.
在"threejs-3d-fly-codes_jb51"文件夹中,我们通常会看到以下核心文件: 1. index.html:这是项目的主页面,包含HTML结构和JavaScript脚本引用。 2. main.js:主要的JavaScript代码,实现3D场景的创建和动画逻辑。 ...
LearningMATLAB-All_Statistics_Codes.zip All_Statistics_Codes.zip MatlabLearn.pdf
LearningMATLAB-All_Various_Codes.zip All_Statistics_Codes.zip MatlabLearn.pdf
这个“activiti-in-action-codes-master.zip”压缩包包含了与《Activiti in Action》这本书配套的源代码,帮助读者深入理解Activiti的工作原理和实践应用。 首先,让我们了解什么是BPMN 2.0。Business Process ...
在给定的压缩包文件“CSR-bc5-Source-Codes.rar”中,包含了CSR BC5的相关源代码,这对于开发者来说是极其宝贵的资源,可以深入了解CSR BC5的工作原理,并进行定制化开发。 CSR BC5是基于ADK (Application ...
标题中的"Ch-2.-Matlab-Codes.rar_NLS_TOA_single"暗示这是一组MATLAB代码,专门用于非线性最小二乘(NLS)方法在单次试验中的到达时间(TOA)定位问题。非线性最小二乘法是一种优化技术,常用于解决在数据拟合过程...
No_Description_Self-Driving-Car-Course-Codes
单bit错误校正,多bit错误检测的ECC算法论文;比传统的Hamming更加简洁、高效。
标题中的"Clinic-Management-PHP-MySQL-Source-Codes.zip_clinic_clinic php"表明这是一个基于PHP和MySQL开发的诊所管理系统源代码包。这个系统主要用于管理医疗诊所的日常运营和患者服务。从描述中我们可以了解到,...
下面我们将详细探讨标题为"Ongoing-ns-2-codes.zip_sample tcl"的压缩包中的TCL样本代码及其相关知识点。 一、NS2基本概念 1. 模块化设计:NS2由一系列模块组成,包括节点(nodes)、网络接口(interfaces)、...
标题 "jquery-select-auto-complete-codes.rar" 涉及的是一个使用JQuery实现的自动完成功能,特别针对搜索框的交互设计。JQuery是一个广泛使用的JavaScript库,它简化了DOM操作、事件处理、动画效果以及Ajax交互。在...
### 低密度奇偶校验码(Low-Density Parity-Check Codes,简称LDPC码) #### 引言 在1963年,罗伯特·G·加勒格在其博士论文中首次提出了低密度奇偶校验码的概念。这篇论文不仅为通信工程领域带来了重大的突破,...
目录 Invited Talks.- Understanding and Inductive Inference.- Computing with Cells: Membrane... Zero-Knowledge Argument for Simultaneous Discrete Logarithms.- Directed Figure Codes: Decidability Frontier.
南京大学“开源仓库代码挖掘和可视化”创新项目代码_Git-Repository-Miner-Codes
实验四-代码-UAV-AmBC-TWC-simulation codes.zip
- **克尔多克码(Kerdock Codes)**与**预备拉塔码(Preparata Codes)**:这两类码具有良好的非线性性质,适合于某些特定的应用场景。 - **自对偶码(Self-Dual Codes)**:这类码具有独特的数学性质,在编码理论中占有...
Website_for_pid_codes.7z
标题中的"POWER-ELECTRONIC-SIMULINK-CODES.rar"表明这是一个关于电力电子的Simulink模型代码集合,而"SIMULINK_The Power_matlab si"进一步强调了这是利用Simulink进行电力系统建模和仿真,结合Matlab的工具。...