Bug 1175447 - mono audio support. r=padenot, r=sotaro

This patch is to enable mono audio option for those who has full hearing loss in one ear.
With this feature, they can get the complete audio with using one ear.

--HG--
extra : transplant_source : %EC%27%97%1Ai%0D%E3%BC%D0%12%97-K%0Ek%BD%8A%C8%A9%85
This commit is contained in:
Hayden Huang 2015-08-06 14:30:22 +08:00
parent fb94baa0ac
commit 997857d190
9 changed files with 50 additions and 4 deletions

View File

@ -78,6 +78,12 @@ var SettingsListener = {
SettingsListener.init();
// =================== Mono Audio ======================
SettingsListener.observe('accessibility.monoaudio.enable', false, function(value) {
Services.prefs.setBoolPref('accessibility.monoaudio.enable', value);
});
// =================== Console ======================
SettingsListener.observe('debug.console.enabled', true, function(value) {

View File

@ -17,6 +17,7 @@
#include "mozilla/Telemetry.h"
#include "CubebUtils.h"
#include "nsPrintfCString.h"
#include "gfxPrefs.h"
namespace mozilla {
@ -130,6 +131,7 @@ AudioStream::AudioStream()
, mBytesPerFrame(0)
, mState(INITIALIZED)
, mLastGoodPosition(0)
, mIsMonoAudioEnabled(gfxPrefs::MonoAudio())
{
}
@ -421,11 +423,14 @@ AudioStream::Write(const AudioDataValue* aBuf, uint32_t aFrames)
// Downmix to Stereo.
if (mChannels > 2 && mChannels <= 8) {
DownmixAudioToStereo(const_cast<AudioDataValue*> (aBuf), mChannels, aFrames);
}
else if (mChannels > 8) {
} else if (mChannels > 8) {
return NS_ERROR_FAILURE;
}
if (mChannels >= 2 && mIsMonoAudioEnabled) {
DownmixStereoToMono(const_cast<AudioDataValue*> (aBuf), aFrames);
}
const uint8_t* src = reinterpret_cast<const uint8_t*>(aBuf);
uint32_t bytesToCopy = FramesToBytes(aFrames);

View File

@ -325,6 +325,8 @@ private:
// The last good position returned by cubeb_stream_get_position(). Used to
// check if the cubeb position is going backward.
uint64_t mLastGoodPosition;
// Get this value from the preferece, if true, we would downmix the stereo.
bool mIsMonoAudioEnabled;
};
} // namespace mozilla

View File

@ -188,6 +188,23 @@ int DownmixAudioToStereo(mozilla::AudioDataValue* buffer,
return outChannels;
}
void DownmixStereoToMono(mozilla::AudioDataValue* aBuffer,
uint32_t aFrames)
{
MOZ_ASSERT(aBuffer);
const int channels = 2;
for (uint32_t fIdx = 0; fIdx < aFrames; ++fIdx) {
#ifdef MOZ_SAMPLE_TYPE_FLOAT32
float sample = 0.0;
#else
int sample = 0;
#endif
// The sample of the buffer would be interleaved.
sample = (aBuffer[fIdx*channels] + aBuffer[fIdx*channels + 1]) * 0.5;
aBuffer[fIdx*channels] = aBuffer[fIdx*channels + 1] = sample;
}
}
bool
IsVideoContentType(const nsCString& aContentType)
{

View File

@ -168,6 +168,11 @@ int DownmixAudioToStereo(mozilla::AudioDataValue* buffer,
int channels,
uint32_t frames);
// Downmix Stereo audio samples to Mono.
// Input are the buffer contains stereo data and the number of frames.
void DownmixStereoToMono(mozilla::AudioDataValue* aBuffer,
uint32_t aFrames);
bool IsVideoContentType(const nsCString& aContentType);
// Returns true if it's safe to use aPicture as the picture to be

View File

@ -11,6 +11,7 @@
#include "AbstractMediaDecoder.h"
#include "AudioChannelService.h"
#include "MediaStreamSource.h"
#include "gfxPrefs.h"
#ifdef MOZ_AUDIO_OFFLOAD
#include <stagefright/Utils.h>
@ -36,6 +37,11 @@ MediaOmxCommonReader::MediaOmxCommonReader(AbstractMediaDecoder *aDecoder)
mAudioChannel = dom::AudioChannelService::GetDefaultAudioChannel();
}
bool MediaOmxCommonReader::IsMonoAudioEnabled()
{
return gfxPrefs::MonoAudio();
}
#ifdef MOZ_AUDIO_OFFLOAD
void MediaOmxCommonReader::CheckAudioOffload()
{
@ -66,7 +72,8 @@ void MediaOmxCommonReader::CheckAudioOffload()
isNotStreaming, mAudioChannel));
if ((meta.get()) && hasNoVideo && isNotStreaming && isTypeMusic &&
canOffloadStream(meta, false, false, AUDIO_STREAM_MUSIC)) {
canOffloadStream(meta, false, false, AUDIO_STREAM_MUSIC) &&
!IsMonoAudioEnabled()) {
DECODER_LOG(LogLevel::Debug, ("Can offload this audio stream"));
mDecoder->SetPlatformCanOffloadAudio(true);
}

View File

@ -47,6 +47,8 @@ protected:
// Weak reference to the MediaStreamSource that will be created by either
// MediaOmxReader or MediaCodecReader.
android::MediaStreamSource* mStreamSource;
// Get value from the preferece, if true, we stop the audio offload.
bool IsMonoAudioEnabled();
};
} // namespace mozilla

View File

@ -1102,7 +1102,6 @@ AudioManager::AppendProfileToVolumeSetting(const char* aName, AudioOutputProfile
return topic;
}
void
AudioManager::InitVolumeFromDatabase()
{

View File

@ -133,6 +133,9 @@ private:
// We will keep these in an alphabetical order to make it easier to see if
// a method accessing a pref already exists. Just add yours in the list.
// It's a short time fix, and will be removed after landing bug 1206637.
DECL_GFX_PREF(Live, "accessibility.monoaudio.enable", MonoAudio, bool, false);
// The apz prefs are explained in AsyncPanZoomController.cpp
DECL_GFX_PREF(Live, "apz.allow_checkerboarding", APZAllowCheckerboarding, bool, true);
DECL_GFX_PREF(Live, "apz.allow_zooming", APZAllowZooming, bool, false);