2014年1月5日 星期日

iOS -- 如何處理撥放的聲音(音量大小、聲音路徑、特效)

當 iOS 設備可以正確的播放聲音之後,後續便可能需要對此聲音作些處理,例如:變更音量大小,設定音量從喇叭或是耳機輸出,或者對於此聲音做些特效。


一、調整音量
建議先取得系統目前的音量設定,做法是使用 AudioQueueGetProperty() 取得 kAudioQueueProperty_CurrentLevelMeter 的值,範例如下:
 1 UInt32 levelSize = sizeof(AudioQueueLevelMeterState) * streamDescription.mChannelsPerFrame;
 2 AudioQueueLevelMeterState *level = (AudioQueueLevelMeterState*)malloc(levelSize);
 3 if (AudioQueueGetProperty(inQueue,
 4                           kAudioQueueProperty_CurrentLevelMeter,
 5                           &levelSize,
 6                           &level) == noErr) {
 7     printf("Current peak: %f", level[0].mPeakPower);
 8 }
接著有兩種方式可用來調整音量 
1. 直接使用 AudioQueueSetParameter() 進行設定
 1 AudioQueueSetParameter(mQueue, kAudioQueueParam_Volume, vVolume);
2. 如果播放的內容是 PCM,則可以直接修改 PCM 內容進行調整,如下
 1 // create short pointers to our byte data
 2 int16_t *inDataShort = (int16_t *)inData;
 3 int16_t *outDataShort = (int16_t *)inData;
 4 
 5 int16_t ampScale = 2;
 6 for (int i = 0; i < fileSize; i++) {
 7     outDataShort[i] = inDataShort[i] / ampScale;
 8 }

二、改變聲音路由
以 iPhone 而言,預設聲音會從手機喇叭輸出,若使用者插入耳機或使用程式改變聲音路由,則聲音將不會從喇叭輸出,此時若想要聲音仍會從喇叭輸出,便需要更改聲音路由。其作法如下:
 1 OSStatus error;
 2 UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker; 
 3 error = AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof (audioRouteOverride), &audioRouteOverride);
 4 if (error) printf("couldn't set audio speaker!");
摘錄原文說明如後:
Constants
kAudioSessionOverrideAudioRoute_None
Specifies, for the kAudioSessionCategory_PlayAndRecord category, that output audio should go to the receiver. This is the default output audio route for this category.
Available in iOS 2.1 and later.
Declared in AudioSession.h.
kAudioSessionOverrideAudioRoute_Speaker
Specifies, for the kAudioSessionCategory_PlayAndRecord category, that output audio should go to the speaker, not the receiver.
Available in iOS 2.1 and later.
Declared in AudioSession.h.

三、聲音特效
這部分處理需要對於聲音有詳盡的了解才能做到,由於個人才疏學淺,因此此處只收集了各種有用的資訊,沒辦法直接提供現成的程式範例。 
要做聲音特效,第一步需要先將聲音格式還原為PCM,如此才方便處理。一般的特效指的是設定為電影,音樂,遊戲等特殊用途。此部分可以直接參考 audacity 所提供的原始碼。 
如果是要改變人的聲音,例如將一段聲音換成男聲、女聲、唐老鴨聲音等等。
則需要調整音高(pitch)與音色(timbre),參考此篇文章,可以聽到聲音經過調整過後的各種效果(分別增減 3, 6, 12 個半音(semitones))。 
另外有個好心人purplelilgirl,提供了一個類似 Toking Tom的程式碼實作範例。

參考資料: