handle RAW stereo audio files by using stereo.raw extension

This commit is contained in:
Stephen Birarda 2014-11-19 12:20:12 -08:00
parent c2adc6256e
commit 03bfaa4869
9 changed files with 34 additions and 18 deletions

View file

@ -14,11 +14,10 @@ var position = { x: 700, y: 25, z: 725 };
var audioOptions = { var audioOptions = {
position: position, position: position,
volume: 0.4, volume: 0.4,
loop: true, loop: true
stereo: false
}; };
var sound = SoundCache.getSound(soundURL, audioOptions.isStereo); var sound = SoundCache.getSound(soundURL);
var injector = null; var injector = null;
var count = 100; var count = 100;

View file

@ -12,13 +12,12 @@
Script.include("libraries/globals.js"); Script.include("libraries/globals.js");
var modelURL = HIFI_PUBLIC_BUCKET + "models/entities/radio/Speakers.fbx"; var modelURL = HIFI_PUBLIC_BUCKET + "models/entities/radio/Speakers.fbx";
var soundURL = HIFI_PUBLIC_BUCKET + "sounds/FamilyStereo.raw"; var soundURL = HIFI_PUBLIC_BUCKET + "sounds/family.stereo.raw";
var AudioRotationOffset = Quat.fromPitchYawRollDegrees(0, -90, 0); var AudioRotationOffset = Quat.fromPitchYawRollDegrees(0, -90, 0);
var audioOptions = { var audioOptions = {
volume: 0.5, volume: 0.5,
loop: true, loop: true
stereo: true
} }
var injector = null; var injector = null;

View file

@ -89,10 +89,12 @@ void AudioInjector::injectLocally() {
bool success = false; bool success = false;
if (_localAudioInterface) { if (_localAudioInterface) {
if (_audioData.size() > 0) { if (_audioData.size() > 0) {
_localBuffer = new AudioInjectorLocalBuffer(_audioData, this); _localBuffer = new AudioInjectorLocalBuffer(_audioData, this);
_localBuffer->open(QIODevice::ReadOnly); _localBuffer->open(QIODevice::ReadOnly);
_localBuffer->setShouldLoop(_options.loop); _localBuffer->setShouldLoop(_options.loop);
QMetaObject::invokeMethod(_localAudioInterface, "outputLocalInjector", QMetaObject::invokeMethod(_localAudioInterface, "outputLocalInjector",
Qt::BlockingQueuedConnection, Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, success), Q_RETURN_ARG(bool, success),

View file

@ -26,6 +26,7 @@ public:
void setShouldLoop(bool shouldLoop) { _shouldLoop = shouldLoop; } void setShouldLoop(bool shouldLoop) { _shouldLoop = shouldLoop; }
void setCurrentOffset(int currentOffset) { _currentOffset = currentOffset; }
private: private:
qint64 recursiveReadFromFront(char* data, qint64 maxSize); qint64 recursiveReadFromFront(char* data, qint64 maxSize);

View file

@ -20,7 +20,8 @@ AudioInjectorOptions::AudioInjectorOptions() :
orientation(glm::vec3(0.0f, 0.0f, 0.0f)), orientation(glm::vec3(0.0f, 0.0f, 0.0f)),
stereo(false), stereo(false),
ignorePenumbra(false), ignorePenumbra(false),
localOnly(false) localOnly(false),
secondOffset(0.0)
{ {
} }
@ -31,9 +32,9 @@ QScriptValue injectorOptionsToScriptValue(QScriptEngine* engine, const AudioInje
obj.setProperty("volume", injectorOptions.volume); obj.setProperty("volume", injectorOptions.volume);
obj.setProperty("loop", injectorOptions.loop); obj.setProperty("loop", injectorOptions.loop);
obj.setProperty("orientation", quatToScriptValue(engine, injectorOptions.orientation)); obj.setProperty("orientation", quatToScriptValue(engine, injectorOptions.orientation));
obj.setProperty("stereo", injectorOptions.stereo);
obj.setProperty("ignorePenumbra", injectorOptions.ignorePenumbra); obj.setProperty("ignorePenumbra", injectorOptions.ignorePenumbra);
obj.setProperty("localOnly", injectorOptions.localOnly); obj.setProperty("localOnly", injectorOptions.localOnly);
obj.setProperty("secondOffset", injectorOptions.secondOffset);
return obj; return obj;
} }
@ -54,10 +55,6 @@ void injectorOptionsFromScriptValue(const QScriptValue& object, AudioInjectorOpt
quatFromScriptValue(object.property("orientation"), injectorOptions.orientation); quatFromScriptValue(object.property("orientation"), injectorOptions.orientation);
} }
if (object.property("stereo").isValid()) {
injectorOptions.stereo = object.property("stereo").toBool();
}
if (object.property("ignorePenumbra").isValid()) { if (object.property("ignorePenumbra").isValid()) {
injectorOptions.ignorePenumbra = object.property("ignorePenumbra").toBool(); injectorOptions.ignorePenumbra = object.property("ignorePenumbra").toBool();
} }
@ -65,4 +62,8 @@ void injectorOptionsFromScriptValue(const QScriptValue& object, AudioInjectorOpt
if (object.property("localOnly").isValid()) { if (object.property("localOnly").isValid()) {
injectorOptions.localOnly = object.property("localOnly").toBool(); injectorOptions.localOnly = object.property("localOnly").toBool();
} }
if (object.property("secondOffset").isValid()) {
injectorOptions.secondOffset = object.property("secondOffset").toNumber();
}
} }

View file

@ -27,6 +27,7 @@ public:
bool stereo; bool stereo;
bool ignorePenumbra; bool ignorePenumbra;
bool localOnly; bool localOnly;
float secondOffset;
}; };
Q_DECLARE_METATYPE(AudioInjectorOptions); Q_DECLARE_METATYPE(AudioInjectorOptions);

View file

@ -44,7 +44,11 @@ void AudioScriptingInterface::stopAllInjectors() {
AudioInjector* AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions& injectorOptions) { AudioInjector* AudioScriptingInterface::playSound(Sound* sound, const AudioInjectorOptions& injectorOptions) {
if (sound) { if (sound) {
AudioInjector* injector = new AudioInjector(sound, injectorOptions); // stereo option isn't set from script, this comes from sound metadata or filename
AudioInjectorOptions optionsCopy = injectorOptions;
optionsCopy.stereo = sound->isStereo();
AudioInjector* injector = new AudioInjector(sound, optionsCopy);
injector->setLocalAudioInterface(_localAudioInterface); injector->setLocalAudioInterface(_localAudioInterface);
QThread* injectorThread = new QThread(); QThread* injectorThread = new QThread();

View file

@ -64,7 +64,14 @@ void Sound::downloadFinished(QNetworkReply* reply) {
interpretAsWav(rawAudioByteArray, outputAudioByteArray); interpretAsWav(rawAudioByteArray, outputAudioByteArray);
downSample(outputAudioByteArray); downSample(outputAudioByteArray);
} else { } else {
// Process as RAW file // check if this was a stereo raw file
// since it's raw the only way for us to know that is if the file was called .stereo.raw
if (reply->url().fileName().toLower().endsWith("stereo.raw")) {
_isStereo = true;
qDebug() << "Processing sound from" << reply->url() << "as stereo audio file.";
}
// Process as RAW file
downSample(rawAudioByteArray); downSample(rawAudioByteArray);
} }
trimFrames(); trimFrames();
@ -206,10 +213,12 @@ void Sound::interpretAsWav(const QByteArray& inputAudioByteArray, QByteArray& ou
qDebug() << "Currently not supporting non PCM audio files."; qDebug() << "Currently not supporting non PCM audio files.";
return; return;
} }
if (qFromLittleEndian<quint16>(fileHeader.wave.numChannels) != 1) { if (qFromLittleEndian<quint16>(fileHeader.wave.numChannels) == 2) {
qDebug() << "Currently not supporting stereo audio files."; _isStereo = true;
return; } else if (qFromLittleEndian<quint16>(fileHeader.wave.numChannels) > 2) {
qDebug() << "Currently not support audio files with more than 2 channels.";
} }
if (qFromLittleEndian<quint16>(fileHeader.wave.bitsPerSample) != 16) { if (qFromLittleEndian<quint16>(fileHeader.wave.bitsPerSample) != 16) {
qDebug() << "Currently not supporting non 16bit audio files."; qDebug() << "Currently not supporting non 16bit audio files.";
return; return;

View file

@ -25,7 +25,7 @@ class Sound : public Resource {
public: public:
Sound(const QUrl& url, bool isStereo = false); Sound(const QUrl& url, bool isStereo = false);
bool isStereo() const { return _isStereo; } bool isStereo() const { return _isStereo; }
bool isReady() const { return _isReady; } bool isReady() const { return _isReady; }
const QByteArray& getByteArray() { return _byteArray; } const QByteArray& getByteArray() { return _byteArray; }