Remove pocketsphinx/speech recognition.

This commit is contained in:
Fedor 2020-06-10 21:12:06 +03:00
parent 2d0a568f07
commit b1b822ad39
278 changed files with 38 additions and 351861 deletions

View File

@ -40,12 +40,6 @@ external_dirs += ['media/libwebp']
if CONFIG['CPU_ARCH'] == 'arm':
external_dirs += ['media/openmax_dl']
if CONFIG['MOZ_WEBSPEECH_POCKETSPHINX']:
external_dirs += [
'media/sphinxbase',
'media/pocketsphinx',
]
if CONFIG['MOZ_FFVPX']:
external_dirs += ['media/ffvpx']

View File

@ -70,7 +70,6 @@ LOCAL_INCLUDES += [
'/dom/html',
'/dom/indexedDB',
'/dom/media/webaudio',
'/dom/media/webspeech/recognition',
'/dom/svg',
'/dom/workers',
'/dom/xbl',

View File

@ -1,51 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SpeechRecognitionError.h"
namespace mozilla {
namespace dom {
SpeechRecognitionError::SpeechRecognitionError(
mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent)
: Event(aOwner, aPresContext, aEvent)
, mError()
{
}
SpeechRecognitionError::~SpeechRecognitionError() {}
already_AddRefed<SpeechRecognitionError>
SpeechRecognitionError::Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const SpeechRecognitionErrorInit& aParam,
ErrorResult& aRv)
{
nsCOMPtr<mozilla::dom::EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
RefPtr<SpeechRecognitionError> e = new SpeechRecognitionError(t, nullptr, nullptr);
bool trusted = e->Init(t);
e->InitSpeechRecognitionError(aType, aParam.mBubbles, aParam.mCancelable, aParam.mError, aParam.mMessage);
e->SetTrusted(trusted);
e->SetComposed(aParam.mComposed);
return e.forget();
}
void
SpeechRecognitionError::InitSpeechRecognitionError(const nsAString& aType,
bool aCanBubble,
bool aCancelable,
SpeechRecognitionErrorCode aError,
const nsAString& aMessage)
{
Event::InitEvent(aType, aCanBubble, aCancelable);
mError = aError;
mMessage = aMessage;
}
} // namespace dom
} // namespace mozilla

View File

@ -1,62 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SpeechRecognitionError_h__
#define SpeechRecognitionError_h__
#include "mozilla/dom/Event.h"
#include "mozilla/dom/SpeechRecognitionErrorBinding.h"
namespace mozilla {
namespace dom {
class SpeechRecognitionError : public Event
{
public:
SpeechRecognitionError(mozilla::dom::EventTarget* aOwner,
nsPresContext* aPresContext,
WidgetEvent* aEvent);
virtual ~SpeechRecognitionError();
static already_AddRefed<SpeechRecognitionError>
Constructor(const GlobalObject& aGlobal,
const nsAString& aType,
const SpeechRecognitionErrorInit& aParam,
ErrorResult& aRv);
virtual JSObject* WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override
{
return mozilla::dom::SpeechRecognitionErrorBinding::Wrap(aCx, this, aGivenProto);
}
void
GetMessage(nsAString& aString)
{
aString = mMessage;
}
SpeechRecognitionErrorCode
Error()
{
return mError;
}
void
InitSpeechRecognitionError(const nsAString& aType,
bool aCanBubble,
bool aCancelable,
SpeechRecognitionErrorCode aError,
const nsAString& aMessage);
protected:
SpeechRecognitionErrorCode mError;
nsString mMessage;
};
} // namespace dom
} // namespace mozilla
#endif // SpeechRecognitionError_h__

View File

@ -73,9 +73,6 @@ EXPORTS.mozilla.dom += [
'XULCommandEvent.h',
]
if CONFIG['MOZ_WEBSPEECH']:
EXPORTS.mozilla.dom += ['SpeechRecognitionError.h']
SOURCES += [
'AnimationEvent.cpp',
'AsyncEventDispatcher.cpp',
@ -127,9 +124,6 @@ SOURCES += [
'XULCommandEvent.cpp',
]
if CONFIG['MOZ_WEBSPEECH']:
SOURCES += ['SpeechRecognitionError.cpp']
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'

View File

@ -3,7 +3,10 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS = ['synth']
if CONFIG['MOZ_WEBSPEECH']:
DIRS += ['recognition']
DIRS += ['synth']
else:
IPDL_SOURCES += [
'synth/ipc/PSpeechSynthesis.ipdl',
'synth/ipc/PSpeechSynthesisRequest.ipdl',
]

View File

@ -1,357 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsThreadUtils.h"
#include "nsXPCOMCIDInternal.h"
#include "PocketSphinxSpeechRecognitionService.h"
#include "nsIFile.h"
#include "SpeechGrammar.h"
#include "SpeechRecognition.h"
#include "SpeechRecognitionAlternative.h"
#include "SpeechRecognitionResult.h"
#include "SpeechRecognitionResultList.h"
#include "nsIObserverService.h"
#include "MediaPrefs.h"
#include "mozilla/Services.h"
#include "nsDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsMemory.h"
extern "C" {
#include "pocketsphinx/pocketsphinx.h"
#include "sphinxbase/logmath.h"
#include "sphinxbase/sphinx_config.h"
#include "sphinxbase/jsgf.h"
}
namespace mozilla {
using namespace dom;
class DecodeResultTask : public Runnable
{
public:
DecodeResultTask(const nsString& hypstring,
float64 confidence,
WeakPtr<dom::SpeechRecognition> recognition)
: mResult(hypstring),
mConfidence(confidence),
mRecognition(recognition),
mWorkerThread(do_GetCurrentThread())
{
MOZ_ASSERT(
!NS_IsMainThread()); // This should be running on the worker thread
}
NS_IMETHOD
Run() override
{
MOZ_ASSERT(NS_IsMainThread()); // This method is supposed to run on the main
// thread!
// Declare javascript result events
RefPtr<SpeechEvent> event = new SpeechEvent(
mRecognition, SpeechRecognition::EVENT_RECOGNITIONSERVICE_FINAL_RESULT);
SpeechRecognitionResultList* resultList =
new SpeechRecognitionResultList(mRecognition);
SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition);
if (0 < mRecognition->MaxAlternatives()) {
SpeechRecognitionAlternative* alternative =
new SpeechRecognitionAlternative(mRecognition);
alternative->mTranscript = mResult;
alternative->mConfidence = mConfidence;
result->mItems.AppendElement(alternative);
}
resultList->mItems.AppendElement(result);
event->mRecognitionResultList = resultList;
NS_DispatchToMainThread(event);
// If we don't destroy the thread when we're done with it, it will hang
// around forever... bad!
// But thread->Shutdown must be called from the main thread, not from the
// thread itself.
return mWorkerThread->Shutdown();
}
private:
nsString mResult;
float64 mConfidence;
WeakPtr<dom::SpeechRecognition> mRecognition;
nsCOMPtr<nsIThread> mWorkerThread;
};
class DecodeTask : public Runnable
{
public:
DecodeTask(WeakPtr<dom::SpeechRecognition> recogntion,
const nsTArray<int16_t>& audiovector, ps_decoder_t* ps)
: mRecognition(recogntion), mAudiovector(audiovector), mPs(ps)
{
}
NS_IMETHOD
Run() override
{
char const* hyp;
int rv;
int32 final;
int32 logprob;
float64 confidence;
nsAutoCString hypoValue;
rv = ps_start_utt(mPs);
rv = ps_process_raw(mPs, &mAudiovector[0], mAudiovector.Length(), FALSE,
FALSE);
rv = ps_end_utt(mPs);
confidence = 0;
if (rv >= 0) {
hyp = ps_get_hyp_final(mPs, &final);
if (hyp && final) {
logprob = ps_get_prob(mPs);
confidence = logmath_exp(ps_get_logmath(mPs), logprob);
hypoValue.Assign(hyp);
}
}
nsCOMPtr<nsIRunnable> resultrunnable =
new DecodeResultTask(NS_ConvertUTF8toUTF16(hypoValue), confidence, mRecognition);
return NS_DispatchToMainThread(resultrunnable);
}
private:
WeakPtr<dom::SpeechRecognition> mRecognition;
nsTArray<int16_t> mAudiovector;
ps_decoder_t* mPs;
};
NS_IMPL_ISUPPORTS(PocketSphinxSpeechRecognitionService,
nsISpeechRecognitionService, nsIObserver)
PocketSphinxSpeechRecognitionService::PocketSphinxSpeechRecognitionService()
{
mSpeexState = nullptr;
// get root folder
nsCOMPtr<nsIFile> tmpFile;
nsAutoString aStringAMPath; // am folder
nsAutoString aStringDictPath; // dict folder
NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(tmpFile));
#if defined(XP_WIN) // for some reason, on windows NS_GRE_DIR is not bin root,
// but bin/browser
tmpFile->AppendRelativePath(NS_LITERAL_STRING(".."));
#endif
tmpFile->AppendRelativePath(NS_LITERAL_STRING("models"));
tmpFile->AppendRelativePath(NS_LITERAL_STRING("en-US"));
tmpFile->GetPath(aStringAMPath);
NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(tmpFile));
#if defined(XP_WIN) // for some reason, on windows NS_GRE_DIR is not bin root,
// but bin/browser
tmpFile->AppendRelativePath(NS_LITERAL_STRING(".."));
#endif
tmpFile->AppendRelativePath(NS_LITERAL_STRING("models")); //
tmpFile->AppendRelativePath(NS_LITERAL_STRING("dict")); //
tmpFile->AppendRelativePath(NS_LITERAL_STRING("en-US.dic")); //
tmpFile->GetPath(aStringDictPath);
// FOR B2G PATHS HARDCODED (APPEND /DATA ON THE BEGINING, FOR DESKTOP, ONLY
// MODELS/ RELATIVE TO ROOT
mPSConfig = cmd_ln_init(nullptr, ps_args(), TRUE, "-bestpath", "yes", "-hmm",
ToNewUTF8String(aStringAMPath), // acoustic model
"-dict", ToNewUTF8String(aStringDictPath), nullptr);
if (mPSConfig == nullptr) {
ISDecoderCreated = false;
} else {
mPSHandle = ps_init(mPSConfig);
if (mPSHandle == nullptr) {
ISDecoderCreated = false;
} else {
ISDecoderCreated = true;
}
}
ISGrammarCompiled = false;
}
PocketSphinxSpeechRecognitionService::~PocketSphinxSpeechRecognitionService()
{
if (mPSConfig) {
free(mPSConfig);
}
if (mPSHandle) {
free(mPSHandle);
}
mSpeexState = nullptr;
}
// CALL START IN JS FALLS HERE
NS_IMETHODIMP
PocketSphinxSpeechRecognitionService::Initialize(
WeakPtr<SpeechRecognition> aSpeechRecognition)
{
if (!ISDecoderCreated || !ISGrammarCompiled) {
return NS_ERROR_NOT_INITIALIZED;
} else {
mAudioVector.Clear();
if (mSpeexState) {
mSpeexState = nullptr;
}
mRecognition = aSpeechRecognition;
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
obs->AddObserver(this, SPEECH_RECOGNITION_TEST_EVENT_REQUEST_TOPIC, false);
obs->AddObserver(this, SPEECH_RECOGNITION_TEST_END_TOPIC, false);
return NS_OK;
}
}
NS_IMETHODIMP
PocketSphinxSpeechRecognitionService::ProcessAudioSegment(
AudioSegment* aAudioSegment, int32_t aSampleRate)
{
if (!mSpeexState) {
mSpeexState = speex_resampler_init(1, aSampleRate, 16000,
SPEEX_RESAMPLER_QUALITY_MAX, nullptr);
}
aAudioSegment->ResampleChunks(mSpeexState, aSampleRate, 16000);
AudioSegment::ChunkIterator iterator(*aAudioSegment);
while (!iterator.IsEnded()) {
mozilla::AudioChunk& chunk = *(iterator);
MOZ_ASSERT(chunk.mBuffer);
const int16_t* buf = static_cast<const int16_t*>(chunk.mChannelData[0]);
for (int i = 0; i < iterator->mDuration; i++) {
mAudioVector.AppendElement((int16_t)buf[i]);
}
iterator.Next();
}
return NS_OK;
}
NS_IMETHODIMP
PocketSphinxSpeechRecognitionService::SoundEnd()
{
speex_resampler_destroy(mSpeexState);
mSpeexState = nullptr;
// To create a new thread, get the thread manager
nsCOMPtr<nsIThreadManager> tm = do_GetService(NS_THREADMANAGER_CONTRACTID);
nsCOMPtr<nsIThread> decodethread;
nsresult rv = tm->NewThread(0, 0, getter_AddRefs(decodethread));
if (NS_FAILED(rv)) {
// In case of failure, call back immediately with an empty string which
// indicates failure
return NS_OK;
}
nsCOMPtr<nsIRunnable> r =
new DecodeTask(mRecognition, mAudioVector, mPSHandle);
decodethread->Dispatch(r, nsIEventTarget::DISPATCH_NORMAL);
return NS_OK;
}
NS_IMETHODIMP
PocketSphinxSpeechRecognitionService::ValidateAndSetGrammarList(
SpeechGrammar* aSpeechGrammar,
nsISpeechGrammarCompilationCallback* aCallback)
{
if (!ISDecoderCreated) {
ISGrammarCompiled = false;
} else if (aSpeechGrammar) {
nsAutoString grammar;
ErrorResult rv;
aSpeechGrammar->GetSrc(grammar, rv);
int result = ps_set_jsgf_string(mPSHandle, "name",
NS_ConvertUTF16toUTF8(grammar).get());
if (result != 0) {
ISGrammarCompiled = false;
} else {
ps_set_search(mPSHandle, "name");
ISGrammarCompiled = true;
}
} else {
ISGrammarCompiled = false;
}
return ISGrammarCompiled ? NS_OK : NS_ERROR_NOT_INITIALIZED;
}
NS_IMETHODIMP
PocketSphinxSpeechRecognitionService::Abort()
{
return NS_OK;
}
NS_IMETHODIMP
PocketSphinxSpeechRecognitionService::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
MOZ_ASSERT(MediaPrefs::WebSpeechFakeRecognitionService(),
"Got request to fake recognition service event, "
"but " TEST_PREFERENCE_FAKE_RECOGNITION_SERVICE " is not set");
if (!strcmp(aTopic, SPEECH_RECOGNITION_TEST_END_TOPIC)) {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
obs->RemoveObserver(this, SPEECH_RECOGNITION_TEST_EVENT_REQUEST_TOPIC);
obs->RemoveObserver(this, SPEECH_RECOGNITION_TEST_END_TOPIC);
return NS_OK;
}
const nsDependentString eventName = nsDependentString(aData);
if (eventName.EqualsLiteral("EVENT_RECOGNITIONSERVICE_ERROR")) {
mRecognition->DispatchError(
SpeechRecognition::EVENT_RECOGNITIONSERVICE_ERROR,
SpeechRecognitionErrorCode::Network, // TODO different codes?
NS_LITERAL_STRING("RECOGNITIONSERVICE_ERROR test event"));
} else if (eventName.EqualsLiteral("EVENT_RECOGNITIONSERVICE_FINAL_RESULT")) {
RefPtr<SpeechEvent> event = new SpeechEvent(
mRecognition, SpeechRecognition::EVENT_RECOGNITIONSERVICE_FINAL_RESULT);
event->mRecognitionResultList = BuildMockResultList();
NS_DispatchToMainThread(event);
}
return NS_OK;
}
SpeechRecognitionResultList*
PocketSphinxSpeechRecognitionService::BuildMockResultList()
{
SpeechRecognitionResultList* resultList =
new SpeechRecognitionResultList(mRecognition);
SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition);
if (0 < mRecognition->MaxAlternatives()) {
SpeechRecognitionAlternative* alternative =
new SpeechRecognitionAlternative(mRecognition);
alternative->mTranscript = NS_LITERAL_STRING("Mock final result");
alternative->mConfidence = 0.0f;
result->mItems.AppendElement(alternative);
}
resultList->mItems.AppendElement(result);
return resultList;
}
} // namespace mozilla

View File

@ -1,85 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_PocketSphinxRecognitionService_h
#define mozilla_dom_PocketSphinxRecognitionService_h
#include "nsCOMPtr.h"
#include "nsTArray.h"
#include "nsIObserver.h"
#include "nsISpeechRecognitionService.h"
#include "speex/speex_resampler.h"
extern "C" {
#include <pocketsphinx/pocketsphinx.h>
#include <sphinxbase/sphinx_config.h>
}
#define NS_POCKETSPHINX_SPEECH_RECOGNITION_SERVICE_CID \
{ \
0x0ff5ce56, 0x5b09, 0x4db8, { \
0xad, 0xc6, 0x82, 0x66, 0xaf, 0x95, 0xf8, 0x64 \
} \
};
namespace mozilla {
/**
* Pocketsphix implementation of the nsISpeechRecognitionService interface
*/
class PocketSphinxSpeechRecognitionService : public nsISpeechRecognitionService,
public nsIObserver
{
public:
// Add XPCOM glue code
NS_DECL_ISUPPORTS
NS_DECL_NSISPEECHRECOGNITIONSERVICE
// Add nsIObserver code
NS_DECL_NSIOBSERVER
/**
* Default constructs a PocketSphinxSpeechRecognitionService loading default
* files
*/
PocketSphinxSpeechRecognitionService();
private:
/**
* Private destructor to prevent bypassing of reference counting
*/
virtual ~PocketSphinxSpeechRecognitionService();
/** The associated SpeechRecognition */
WeakPtr<dom::SpeechRecognition> mRecognition;
/**
* Builds a mock SpeechRecognitionResultList
*/
dom::SpeechRecognitionResultList* BuildMockResultList();
/** Speex state */
SpeexResamplerState* mSpeexState;
/** Pocksphix decoder */
ps_decoder_t* mPSHandle;
/** Sphinxbase parsed command line arguments */
cmd_ln_t* mPSConfig;
/** Flag to verify if decoder was created */
bool ISDecoderCreated;
/** Flag to verify if grammar was compiled */
bool ISGrammarCompiled;
/** Audio data */
nsTArray<int16_t> mAudioVector;
};
} // namespace mozilla
#endif

View File

@ -1,81 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SpeechGrammar.h"
#include "mozilla/dom/SpeechGrammarBinding.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SpeechGrammar, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(SpeechGrammar)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechGrammar)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SpeechGrammar)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
SpeechGrammar::SpeechGrammar(nsISupports* aParent)
: mParent(aParent)
{
}
SpeechGrammar::~SpeechGrammar()
{
}
already_AddRefed<SpeechGrammar>
SpeechGrammar::Constructor(const GlobalObject& aGlobal,
ErrorResult& aRv)
{
RefPtr<SpeechGrammar> speechGrammar =
new SpeechGrammar(aGlobal.GetAsSupports());
return speechGrammar.forget();
}
nsISupports*
SpeechGrammar::GetParentObject() const
{
return mParent;
}
JSObject*
SpeechGrammar::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return SpeechGrammarBinding::Wrap(aCx, this, aGivenProto);
}
void
SpeechGrammar::GetSrc(nsString& aRetVal, ErrorResult& aRv) const
{
aRetVal = mSrc;
return;
}
void
SpeechGrammar::SetSrc(const nsAString& aArg, ErrorResult& aRv)
{
mSrc = aArg;
return;
}
float
SpeechGrammar::GetWeight(ErrorResult& aRv) const
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return 0;
}
void
SpeechGrammar::SetWeight(float aArg, ErrorResult& aRv)
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return;
}
} // namespace dom
} // namespace mozilla

View File

@ -1,59 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SpeechGrammar_h
#define mozilla_dom_SpeechGrammar_h
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsString.h"
#include "nsWrapperCache.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
namespace mozilla {
namespace dom {
class GlobalObject;
class SpeechGrammar final : public nsISupports,
public nsWrapperCache
{
public:
explicit SpeechGrammar(nsISupports* aParent);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(SpeechGrammar)
nsISupports* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static already_AddRefed<SpeechGrammar>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
void GetSrc(nsString& aRetVal, ErrorResult& aRv) const;
void SetSrc(const nsAString& aArg, ErrorResult& aRv);
float GetWeight(ErrorResult& aRv) const;
void SetWeight(float aArg, ErrorResult& aRv);
private:
~SpeechGrammar();
nsCOMPtr<nsISupports> mParent;
nsString mSrc;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -1,104 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SpeechGrammarList.h"
#include "mozilla/dom/SpeechGrammarListBinding.h"
#include "mozilla/ErrorResult.h"
#include "nsCOMPtr.h"
#include "nsXPCOMStrings.h"
#include "SpeechGrammar.h"
#include "SpeechRecognition.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SpeechGrammarList, mParent, mItems)
NS_IMPL_CYCLE_COLLECTING_ADDREF(SpeechGrammarList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechGrammarList)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SpeechGrammarList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
SpeechGrammarList::SpeechGrammarList(nsISupports* aParent)
: mParent(aParent)
{
}
SpeechGrammarList::~SpeechGrammarList()
{
}
already_AddRefed<SpeechGrammarList>
SpeechGrammarList::Constructor(const GlobalObject& aGlobal,
ErrorResult& aRv)
{
RefPtr<SpeechGrammarList> speechGrammarList =
new SpeechGrammarList(aGlobal.GetAsSupports());
return speechGrammarList.forget();
}
JSObject*
SpeechGrammarList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return SpeechGrammarListBinding::Wrap(aCx, this, aGivenProto);
}
nsISupports*
SpeechGrammarList::GetParentObject() const
{
return mParent;
}
uint32_t
SpeechGrammarList::Length() const
{
return mItems.Length();
}
already_AddRefed<SpeechGrammar>
SpeechGrammarList::Item(uint32_t aIndex, ErrorResult& aRv)
{
RefPtr<SpeechGrammar> result = mItems.ElementAt(aIndex);
return result.forget();
}
void
SpeechGrammarList::AddFromURI(const nsAString& aSrc,
const Optional<float>& aWeight,
ErrorResult& aRv)
{
aRv.Throw(NS_ERROR_NOT_IMPLEMENTED);
return;
}
void
SpeechGrammarList::AddFromString(const nsAString& aString,
const Optional<float>& aWeight,
ErrorResult& aRv)
{
SpeechGrammar* speechGrammar = new SpeechGrammar(mParent);
speechGrammar->SetSrc(aString, aRv);
mItems.AppendElement(speechGrammar);
return;
}
already_AddRefed<SpeechGrammar>
SpeechGrammarList::IndexedGetter(uint32_t aIndex, bool& aPresent,
ErrorResult& aRv)
{
if (aIndex >= Length()) {
aPresent = false;
return nullptr;
}
ErrorResult rv;
aPresent = true;
return Item(aIndex, rv);
}
} // namespace dom
} // namespace mozilla

View File

@ -1,64 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SpeechGrammarList_h
#define mozilla_dom_SpeechGrammarList_h
#include "mozilla/Attributes.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
struct JSContext;
namespace mozilla {
class ErrorResult;
namespace dom {
class GlobalObject;
class SpeechGrammar;
template<typename> class Optional;
class SpeechGrammarList final : public nsISupports,
public nsWrapperCache
{
public:
explicit SpeechGrammarList(nsISupports* aParent);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(SpeechGrammarList)
static already_AddRefed<SpeechGrammarList> Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
nsISupports* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
uint32_t Length() const;
already_AddRefed<SpeechGrammar> Item(uint32_t aIndex, ErrorResult& aRv);
void AddFromURI(const nsAString& aSrc, const Optional<float>& aWeight, ErrorResult& aRv);
void AddFromString(const nsAString& aString, const Optional<float>& aWeight, ErrorResult& aRv);
already_AddRefed<SpeechGrammar> IndexedGetter(uint32_t aIndex, bool& aPresent, ErrorResult& aRv);
private:
~SpeechGrammarList();
nsCOMPtr<nsISupports> mParent;
nsTArray<RefPtr<SpeechGrammar>> mItems;
};
} // namespace dom
} // namespace mozilla
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,296 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SpeechRecognition_h
#define mozilla_dom_SpeechRecognition_h
#include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsWrapperCache.h"
#include "nsTArray.h"
#include "js/TypeDecls.h"
#include "nsIDOMNavigatorUserMedia.h"
#include "nsITimer.h"
#include "MediaEngine.h"
#include "MediaStreamGraph.h"
#include "AudioSegment.h"
#include "mozilla/WeakPtr.h"
#include "SpeechGrammarList.h"
#include "SpeechRecognitionResultList.h"
#include "SpeechStreamListener.h"
#include "nsISpeechRecognitionService.h"
#include "endpointer.h"
#include "mozilla/dom/SpeechRecognitionError.h"
namespace mozilla {
namespace dom {
#define SPEECH_RECOGNITION_TEST_EVENT_REQUEST_TOPIC "SpeechRecognitionTest:RequestEvent"
#define SPEECH_RECOGNITION_TEST_END_TOPIC "SpeechRecognitionTest:End"
class GlobalObject;
class SpeechEvent;
LogModule* GetSpeechRecognitionLog();
#define SR_LOG(...) MOZ_LOG(GetSpeechRecognitionLog(), mozilla::LogLevel::Debug, (__VA_ARGS__))
class SpeechRecognition final : public DOMEventTargetHelper,
public nsIObserver,
public SupportsWeakPtr<SpeechRecognition>
{
public:
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(SpeechRecognition)
explicit SpeechRecognition(nsPIDOMWindowInner* aOwnerWindow);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SpeechRecognition, DOMEventTargetHelper)
NS_DECL_NSIOBSERVER
nsISupports* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
static bool IsAuthorized(JSContext* aCx, JSObject* aGlobal);
static already_AddRefed<SpeechRecognition>
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
already_AddRefed<SpeechGrammarList> Grammars() const;
void SetGrammars(mozilla::dom::SpeechGrammarList& aArg);
void GetLang(nsString& aRetVal) const;
void SetLang(const nsAString& aArg);
bool GetContinuous(ErrorResult& aRv) const;
void SetContinuous(bool aArg, ErrorResult& aRv);
bool InterimResults() const;
void SetInterimResults(bool aArg);
uint32_t MaxAlternatives() const;
void SetMaxAlternatives(uint32_t aArg);
void GetServiceURI(nsString& aRetVal, ErrorResult& aRv) const;
void SetServiceURI(const nsAString& aArg, ErrorResult& aRv);
void Start(const Optional<NonNull<DOMMediaStream>>& aStream, ErrorResult& aRv);
void Stop();
void Abort();
IMPL_EVENT_HANDLER(audiostart)
IMPL_EVENT_HANDLER(soundstart)
IMPL_EVENT_HANDLER(speechstart)
IMPL_EVENT_HANDLER(speechend)
IMPL_EVENT_HANDLER(soundend)
IMPL_EVENT_HANDLER(audioend)
IMPL_EVENT_HANDLER(result)
IMPL_EVENT_HANDLER(nomatch)
IMPL_EVENT_HANDLER(error)
IMPL_EVENT_HANDLER(start)
IMPL_EVENT_HANDLER(end)
enum EventType {
EVENT_START,
EVENT_STOP,
EVENT_ABORT,
EVENT_AUDIO_DATA,
EVENT_AUDIO_ERROR,
EVENT_RECOGNITIONSERVICE_INTERMEDIATE_RESULT,
EVENT_RECOGNITIONSERVICE_FINAL_RESULT,
EVENT_RECOGNITIONSERVICE_ERROR,
EVENT_COUNT
};
void DispatchError(EventType aErrorType, SpeechRecognitionErrorCode aErrorCode, const nsAString& aMessage);
uint32_t FillSamplesBuffer(const int16_t* aSamples, uint32_t aSampleCount);
uint32_t SplitSamplesBuffer(const int16_t* aSamplesBuffer, uint32_t aSampleCount, nsTArray<RefPtr<SharedBuffer>>& aResult);
AudioSegment* CreateAudioSegment(nsTArray<RefPtr<SharedBuffer>>& aChunks);
void FeedAudioData(already_AddRefed<SharedBuffer> aSamples, uint32_t aDuration, MediaStreamListener* aProvider, TrackRate aTrackRate);
friend class SpeechEvent;
private:
virtual ~SpeechRecognition() {};
enum FSMState {
STATE_IDLE,
STATE_STARTING,
STATE_ESTIMATING,
STATE_WAITING_FOR_SPEECH,
STATE_RECOGNIZING,
STATE_WAITING_FOR_RESULT,
STATE_COUNT
};
void SetState(FSMState state);
bool StateBetween(FSMState begin, FSMState end);
bool SetRecognitionService(ErrorResult& aRv);
bool ValidateAndSetGrammarList(ErrorResult& aRv);
class GetUserMediaSuccessCallback : public nsIDOMGetUserMediaSuccessCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMGETUSERMEDIASUCCESSCALLBACK
explicit GetUserMediaSuccessCallback(SpeechRecognition* aRecognition)
: mRecognition(aRecognition)
{}
private:
virtual ~GetUserMediaSuccessCallback() {}
RefPtr<SpeechRecognition> mRecognition;
};
class GetUserMediaErrorCallback : public nsIDOMGetUserMediaErrorCallback
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMGETUSERMEDIAERRORCALLBACK
explicit GetUserMediaErrorCallback(SpeechRecognition* aRecognition)
: mRecognition(aRecognition)
{}
private:
virtual ~GetUserMediaErrorCallback() {}
RefPtr<SpeechRecognition> mRecognition;
};
NS_IMETHOD StartRecording(DOMMediaStream* aDOMStream);
NS_IMETHOD StopRecording();
uint32_t ProcessAudioSegment(AudioSegment* aSegment, TrackRate aTrackRate);
void NotifyError(SpeechEvent* aEvent);
void ProcessEvent(SpeechEvent* aEvent);
void Transition(SpeechEvent* aEvent);
void Reset();
void ResetAndEnd();
void WaitForAudioData(SpeechEvent* aEvent);
void StartedAudioCapture(SpeechEvent* aEvent);
void StopRecordingAndRecognize(SpeechEvent* aEvent);
void WaitForEstimation(SpeechEvent* aEvent);
void DetectSpeech(SpeechEvent* aEvent);
void WaitForSpeechEnd(SpeechEvent* aEvent);
void NotifyFinalResult(SpeechEvent* aEvent);
void DoNothing(SpeechEvent* aEvent);
void AbortSilently(SpeechEvent* aEvent);
void AbortError(SpeechEvent* aEvent);
RefPtr<DOMMediaStream> mDOMStream;
RefPtr<SpeechStreamListener> mSpeechListener;
nsCOMPtr<nsISpeechRecognitionService> mRecognitionService;
FSMState mCurrentState;
Endpointer mEndpointer;
uint32_t mEstimationSamples;
uint32_t mAudioSamplesPerChunk;
// buffer holds one chunk of mAudioSamplesPerChunk
// samples before feeding it to mEndpointer
RefPtr<SharedBuffer> mAudioSamplesBuffer;
uint32_t mBufferedSamples;
nsCOMPtr<nsITimer> mSpeechDetectionTimer;
bool mAborted;
nsString mLang;
RefPtr<SpeechGrammarList> mSpeechGrammarList;
// WebSpeechAPI (http://bit.ly/1gIl7DC) states:
//
// 1. Default value MUST be false
// 2. If true, interim results SHOULD be returned
// 3. If false, interim results MUST NOT be returned
//
// Pocketsphinx does not return interm results; so, defaulting
// mInterimResults to false, then ignoring its subsequent value
// is a conforming implementation.
bool mInterimResults;
// WebSpeechAPI (http://bit.ly/1JAiqeo) states:
//
// 1. Default value is 1
// 2. Subsequent value is the "maximum number of SpeechRecognitionAlternatives per result"
//
// Pocketsphinx can only return at maximum a single SpeechRecognitionAlternative
// per SpeechRecognitionResult. So defaulting mMaxAlternatives to 1, for all non
// zero values ignoring mMaxAlternatives while for a 0 value returning no
// SpeechRecognitionAlternative per result is a conforming implementation.
uint32_t mMaxAlternatives;
void ProcessTestEventRequest(nsISupports* aSubject, const nsAString& aEventName);
const char* GetName(FSMState aId);
const char* GetName(SpeechEvent* aId);
};
class SpeechEvent : public Runnable
{
public:
SpeechEvent(SpeechRecognition* aRecognition, SpeechRecognition::EventType aType)
: mAudioSegment(0)
, mRecognitionResultList(nullptr)
, mError(nullptr)
, mRecognition(aRecognition)
, mType(aType)
, mTrackRate(0)
{
}
~SpeechEvent();
NS_IMETHOD Run() override;
AudioSegment* mAudioSegment;
RefPtr<SpeechRecognitionResultList> mRecognitionResultList; // TODO: make this a session being passed which also has index and stuff
RefPtr<SpeechRecognitionError> mError;
friend class SpeechRecognition;
private:
SpeechRecognition* mRecognition;
// for AUDIO_DATA events, keep a reference to the provider
// of the data (i.e., the SpeechStreamListener) to ensure it
// is kept alive (and keeps SpeechRecognition alive) until this
// event gets processed.
RefPtr<MediaStreamListener> mProvider;
SpeechRecognition::EventType mType;
TrackRate mTrackRate;
};
} // namespace dom
inline nsISupports*
ToSupports(dom::SpeechRecognition* aRec)
{
return ToSupports(static_cast<DOMEventTargetHelper*>(aRec));
}
} // namespace mozilla
#endif

View File

@ -1,59 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SpeechRecognitionAlternative.h"
#include "mozilla/dom/SpeechRecognitionAlternativeBinding.h"
#include "SpeechRecognition.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SpeechRecognitionAlternative, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(SpeechRecognitionAlternative)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechRecognitionAlternative)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SpeechRecognitionAlternative)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
SpeechRecognitionAlternative::SpeechRecognitionAlternative(SpeechRecognition* aParent)
: mConfidence(0)
, mParent(aParent)
{
}
SpeechRecognitionAlternative::~SpeechRecognitionAlternative()
{
}
JSObject*
SpeechRecognitionAlternative::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return SpeechRecognitionAlternativeBinding::Wrap(aCx, this, aGivenProto);
}
nsISupports*
SpeechRecognitionAlternative::GetParentObject() const
{
return static_cast<DOMEventTargetHelper*>(mParent.get());
}
void
SpeechRecognitionAlternative::GetTranscript(nsString& aRetVal) const
{
aRetVal = mTranscript;
}
float
SpeechRecognitionAlternative::Confidence() const
{
return mConfidence;
}
} // namespace dom
} // namespace mozilla

View File

@ -1,50 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SpeechRecognitionAlternative_h
#define mozilla_dom_SpeechRecognitionAlternative_h
#include "nsCycleCollectionParticipant.h"
#include "nsString.h"
#include "nsWrapperCache.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
namespace mozilla {
namespace dom {
class SpeechRecognition;
class SpeechRecognitionAlternative final : public nsISupports,
public nsWrapperCache
{
public:
explicit SpeechRecognitionAlternative(SpeechRecognition* aParent);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(SpeechRecognitionAlternative)
nsISupports* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void GetTranscript(nsString& aRetVal) const;
float Confidence() const;
nsString mTranscript;
float mConfidence;
private:
~SpeechRecognitionAlternative();
RefPtr<SpeechRecognition> mParent;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -1,76 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SpeechRecognitionResult.h"
#include "mozilla/dom/SpeechRecognitionResultBinding.h"
#include "SpeechRecognition.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SpeechRecognitionResult, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(SpeechRecognitionResult)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechRecognitionResult)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SpeechRecognitionResult)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
SpeechRecognitionResult::SpeechRecognitionResult(SpeechRecognition* aParent)
: mParent(aParent)
{
}
SpeechRecognitionResult::~SpeechRecognitionResult()
{
}
JSObject*
SpeechRecognitionResult::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return SpeechRecognitionResultBinding::Wrap(aCx, this, aGivenProto);
}
nsISupports*
SpeechRecognitionResult::GetParentObject() const
{
return static_cast<DOMEventTargetHelper*>(mParent.get());
}
already_AddRefed<SpeechRecognitionAlternative>
SpeechRecognitionResult::IndexedGetter(uint32_t aIndex, bool& aPresent)
{
if (aIndex >= Length()) {
aPresent = false;
return nullptr;
}
aPresent = true;
return Item(aIndex);
}
uint32_t
SpeechRecognitionResult::Length() const
{
return mItems.Length();
}
already_AddRefed<SpeechRecognitionAlternative>
SpeechRecognitionResult::Item(uint32_t aIndex)
{
RefPtr<SpeechRecognitionAlternative> alternative = mItems.ElementAt(aIndex);
return alternative.forget();
}
bool
SpeechRecognitionResult::IsFinal() const
{
return true; // TODO
}
} // namespace dom
} // namespace mozilla

View File

@ -1,55 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SpeechRecognitionResult_h
#define mozilla_dom_SpeechRecognitionResult_h
#include "nsCOMPtr.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "nsTArray.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "SpeechRecognitionAlternative.h"
namespace mozilla {
namespace dom {
class SpeechRecognitionResult final : public nsISupports,
public nsWrapperCache
{
public:
explicit SpeechRecognitionResult(SpeechRecognition* aParent);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(SpeechRecognitionResult)
nsISupports* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
uint32_t Length() const;
already_AddRefed<SpeechRecognitionAlternative> Item(uint32_t aIndex);
bool IsFinal() const;
already_AddRefed<SpeechRecognitionAlternative> IndexedGetter(uint32_t aIndex, bool& aPresent);
nsTArray<RefPtr<SpeechRecognitionAlternative>> mItems;
private:
~SpeechRecognitionResult();
RefPtr<SpeechRecognition> mParent;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -1,71 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SpeechRecognitionResultList.h"
#include "mozilla/dom/SpeechRecognitionResultListBinding.h"
#include "SpeechRecognition.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SpeechRecognitionResultList, mParent, mItems)
NS_IMPL_CYCLE_COLLECTING_ADDREF(SpeechRecognitionResultList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(SpeechRecognitionResultList)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SpeechRecognitionResultList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
SpeechRecognitionResultList::SpeechRecognitionResultList(SpeechRecognition* aParent)
: mParent(aParent)
{
}
SpeechRecognitionResultList::~SpeechRecognitionResultList()
{
}
nsISupports*
SpeechRecognitionResultList::GetParentObject() const
{
return static_cast<DOMEventTargetHelper*>(mParent.get());
}
JSObject*
SpeechRecognitionResultList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
{
return SpeechRecognitionResultListBinding::Wrap(aCx, this, aGivenProto);
}
already_AddRefed<SpeechRecognitionResult>
SpeechRecognitionResultList::IndexedGetter(uint32_t aIndex, bool& aPresent)
{
if (aIndex >= Length()) {
aPresent = false;
return nullptr;
}
aPresent = true;
return Item(aIndex);
}
uint32_t
SpeechRecognitionResultList::Length() const
{
return mItems.Length();
}
already_AddRefed<SpeechRecognitionResult>
SpeechRecognitionResultList::Item(uint32_t aIndex)
{
RefPtr<SpeechRecognitionResult> result = mItems.ElementAt(aIndex);
return result.forget();
}
} // namespace dom
} // namespace mozilla

View File

@ -1,53 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SpeechRecognitionResultList_h
#define mozilla_dom_SpeechRecognitionResultList_h
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
#include "nsTArray.h"
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "SpeechRecognitionResult.h"
namespace mozilla {
namespace dom {
class SpeechRecognition;
class SpeechRecognitionResultList final : public nsISupports,
public nsWrapperCache
{
public:
explicit SpeechRecognitionResultList(SpeechRecognition* aParent);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(SpeechRecognitionResultList)
nsISupports* GetParentObject() const;
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
uint32_t Length() const;
already_AddRefed<SpeechRecognitionResult> Item(uint32_t aIndex);
already_AddRefed<SpeechRecognitionResult> IndexedGetter(uint32_t aIndex, bool& aPresent);
nsTArray<RefPtr<SpeechRecognitionResult>> mItems;
private:
~SpeechRecognitionResultList();
RefPtr<SpeechRecognition> mParent;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -1,94 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SpeechStreamListener.h"
#include "SpeechRecognition.h"
#include "nsProxyRelease.h"
namespace mozilla {
namespace dom {
SpeechStreamListener::SpeechStreamListener(SpeechRecognition* aRecognition)
: mRecognition(aRecognition)
{
}
SpeechStreamListener::~SpeechStreamListener()
{
nsCOMPtr<nsIThread> mainThread;
NS_GetMainThread(getter_AddRefs(mainThread));
NS_ProxyRelease(mainThread, mRecognition.forget());
}
void
SpeechStreamListener::NotifyQueuedAudioData(MediaStreamGraph* aGraph, TrackID aID,
StreamTime aTrackOffset,
const AudioSegment& aQueuedMedia,
MediaStream* aInputStream,
TrackID aInputTrackID)
{
AudioSegment* audio = const_cast<AudioSegment*>(
static_cast<const AudioSegment*>(&aQueuedMedia));
AudioSegment::ChunkIterator iterator(*audio);
while (!iterator.IsEnded()) {
// Skip over-large chunks so we don't crash!
if (iterator->GetDuration() > INT_MAX) {
continue;
}
int duration = int(iterator->GetDuration());
if (iterator->IsNull()) {
nsTArray<int16_t> nullData;
PodZero(nullData.AppendElements(duration), duration);
ConvertAndDispatchAudioChunk(duration, iterator->mVolume,
nullData.Elements(), aGraph->GraphRate());
} else {
AudioSampleFormat format = iterator->mBufferFormat;
MOZ_ASSERT(format == AUDIO_FORMAT_S16 || format == AUDIO_FORMAT_FLOAT32);
if (format == AUDIO_FORMAT_S16) {
ConvertAndDispatchAudioChunk(duration,iterator->mVolume,
static_cast<const int16_t*>(iterator->mChannelData[0]),
aGraph->GraphRate());
} else if (format == AUDIO_FORMAT_FLOAT32) {
ConvertAndDispatchAudioChunk(duration,iterator->mVolume,
static_cast<const float*>(iterator->mChannelData[0]),
aGraph->GraphRate());
}
}
iterator.Next();
}
}
template<typename SampleFormatType> void
SpeechStreamListener::ConvertAndDispatchAudioChunk(int aDuration, float aVolume,
SampleFormatType* aData,
TrackRate aTrackRate)
{
RefPtr<SharedBuffer> samples(SharedBuffer::Create(aDuration *
1 * // channel
sizeof(int16_t)));
int16_t* to = static_cast<int16_t*>(samples->Data());
ConvertAudioSamplesWithScale(aData, to, aDuration, aVolume);
mRecognition->FeedAudioData(samples.forget(), aDuration, this, aTrackRate);
}
void
SpeechStreamListener::NotifyEvent(MediaStreamGraph* aGraph,
MediaStreamGraphEvent event)
{
// TODO dispatch SpeechEnd event so services can be informed
}
} // namespace dom
} // namespace mozilla

View File

@ -1,46 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_SpeechStreamListener_h
#define mozilla_dom_SpeechStreamListener_h
#include "MediaStreamGraph.h"
#include "MediaStreamListener.h"
#include "AudioSegment.h"
namespace mozilla {
class AudioSegment;
namespace dom {
class SpeechRecognition;
class SpeechStreamListener : public MediaStreamListener
{
public:
explicit SpeechStreamListener(SpeechRecognition* aRecognition);
~SpeechStreamListener();
void NotifyQueuedAudioData(MediaStreamGraph* aGraph, TrackID aID,
StreamTime aTrackOffset,
const AudioSegment& aQueuedMedia,
MediaStream* aInputStream,
TrackID aInputTrackID) override;
void NotifyEvent(MediaStreamGraph* aGraph,
MediaStreamGraphEvent event) override;
private:
template<typename SampleFormatType>
void ConvertAndDispatchAudioChunk(int aDuration, float aVolume, SampleFormatType* aData, TrackRate aTrackRate);
RefPtr<SpeechRecognition> mRecognition;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -1,193 +0,0 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "endpointer.h"
#include "AudioSegment.h"
namespace {
const int kFrameRate = 200; // 1 frame = 5ms of audio.
}
namespace mozilla {
Endpointer::Endpointer(int sample_rate)
: speech_input_possibly_complete_silence_length_us_(-1),
speech_input_complete_silence_length_us_(-1),
audio_frame_time_us_(0),
sample_rate_(sample_rate),
frame_size_(0) {
Reset();
frame_size_ = static_cast<int>(sample_rate / static_cast<float>(kFrameRate));
speech_input_minimum_length_us_ =
static_cast<int64_t>(1.7 * 1000000);
speech_input_complete_silence_length_us_ =
static_cast<int64_t>(0.5 * 1000000);
long_speech_input_complete_silence_length_us_ = -1;
long_speech_length_us_ = -1;
speech_input_possibly_complete_silence_length_us_ =
1 * 1000000;
// Set the default configuration for Push To Talk mode.
EnergyEndpointerParams ep_config;
ep_config.set_frame_period(1.0f / static_cast<float>(kFrameRate));
ep_config.set_frame_duration(1.0f / static_cast<float>(kFrameRate));
ep_config.set_endpoint_margin(0.2f);
ep_config.set_onset_window(0.15f);
ep_config.set_speech_on_window(0.4f);
ep_config.set_offset_window(0.15f);
ep_config.set_onset_detect_dur(0.09f);
ep_config.set_onset_confirm_dur(0.075f);
ep_config.set_on_maintain_dur(0.10f);
ep_config.set_offset_confirm_dur(0.12f);
ep_config.set_decision_threshold(1000.0f);
ep_config.set_min_decision_threshold(50.0f);
ep_config.set_fast_update_dur(0.2f);
ep_config.set_sample_rate(static_cast<float>(sample_rate));
ep_config.set_min_fundamental_frequency(57.143f);
ep_config.set_max_fundamental_frequency(400.0f);
ep_config.set_contamination_rejection_period(0.25f);
energy_endpointer_.Init(ep_config);
}
void Endpointer::Reset() {
old_ep_status_ = EP_PRE_SPEECH;
waiting_for_speech_possibly_complete_timeout_ = false;
waiting_for_speech_complete_timeout_ = false;
speech_previously_detected_ = false;
speech_input_complete_ = false;
audio_frame_time_us_ = 0; // Reset time for packets sent to endpointer.
speech_end_time_us_ = -1;
speech_start_time_us_ = -1;
}
void Endpointer::StartSession() {
Reset();
energy_endpointer_.StartSession();
}
void Endpointer::EndSession() {
energy_endpointer_.EndSession();
}
void Endpointer::SetEnvironmentEstimationMode() {
Reset();
energy_endpointer_.SetEnvironmentEstimationMode();
}
void Endpointer::SetUserInputMode() {
energy_endpointer_.SetUserInputMode();
}
EpStatus Endpointer::Status(int64_t *time) {
return energy_endpointer_.Status(time);
}
EpStatus Endpointer::ProcessAudio(const AudioChunk& raw_audio, float* rms_out) {
MOZ_ASSERT(raw_audio.mBufferFormat == AUDIO_FORMAT_S16, "Audio is not in 16 bit format");
const int16_t* audio_data = static_cast<const int16_t*>(raw_audio.mChannelData[0]);
const int num_samples = raw_audio.mDuration;
EpStatus ep_status = EP_PRE_SPEECH;
// Process the input data in blocks of frame_size_, dropping any incomplete
// frames at the end (which is ok since typically the caller will be recording
// audio in multiples of our frame size).
int sample_index = 0;
while (sample_index + frame_size_ <= num_samples) {
// Have the endpointer process the frame.
energy_endpointer_.ProcessAudioFrame(audio_frame_time_us_,
audio_data + sample_index,
frame_size_,
rms_out);
sample_index += frame_size_;
audio_frame_time_us_ += (frame_size_ * 1000000) /
sample_rate_;
// Get the status of the endpointer.
int64_t ep_time;
ep_status = energy_endpointer_.Status(&ep_time);
if (old_ep_status_ != ep_status)
fprintf(stderr, "Status changed old= %d, new= %d\n", old_ep_status_, ep_status);
// Handle state changes.
if ((EP_SPEECH_PRESENT == ep_status) &&
(EP_POSSIBLE_ONSET == old_ep_status_)) {
speech_end_time_us_ = -1;
waiting_for_speech_possibly_complete_timeout_ = false;
waiting_for_speech_complete_timeout_ = false;
// Trigger SpeechInputDidStart event on first detection.
if (false == speech_previously_detected_) {
speech_previously_detected_ = true;
speech_start_time_us_ = ep_time;
}
}
if ((EP_PRE_SPEECH == ep_status) &&
(EP_POSSIBLE_OFFSET == old_ep_status_)) {
speech_end_time_us_ = ep_time;
waiting_for_speech_possibly_complete_timeout_ = true;
waiting_for_speech_complete_timeout_ = true;
}
if (ep_time > speech_input_minimum_length_us_) {
// Speech possibly complete timeout.
if ((waiting_for_speech_possibly_complete_timeout_) &&
(ep_time - speech_end_time_us_ >
speech_input_possibly_complete_silence_length_us_)) {
waiting_for_speech_possibly_complete_timeout_ = false;
}
if (waiting_for_speech_complete_timeout_) {
// The length of the silence timeout period can be held constant, or it
// can be changed after a fixed amount of time from the beginning of
// speech.
bool has_stepped_silence =
(long_speech_length_us_ > 0) &&
(long_speech_input_complete_silence_length_us_ > 0);
int64_t requested_silence_length;
if (has_stepped_silence &&
(ep_time - speech_start_time_us_) > long_speech_length_us_) {
requested_silence_length =
long_speech_input_complete_silence_length_us_;
} else {
requested_silence_length =
speech_input_complete_silence_length_us_;
}
// Speech complete timeout.
if ((ep_time - speech_end_time_us_) > requested_silence_length) {
waiting_for_speech_complete_timeout_ = false;
speech_input_complete_ = true;
}
}
}
old_ep_status_ = ep_status;
}
return ep_status;
}
} // namespace mozilla

View File

@ -1,180 +0,0 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONTENT_BROWSER_SPEECH_ENDPOINTER_ENDPOINTER_H_
#define CONTENT_BROWSER_SPEECH_ENDPOINTER_ENDPOINTER_H_
#include "energy_endpointer.h"
namespace mozilla {
struct AudioChunk;
// A simple interface to the underlying energy-endpointer implementation, this
// class lets callers provide audio as being recorded and let them poll to find
// when the user has stopped speaking.
//
// There are two events that may trigger the end of speech:
//
// speechInputPossiblyComplete event:
//
// Signals that silence/noise has been detected for a *short* amount of
// time after some speech has been detected. It can be used for low latency
// UI feedback. To disable it, set it to a large amount.
//
// speechInputComplete event:
//
// This event is intended to signal end of input and to stop recording.
// The amount of time to wait after speech is set by
// speech_input_complete_silence_length_ and optionally two other
// parameters (see below).
// This time can be held constant, or can change as more speech is detected.
// In the latter case, the time changes after a set amount of time from the
// *beginning* of speech. This is motivated by the expectation that there
// will be two distinct types of inputs: short search queries and longer
// dictation style input.
//
// Three parameters are used to define the piecewise constant timeout function.
// The timeout length is speech_input_complete_silence_length until
// long_speech_length, when it changes to
// long_speech_input_complete_silence_length.
class Endpointer {
public:
explicit Endpointer(int sample_rate);
// Start the endpointer. This should be called at the beginning of a session.
void StartSession();
// Stop the endpointer.
void EndSession();
// Start environment estimation. Audio will be used for environment estimation
// i.e. noise level estimation.
void SetEnvironmentEstimationMode();
// Start user input. This should be called when the user indicates start of
// input, e.g. by pressing a button.
void SetUserInputMode();
// Process a segment of audio, which may be more than one frame.
// The status of the last frame will be returned.
EpStatus ProcessAudio(const AudioChunk& raw_audio, float* rms_out);
// Get the status of the endpointer.
EpStatus Status(int64_t *time_us);
// Get the expected frame size for audio chunks. Audio chunks are expected
// to contain a number of samples that is a multiple of this number, and extra
// samples will be dropped.
int32_t FrameSize() const {
return frame_size_;
}
// Returns true if the endpointer detected reasonable audio levels above
// background noise which could be user speech, false if not.
bool DidStartReceivingSpeech() const {
return speech_previously_detected_;
}
bool IsEstimatingEnvironment() const {
return energy_endpointer_.estimating_environment();
}
void set_speech_input_complete_silence_length(int64_t time_us) {
speech_input_complete_silence_length_us_ = time_us;
}
void set_long_speech_input_complete_silence_length(int64_t time_us) {
long_speech_input_complete_silence_length_us_ = time_us;
}
void set_speech_input_possibly_complete_silence_length(int64_t time_us) {
speech_input_possibly_complete_silence_length_us_ = time_us;
}
void set_long_speech_length(int64_t time_us) {
long_speech_length_us_ = time_us;
}
bool speech_input_complete() const {
return speech_input_complete_;
}
// RMS background noise level in dB.
float NoiseLevelDb() const { return energy_endpointer_.GetNoiseLevelDb(); }
private:
// Reset internal states. Helper method common to initial input utterance
// and following input utternaces.
void Reset();
// Minimum allowable length of speech input.
int64_t speech_input_minimum_length_us_;
// The speechInputPossiblyComplete event signals that silence/noise has been
// detected for a *short* amount of time after some speech has been detected.
// This proporty specifies the time period.
int64_t speech_input_possibly_complete_silence_length_us_;
// The speechInputComplete event signals that silence/noise has been
// detected for a *long* amount of time after some speech has been detected.
// This property specifies the time period.
int64_t speech_input_complete_silence_length_us_;
// Same as above, this specifies the required silence period after speech
// detection. This period is used instead of
// speech_input_complete_silence_length_ when the utterance is longer than
// long_speech_length_. This parameter is optional.
int64_t long_speech_input_complete_silence_length_us_;
// The period of time after which the endpointer should consider
// long_speech_input_complete_silence_length_ as a valid silence period
// instead of speech_input_complete_silence_length_. This parameter is
// optional.
int64_t long_speech_length_us_;
// First speech onset time, used in determination of speech complete timeout.
int64_t speech_start_time_us_;
// Most recent end time, used in determination of speech complete timeout.
int64_t speech_end_time_us_;
int64_t audio_frame_time_us_;
EpStatus old_ep_status_;
bool waiting_for_speech_possibly_complete_timeout_;
bool waiting_for_speech_complete_timeout_;
bool speech_previously_detected_;
bool speech_input_complete_;
EnergyEndpointer energy_endpointer_;
int sample_rate_;
int32_t frame_size_;
};
} // namespace mozilla
#endif // CONTENT_BROWSER_SPEECH_ENDPOINTER_ENDPOINTER_H_

View File

@ -1,393 +0,0 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "energy_endpointer.h"
#include <math.h>
namespace {
// Returns the RMS (quadratic mean) of the input signal.
float RMS(const int16_t* samples, int num_samples) {
int64_t ssq_int64_t = 0;
int64_t sum_int64_t = 0;
for (int i = 0; i < num_samples; ++i) {
sum_int64_t += samples[i];
ssq_int64_t += samples[i] * samples[i];
}
// now convert to floats.
double sum = static_cast<double>(sum_int64_t);
sum /= num_samples;
double ssq = static_cast<double>(ssq_int64_t);
return static_cast<float>(sqrt((ssq / num_samples) - (sum * sum)));
}
int64_t Secs2Usecs(float seconds) {
return static_cast<int64_t>(0.5 + (1.0e6 * seconds));
}
float GetDecibel(float value) {
if (value > 1.0e-100)
return 20 * log10(value);
return -2000.0;
}
} // namespace
namespace mozilla {
// Stores threshold-crossing histories for making decisions about the speech
// state.
class EnergyEndpointer::HistoryRing {
public:
HistoryRing() : insertion_index_(0) {}
// Resets the ring to |size| elements each with state |initial_state|
void SetRing(int size, bool initial_state);
// Inserts a new entry into the ring and drops the oldest entry.
void Insert(int64_t time_us, bool decision);
// Returns the time in microseconds of the most recently added entry.
int64_t EndTime() const;
// Returns the sum of all intervals during which 'decision' is true within
// the time in seconds specified by 'duration'. The returned interval is
// in seconds.
float RingSum(float duration_sec);
private:
struct DecisionPoint {
int64_t time_us;
bool decision;
};
std::vector<DecisionPoint> decision_points_;
int insertion_index_; // Index at which the next item gets added/inserted.
HistoryRing(const HistoryRing&);
void operator=(const HistoryRing&);
};
void EnergyEndpointer::HistoryRing::SetRing(int size, bool initial_state) {
insertion_index_ = 0;
decision_points_.clear();
DecisionPoint init = { -1, initial_state };
decision_points_.resize(size, init);
}
void EnergyEndpointer::HistoryRing::Insert(int64_t time_us, bool decision) {
decision_points_[insertion_index_].time_us = time_us;
decision_points_[insertion_index_].decision = decision;
insertion_index_ = (insertion_index_ + 1) % decision_points_.size();
}
int64_t EnergyEndpointer::HistoryRing::EndTime() const {
int ind = insertion_index_ - 1;
if (ind < 0)
ind = decision_points_.size() - 1;
return decision_points_[ind].time_us;
}
float EnergyEndpointer::HistoryRing::RingSum(float duration_sec) {
if (!decision_points_.size())
return 0.0;
int64_t sum_us = 0;
int ind = insertion_index_ - 1;
if (ind < 0)
ind = decision_points_.size() - 1;
int64_t end_us = decision_points_[ind].time_us;
bool is_on = decision_points_[ind].decision;
int64_t start_us = end_us - static_cast<int64_t>(0.5 + (1.0e6 * duration_sec));
if (start_us < 0)
start_us = 0;
size_t n_summed = 1; // n points ==> (n-1) intervals
while ((decision_points_[ind].time_us > start_us) &&
(n_summed < decision_points_.size())) {
--ind;
if (ind < 0)
ind = decision_points_.size() - 1;
if (is_on)
sum_us += end_us - decision_points_[ind].time_us;
is_on = decision_points_[ind].decision;
end_us = decision_points_[ind].time_us;
n_summed++;
}
return 1.0e-6f * sum_us; // Returns total time that was super threshold.
}
EnergyEndpointer::EnergyEndpointer()
: status_(EP_PRE_SPEECH),
offset_confirm_dur_sec_(0),
endpointer_time_us_(0),
fast_update_frames_(0),
frame_counter_(0),
max_window_dur_(4.0),
sample_rate_(0),
history_(new HistoryRing()),
decision_threshold_(0),
estimating_environment_(false),
noise_level_(0),
rms_adapt_(0),
start_lag_(0),
end_lag_(0),
user_input_start_time_us_(0) {
}
EnergyEndpointer::~EnergyEndpointer() {
}
int EnergyEndpointer::TimeToFrame(float time) const {
return static_cast<int32_t>(0.5 + (time / params_.frame_period()));
}
void EnergyEndpointer::Restart(bool reset_threshold) {
status_ = EP_PRE_SPEECH;
user_input_start_time_us_ = 0;
if (reset_threshold) {
decision_threshold_ = params_.decision_threshold();
rms_adapt_ = decision_threshold_;
noise_level_ = params_.decision_threshold() / 2.0f;
frame_counter_ = 0; // Used for rapid initial update of levels.
}
// Set up the memories to hold the history windows.
history_->SetRing(TimeToFrame(max_window_dur_), false);
// Flag that indicates that current input should be used for
// estimating the environment. The user has not yet started input
// by e.g. pressed the push-to-talk button. By default, this is
// false for backward compatibility.
estimating_environment_ = false;
}
void EnergyEndpointer::Init(const EnergyEndpointerParams& params) {
params_ = params;
// Find the longest history interval to be used, and make the ring
// large enough to accommodate that number of frames. NOTE: This
// depends upon ep_frame_period being set correctly in the factory
// that did this instantiation.
max_window_dur_ = params_.onset_window();
if (params_.speech_on_window() > max_window_dur_)
max_window_dur_ = params_.speech_on_window();
if (params_.offset_window() > max_window_dur_)
max_window_dur_ = params_.offset_window();
Restart(true);
offset_confirm_dur_sec_ = params_.offset_window() -
params_.offset_confirm_dur();
if (offset_confirm_dur_sec_ < 0.0)
offset_confirm_dur_sec_ = 0.0;
user_input_start_time_us_ = 0;
// Flag that indicates that current input should be used for
// estimating the environment. The user has not yet started input
// by e.g. pressed the push-to-talk button. By default, this is
// false for backward compatibility.
estimating_environment_ = false;
// The initial value of the noise and speech levels is inconsequential.
// The level of the first frame will overwrite these values.
noise_level_ = params_.decision_threshold() / 2.0f;
fast_update_frames_ =
static_cast<int64_t>(params_.fast_update_dur() / params_.frame_period());
frame_counter_ = 0; // Used for rapid initial update of levels.
sample_rate_ = params_.sample_rate();
start_lag_ = static_cast<int>(sample_rate_ /
params_.max_fundamental_frequency());
end_lag_ = static_cast<int>(sample_rate_ /
params_.min_fundamental_frequency());
}
void EnergyEndpointer::StartSession() {
Restart(true);
}
void EnergyEndpointer::EndSession() {
status_ = EP_POST_SPEECH;
}
void EnergyEndpointer::SetEnvironmentEstimationMode() {
Restart(true);
estimating_environment_ = true;
}
void EnergyEndpointer::SetUserInputMode() {
estimating_environment_ = false;
user_input_start_time_us_ = endpointer_time_us_;
}
void EnergyEndpointer::ProcessAudioFrame(int64_t time_us,
const int16_t* samples,
int num_samples,
float* rms_out) {
endpointer_time_us_ = time_us;
float rms = RMS(samples, num_samples);
// Check that this is user input audio vs. pre-input adaptation audio.
// Input audio starts when the user indicates start of input, by e.g.
// pressing push-to-talk. Audio recieved prior to that is used to update
// noise and speech level estimates.
if (!estimating_environment_) {
bool decision = false;
if ((endpointer_time_us_ - user_input_start_time_us_) <
Secs2Usecs(params_.contamination_rejection_period())) {
decision = false;
//PR_LOG(GetSpeechRecognitionLog(), PR_LOG_DEBUG, ("decision: forced to false, time: %d", endpointer_time_us_));
} else {
decision = (rms > decision_threshold_);
}
history_->Insert(endpointer_time_us_, decision);
switch (status_) {
case EP_PRE_SPEECH:
if (history_->RingSum(params_.onset_window()) >
params_.onset_detect_dur()) {
status_ = EP_POSSIBLE_ONSET;
}
break;
case EP_POSSIBLE_ONSET: {
float tsum = history_->RingSum(params_.onset_window());
if (tsum > params_.onset_confirm_dur()) {
status_ = EP_SPEECH_PRESENT;
} else { // If signal is not maintained, drop back to pre-speech.
if (tsum <= params_.onset_detect_dur())
status_ = EP_PRE_SPEECH;
}
break;
}
case EP_SPEECH_PRESENT: {
// To induce hysteresis in the state residency, we allow a
// smaller residency time in the on_ring, than was required to
// enter the SPEECH_PERSENT state.
float on_time = history_->RingSum(params_.speech_on_window());
if (on_time < params_.on_maintain_dur())
status_ = EP_POSSIBLE_OFFSET;
break;
}
case EP_POSSIBLE_OFFSET:
if (history_->RingSum(params_.offset_window()) <=
offset_confirm_dur_sec_) {
// Note that this offset time may be beyond the end
// of the input buffer in a real-time system. It will be up
// to the RecognizerSession to decide what to do.
status_ = EP_PRE_SPEECH; // Automatically reset for next utterance.
} else { // If speech picks up again we allow return to SPEECH_PRESENT.
if (history_->RingSum(params_.speech_on_window()) >=
params_.on_maintain_dur())
status_ = EP_SPEECH_PRESENT;
}
break;
default:
break;
}
// If this is a quiet, non-speech region, slowly adapt the detection
// threshold to be about 6dB above the average RMS.
if ((!decision) && (status_ == EP_PRE_SPEECH)) {
decision_threshold_ = (0.98f * decision_threshold_) + (0.02f * 2 * rms);
rms_adapt_ = decision_threshold_;
} else {
// If this is in a speech region, adapt the decision threshold to
// be about 10dB below the average RMS. If the noise level is high,
// the threshold is pushed up.
// Adaptation up to a higher level is 5 times faster than decay to
// a lower level.
if ((status_ == EP_SPEECH_PRESENT) && decision) {
if (rms_adapt_ > rms) {
rms_adapt_ = (0.99f * rms_adapt_) + (0.01f * rms);
} else {
rms_adapt_ = (0.95f * rms_adapt_) + (0.05f * rms);
}
float target_threshold = 0.3f * rms_adapt_ + noise_level_;
decision_threshold_ = (.90f * decision_threshold_) +
(0.10f * target_threshold);
}
}
// Set a floor
if (decision_threshold_ < params_.min_decision_threshold())
decision_threshold_ = params_.min_decision_threshold();
}
// Update speech and noise levels.
UpdateLevels(rms);
++frame_counter_;
if (rms_out)
*rms_out = GetDecibel(rms);
}
float EnergyEndpointer::GetNoiseLevelDb() const {
return GetDecibel(noise_level_);
}
void EnergyEndpointer::UpdateLevels(float rms) {
// Update quickly initially. We assume this is noise and that
// speech is 6dB above the noise.
if (frame_counter_ < fast_update_frames_) {
// Alpha increases from 0 to (k-1)/k where k is the number of time
// steps in the initial adaptation period.
float alpha = static_cast<float>(frame_counter_) /
static_cast<float>(fast_update_frames_);
noise_level_ = (alpha * noise_level_) + ((1 - alpha) * rms);
//PR_LOG(GetSpeechRecognitionLog(), PR_LOG_DEBUG, ("FAST UPDATE, frame_counter_ %d, fast_update_frames_ %d", frame_counter_, fast_update_frames_));
} else {
// Update Noise level. The noise level adapts quickly downward, but
// slowly upward. The noise_level_ parameter is not currently used
// for threshold adaptation. It is used for UI feedback.
if (noise_level_ < rms)
noise_level_ = (0.999f * noise_level_) + (0.001f * rms);
else
noise_level_ = (0.95f * noise_level_) + (0.05f * rms);
}
if (estimating_environment_ || (frame_counter_ < fast_update_frames_)) {
decision_threshold_ = noise_level_ * 2; // 6dB above noise level.
// Set a floor
if (decision_threshold_ < params_.min_decision_threshold())
decision_threshold_ = params_.min_decision_threshold();
}
}
EpStatus EnergyEndpointer::Status(int64_t* status_time) const {
*status_time = history_->EndTime();
return status_;
}
} // namespace mozilla

View File

@ -1,180 +0,0 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The EnergyEndpointer class finds likely speech onset and offset points.
//
// The implementation described here is about the simplest possible.
// It is based on timings of threshold crossings for overall signal
// RMS. It is suitable for light weight applications.
//
// As written, the basic idea is that one specifies intervals that
// must be occupied by super- and sub-threshold energy levels, and
// defers decisions re onset and offset times until these
// specifications have been met. Three basic intervals are tested: an
// onset window, a speech-on window, and an offset window. We require
// super-threshold to exceed some mimimum total durations in the onset
// and speech-on windows before declaring the speech onset time, and
// we specify a required sub-threshold residency in the offset window
// before declaring speech offset. As the various residency requirements are
// met, the EnergyEndpointer instance assumes various states, and can return the
// ID of these states to the client (see EpStatus below).
//
// The levels of the speech and background noise are continuously updated. It is
// important that the background noise level be estimated initially for
// robustness in noisy conditions. The first frames are assumed to be background
// noise and a fast update rate is used for the noise level. The duration for
// fast update is controlled by the fast_update_dur_ paramter.
//
// If used in noisy conditions, the endpointer should be started and run in the
// EnvironmentEstimation mode, for at least 200ms, before switching to
// UserInputMode.
// Audio feedback contamination can appear in the input audio, if not cut
// out or handled by echo cancellation. Audio feedback can trigger a false
// accept. The false accepts can be ignored by setting
// ep_contamination_rejection_period.
#ifndef CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_H_
#define CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_H_
#include <vector>
#include "nsAutoPtr.h"
#include "energy_endpointer_params.h"
namespace mozilla {
// Endpointer status codes
enum EpStatus {
EP_PRE_SPEECH = 10,
EP_POSSIBLE_ONSET,
EP_SPEECH_PRESENT,
EP_POSSIBLE_OFFSET,
EP_POST_SPEECH,
};
class EnergyEndpointer {
public:
// The default construction MUST be followed by Init(), before any
// other use can be made of the instance.
EnergyEndpointer();
virtual ~EnergyEndpointer();
void Init(const EnergyEndpointerParams& params);
// Start the endpointer. This should be called at the beginning of a session.
void StartSession();
// Stop the endpointer.
void EndSession();
// Start environment estimation. Audio will be used for environment estimation
// i.e. noise level estimation.
void SetEnvironmentEstimationMode();
// Start user input. This should be called when the user indicates start of
// input, e.g. by pressing a button.
void SetUserInputMode();
// Computes the next input frame and modifies EnergyEndpointer status as
// appropriate based on the computation.
void ProcessAudioFrame(int64_t time_us,
const int16_t* samples, int num_samples,
float* rms_out);
// Returns the current state of the EnergyEndpointer and the time
// corresponding to the most recently computed frame.
EpStatus Status(int64_t* status_time_us) const;
bool estimating_environment() const {
return estimating_environment_;
}
// Returns estimated noise level in dB.
float GetNoiseLevelDb() const;
private:
class HistoryRing;
// Resets the endpointer internal state. If reset_threshold is true, the
// state will be reset completely, including adaptive thresholds and the
// removal of all history information.
void Restart(bool reset_threshold);
// Update internal speech and noise levels.
void UpdateLevels(float rms);
// Returns the number of frames (or frame number) corresponding to
// the 'time' (in seconds).
int TimeToFrame(float time) const;
EpStatus status_; // The current state of this instance.
float offset_confirm_dur_sec_; // max on time allowed to confirm POST_SPEECH
int64_t endpointer_time_us_; // Time of the most recently received audio frame.
int64_t fast_update_frames_; // Number of frames for initial level adaptation.
int64_t frame_counter_; // Number of frames seen. Used for initial adaptation.
float max_window_dur_; // Largest search window size (seconds)
float sample_rate_; // Sampling rate.
// Ring buffers to hold the speech activity history.
nsAutoPtr<HistoryRing> history_;
// Configuration parameters.
EnergyEndpointerParams params_;
// RMS which must be exceeded to conclude frame is speech.
float decision_threshold_;
// Flag to indicate that audio should be used to estimate environment, prior
// to receiving user input.
bool estimating_environment_;
// Estimate of the background noise level. Used externally for UI feedback.
float noise_level_;
// An adaptive threshold used to update decision_threshold_ when appropriate.
float rms_adapt_;
// Start lag corresponds to the highest fundamental frequency.
int start_lag_;
// End lag corresponds to the lowest fundamental frequency.
int end_lag_;
// Time when mode switched from environment estimation to user input. This
// is used to time forced rejection of audio feedback contamination.
int64_t user_input_start_time_us_;
// prevent copy constructor and assignment
EnergyEndpointer(const EnergyEndpointer&);
void operator=(const EnergyEndpointer&);
};
} // namespace mozilla
#endif // CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_H_

View File

@ -1,77 +0,0 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "energy_endpointer_params.h"
namespace mozilla {
EnergyEndpointerParams::EnergyEndpointerParams() {
SetDefaults();
}
void EnergyEndpointerParams::SetDefaults() {
frame_period_ = 0.01f;
frame_duration_ = 0.01f;
endpoint_margin_ = 0.2f;
onset_window_ = 0.15f;
speech_on_window_ = 0.4f;
offset_window_ = 0.15f;
onset_detect_dur_ = 0.09f;
onset_confirm_dur_ = 0.075f;
on_maintain_dur_ = 0.10f;
offset_confirm_dur_ = 0.12f;
decision_threshold_ = 150.0f;
min_decision_threshold_ = 50.0f;
fast_update_dur_ = 0.2f;
sample_rate_ = 8000.0f;
min_fundamental_frequency_ = 57.143f;
max_fundamental_frequency_ = 400.0f;
contamination_rejection_period_ = 0.25f;
}
void EnergyEndpointerParams::operator=(const EnergyEndpointerParams& source) {
frame_period_ = source.frame_period();
frame_duration_ = source.frame_duration();
endpoint_margin_ = source.endpoint_margin();
onset_window_ = source.onset_window();
speech_on_window_ = source.speech_on_window();
offset_window_ = source.offset_window();
onset_detect_dur_ = source.onset_detect_dur();
onset_confirm_dur_ = source.onset_confirm_dur();
on_maintain_dur_ = source.on_maintain_dur();
offset_confirm_dur_ = source.offset_confirm_dur();
decision_threshold_ = source.decision_threshold();
min_decision_threshold_ = source.min_decision_threshold();
fast_update_dur_ = source.fast_update_dur();
sample_rate_ = source.sample_rate();
min_fundamental_frequency_ = source.min_fundamental_frequency();
max_fundamental_frequency_ = source.max_fundamental_frequency();
contamination_rejection_period_ = source.contamination_rejection_period();
}
} // namespace mozilla

View File

@ -1,159 +0,0 @@
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_PARAMS_H_
#define CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_PARAMS_H_
namespace mozilla {
// Input parameters for the EnergyEndpointer class.
class EnergyEndpointerParams {
public:
EnergyEndpointerParams();
void SetDefaults();
void operator=(const EnergyEndpointerParams& source);
// Accessors and mutators
float frame_period() const { return frame_period_; }
void set_frame_period(float frame_period) {
frame_period_ = frame_period;
}
float frame_duration() const { return frame_duration_; }
void set_frame_duration(float frame_duration) {
frame_duration_ = frame_duration;
}
float endpoint_margin() const { return endpoint_margin_; }
void set_endpoint_margin(float endpoint_margin) {
endpoint_margin_ = endpoint_margin;
}
float onset_window() const { return onset_window_; }
void set_onset_window(float onset_window) { onset_window_ = onset_window; }
float speech_on_window() const { return speech_on_window_; }
void set_speech_on_window(float speech_on_window) {
speech_on_window_ = speech_on_window;
}
float offset_window() const { return offset_window_; }
void set_offset_window(float offset_window) {
offset_window_ = offset_window;
}
float onset_detect_dur() const { return onset_detect_dur_; }
void set_onset_detect_dur(float onset_detect_dur) {
onset_detect_dur_ = onset_detect_dur;
}
float onset_confirm_dur() const { return onset_confirm_dur_; }
void set_onset_confirm_dur(float onset_confirm_dur) {
onset_confirm_dur_ = onset_confirm_dur;
}
float on_maintain_dur() const { return on_maintain_dur_; }
void set_on_maintain_dur(float on_maintain_dur) {
on_maintain_dur_ = on_maintain_dur;
}
float offset_confirm_dur() const { return offset_confirm_dur_; }
void set_offset_confirm_dur(float offset_confirm_dur) {
offset_confirm_dur_ = offset_confirm_dur;
}
float decision_threshold() const { return decision_threshold_; }
void set_decision_threshold(float decision_threshold) {
decision_threshold_ = decision_threshold;
}
float min_decision_threshold() const { return min_decision_threshold_; }
void set_min_decision_threshold(float min_decision_threshold) {
min_decision_threshold_ = min_decision_threshold;
}
float fast_update_dur() const { return fast_update_dur_; }
void set_fast_update_dur(float fast_update_dur) {
fast_update_dur_ = fast_update_dur;
}
float sample_rate() const { return sample_rate_; }
void set_sample_rate(float sample_rate) { sample_rate_ = sample_rate; }
float min_fundamental_frequency() const { return min_fundamental_frequency_; }
void set_min_fundamental_frequency(float min_fundamental_frequency) {
min_fundamental_frequency_ = min_fundamental_frequency;
}
float max_fundamental_frequency() const { return max_fundamental_frequency_; }
void set_max_fundamental_frequency(float max_fundamental_frequency) {
max_fundamental_frequency_ = max_fundamental_frequency;
}
float contamination_rejection_period() const {
return contamination_rejection_period_;
}
void set_contamination_rejection_period(
float contamination_rejection_period) {
contamination_rejection_period_ = contamination_rejection_period;
}
private:
float frame_period_; // Frame period
float frame_duration_; // Window size
float onset_window_; // Interval scanned for onset activity
float speech_on_window_; // Inverval scanned for ongoing speech
float offset_window_; // Interval scanned for offset evidence
float offset_confirm_dur_; // Silence duration required to confirm offset
float decision_threshold_; // Initial rms detection threshold
float min_decision_threshold_; // Minimum rms detection threshold
float fast_update_dur_; // Period for initial estimation of levels.
float sample_rate_; // Expected sample rate.
// Time to add on either side of endpoint threshold crossings
float endpoint_margin_;
// Total dur within onset_window required to enter ONSET state
float onset_detect_dur_;
// Total on time within onset_window required to enter SPEECH_ON state
float onset_confirm_dur_;
// Minimum dur in SPEECH_ON state required to maintain ON state
float on_maintain_dur_;
// Minimum fundamental frequency for autocorrelation.
float min_fundamental_frequency_;
// Maximum fundamental frequency for autocorrelation.
float max_fundamental_frequency_;
// Period after start of user input that above threshold values are ignored.
// This is to reject audio feedback contamination.
float contamination_rejection_period_;
};
} // namespace mozilla
#endif // CONTENT_BROWSER_SPEECH_ENDPOINTER_ENERGY_ENDPOINTER_PARAMS_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +0,0 @@
/* ====================================================================
* Copyright (c) 2015 Alpha Cephei Inc. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY ALPHA CEPHEI INC. ``AS IS'' AND.
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,.
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALPHA CEPHEI INC.
* NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT.
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,.
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY.
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT.
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE.
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
*/
This directory contains generic US english acoustic model trained with
latest sphinxtrain.

View File

@ -1,12 +0,0 @@
-lowerf 130
-upperf 3700
-nfilt 20
-transform dct
-lifter 22
-feat 1s_c_d_dd
-svspec 0-12/13-25/26-38
-agc none
-cmn current
-varnorm no
-cmninit 30.09,0.49,5.51,7.43,-2.39,-1.64,-4.71,0.03,-5.11,0.20,4.84,6.14,0.35
-model ptm

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +0,0 @@
<s> SIL
</s> SIL
<sil> SIL
[NOISE] +NSN+
[SPEECH] +SPN+

View File

@ -1,88 +0,0 @@
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
XPIDL_MODULE = 'dom_webspeechrecognition'
XPIDL_SOURCES = [
'nsISpeechRecognitionService.idl'
]
EXPORTS.mozilla.dom += [
'SpeechGrammar.h',
'SpeechGrammarList.h',
'SpeechRecognition.h',
'SpeechRecognitionAlternative.h',
'SpeechRecognitionResult.h',
'SpeechRecognitionResultList.h',
'SpeechStreamListener.h',
]
if CONFIG['MOZ_WEBSPEECH_TEST_BACKEND']:
EXPORTS.mozilla.dom += [
'test/FakeSpeechRecognitionService.h',
]
if CONFIG['MOZ_WEBSPEECH_POCKETSPHINX']:
EXPORTS.mozilla.dom += [
'PocketSphinxSpeechRecognitionService.h',
]
SOURCES += [
'endpointer.cc',
'energy_endpointer.cc',
'energy_endpointer_params.cc',
'SpeechGrammar.cpp',
'SpeechGrammarList.cpp',
'SpeechRecognition.cpp',
'SpeechRecognitionAlternative.cpp',
'SpeechRecognitionResult.cpp',
'SpeechRecognitionResultList.cpp',
'SpeechStreamListener.cpp',
]
if CONFIG['MOZ_WEBSPEECH_TEST_BACKEND']:
SOURCES += [
'test/FakeSpeechRecognitionService.cpp',
]
if CONFIG['MOZ_WEBSPEECH_POCKETSPHINX']:
SOURCES += [
'PocketSphinxSpeechRecognitionService.cpp',
]
LOCAL_INCLUDES += [
'/dom/base',
'/media/sphinxbase',
]
if CONFIG['MOZ_WEBSPEECH_POCKETSPHINX']:
LOCAL_INCLUDES += [
'/media/pocketsphinx',
]
if CONFIG['MOZ_WEBSPEECH_MODELS']:
FINAL_TARGET_FILES.models.dict += [
'models/dict/en-US.dic',
'models/dict/en-US.dic.dmp',
]
FINAL_TARGET_FILES.models['en-US'] += [
'models/en-US/feat.params',
'models/en-US/mdef',
'models/en-US/means',
'models/en-US/mixture_weights',
'models/en-US/noisedict',
'models/en-US/sendump',
'models/en-US/transition_matrices',
'models/en-US/variances',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wno-error=shadow']

View File

@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
%{C++
#include "mozilla/WeakPtr.h"
namespace mozilla {
class AudioSegment;
namespace dom {
class SpeechRecognition;
class SpeechRecognitionResultList;
class SpeechGrammarList;
class SpeechGrammar;
}
}
%}
native SpeechRecognitionWeakPtr(mozilla::WeakPtr<mozilla::dom::SpeechRecognition>);
[ptr] native AudioSegmentPtr(mozilla::AudioSegment);
[ptr] native SpeechGrammarPtr(mozilla::dom::SpeechGrammar);
[ptr] native SpeechGrammarListPtr(mozilla::dom::SpeechGrammarList);
[uuid(6fcb6ee8-a6db-49ba-9f06-355d7ee18ea7)]
interface nsISpeechGrammarCompilationCallback : nsISupports {
void grammarCompilationEnd(in SpeechGrammarPtr grammarObject, in boolean success);
};
[uuid(8e97f287-f322-44e8-8888-8344fa408ef8)]
interface nsISpeechRecognitionService : nsISupports {
void initialize(in SpeechRecognitionWeakPtr aSpeechRecognition);
void processAudioSegment(in AudioSegmentPtr aAudioSegment, in long aSampleRate);
void validateAndSetGrammarList(in SpeechGrammarPtr aSpeechGrammar, in nsISpeechGrammarCompilationCallback aCallback);
void soundEnd();
void abort();
};
%{C++
#define NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX "@mozilla.org/webspeech/service;1?name="
%}

View File

@ -1,119 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsThreadUtils.h"
#include "FakeSpeechRecognitionService.h"
#include "MediaPrefs.h"
#include "SpeechRecognition.h"
#include "SpeechRecognitionAlternative.h"
#include "SpeechRecognitionResult.h"
#include "SpeechRecognitionResultList.h"
#include "nsIObserverService.h"
#include "mozilla/Services.h"
namespace mozilla {
using namespace dom;
NS_IMPL_ISUPPORTS(FakeSpeechRecognitionService, nsISpeechRecognitionService, nsIObserver)
FakeSpeechRecognitionService::FakeSpeechRecognitionService()
{
}
FakeSpeechRecognitionService::~FakeSpeechRecognitionService()
{
}
NS_IMETHODIMP
FakeSpeechRecognitionService::Initialize(WeakPtr<SpeechRecognition> aSpeechRecognition)
{
mRecognition = aSpeechRecognition;
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
obs->AddObserver(this, SPEECH_RECOGNITION_TEST_EVENT_REQUEST_TOPIC, false);
obs->AddObserver(this, SPEECH_RECOGNITION_TEST_END_TOPIC, false);
return NS_OK;
}
NS_IMETHODIMP
FakeSpeechRecognitionService::ProcessAudioSegment(AudioSegment* aAudioSegment, int32_t aSampleRate)
{
return NS_OK;
}
NS_IMETHODIMP
FakeSpeechRecognitionService::SoundEnd()
{
return NS_OK;
}
NS_IMETHODIMP
FakeSpeechRecognitionService::ValidateAndSetGrammarList(mozilla::dom::SpeechGrammar*, nsISpeechGrammarCompilationCallback*)
{
return NS_OK;
}
NS_IMETHODIMP
FakeSpeechRecognitionService::Abort()
{
return NS_OK;
}
NS_IMETHODIMP
FakeSpeechRecognitionService::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
{
MOZ_ASSERT(MediaPrefs::WebSpeechFakeRecognitionService(),
"Got request to fake recognition service event, but "
TEST_PREFERENCE_FAKE_RECOGNITION_SERVICE " is not set");
if (!strcmp(aTopic, SPEECH_RECOGNITION_TEST_END_TOPIC)) {
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
obs->RemoveObserver(this, SPEECH_RECOGNITION_TEST_EVENT_REQUEST_TOPIC);
obs->RemoveObserver(this, SPEECH_RECOGNITION_TEST_END_TOPIC);
return NS_OK;
}
const nsDependentString eventName = nsDependentString(aData);
if (eventName.EqualsLiteral("EVENT_RECOGNITIONSERVICE_ERROR")) {
mRecognition->DispatchError(SpeechRecognition::EVENT_RECOGNITIONSERVICE_ERROR,
SpeechRecognitionErrorCode::Network, // TODO different codes?
NS_LITERAL_STRING("RECOGNITIONSERVICE_ERROR test event"));
} else if (eventName.EqualsLiteral("EVENT_RECOGNITIONSERVICE_FINAL_RESULT")) {
RefPtr<SpeechEvent> event =
new SpeechEvent(mRecognition,
SpeechRecognition::EVENT_RECOGNITIONSERVICE_FINAL_RESULT);
event->mRecognitionResultList = BuildMockResultList();
NS_DispatchToMainThread(event);
}
return NS_OK;
}
SpeechRecognitionResultList*
FakeSpeechRecognitionService::BuildMockResultList()
{
SpeechRecognitionResultList* resultList = new SpeechRecognitionResultList(mRecognition);
SpeechRecognitionResult* result = new SpeechRecognitionResult(mRecognition);
if (0 < mRecognition->MaxAlternatives()) {
SpeechRecognitionAlternative* alternative = new SpeechRecognitionAlternative(mRecognition);
alternative->mTranscript = NS_LITERAL_STRING("Mock final result");
alternative->mConfidence = 0.0f;
result->mItems.AppendElement(alternative);
}
resultList->mItems.AppendElement(result);
return resultList;
}
} // namespace mozilla

View File

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_FakeSpeechRecognitionService_h
#define mozilla_dom_FakeSpeechRecognitionService_h
#include "nsCOMPtr.h"
#include "nsIObserver.h"
#include "nsISpeechRecognitionService.h"
#define NS_FAKE_SPEECH_RECOGNITION_SERVICE_CID \
{0x48c345e7, 0x9929, 0x4f9a, {0xa5, 0x63, 0xf4, 0x78, 0x22, 0x2d, 0xab, 0xcd}};
namespace mozilla {
class FakeSpeechRecognitionService : public nsISpeechRecognitionService,
public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSISPEECHRECOGNITIONSERVICE
NS_DECL_NSIOBSERVER
FakeSpeechRecognitionService();
private:
virtual ~FakeSpeechRecognitionService();
WeakPtr<dom::SpeechRecognition> mRecognition;
dom::SpeechRecognitionResultList* BuildMockResultList();
};
} // namespace mozilla
#endif

View File

@ -1,181 +0,0 @@
"use strict";
const DEFAULT_AUDIO_SAMPLE_FILE = "hello.ogg";
const SPEECH_RECOGNITION_TEST_REQUEST_EVENT_TOPIC = "SpeechRecognitionTest:RequestEvent";
const SPEECH_RECOGNITION_TEST_END_TOPIC = "SpeechRecognitionTest:End";
var errorCodes = {
NO_SPEECH : "no-speech",
ABORTED : "aborted",
AUDIO_CAPTURE : "audio-capture",
NETWORK : "network",
NOT_ALLOWED : "not-allowed",
SERVICE_NOT_ALLOWED : "service-not-allowed",
BAD_GRAMMAR : "bad-grammar",
LANGUAGE_NOT_SUPPORTED : "language-not-supported"
};
var Services = SpecialPowers.Cu.import("resource://gre/modules/Services.jsm").Services;
function EventManager(sr) {
var self = this;
var nEventsExpected = 0;
self.eventsReceived = [];
var allEvents = [
"audiostart",
"soundstart",
"speechstart",
"speechend",
"soundend",
"audioend",
"result",
"nomatch",
"error",
"start",
"end"
];
var eventDependencies = {
"speechend": "speechstart",
"soundend": "soundstart",
"audioend": "audiostart"
};
var isDone = false;
// set up grammar
var sgl = new SpeechGrammarList();
sgl.addFromString("#JSGF V1.0; grammar test; public <simple> = hello ;", 1);
sr.grammars = sgl;
// AUDIO_DATA events are asynchronous,
// so we queue events requested while they are being
// issued to make them seem synchronous
var isSendingAudioData = false;
var queuedEventRequests = [];
// register default handlers
for (var i = 0; i < allEvents.length; i++) {
(function (eventName) {
sr["on" + eventName] = function (evt) {
var message = "unexpected event: " + eventName;
if (eventName == "error") {
message += " -- " + evt.message;
}
ok(false, message);
if (self.doneFunc && !isDone) {
isDone = true;
self.doneFunc();
}
};
})(allEvents[i]);
}
self.expect = function EventManager_expect(eventName, cb) {
nEventsExpected++;
sr["on" + eventName] = function(evt) {
self.eventsReceived.push(eventName);
ok(true, "received event " + eventName);
var dep = eventDependencies[eventName];
if (dep) {
ok(self.eventsReceived.indexOf(dep) >= 0,
eventName + " must come after " + dep);
}
cb && cb(evt, sr);
if (self.doneFunc && !isDone &&
nEventsExpected === self.eventsReceived.length) {
isDone = true;
self.doneFunc();
}
}
}
self.start = function EventManager_start() {
isSendingAudioData = true;
var audioTag = document.createElement("audio");
audioTag.src = self.audioSampleFile;
var stream = audioTag.mozCaptureStreamUntilEnded();
audioTag.addEventListener("ended", function() {
info("Sample stream ended, requesting queued events");
isSendingAudioData = false;
while (queuedEventRequests.length) {
self.requestFSMEvent(queuedEventRequests.shift());
}
});
audioTag.play();
sr.start(stream);
}
self.requestFSMEvent = function EventManager_requestFSMEvent(eventName) {
if (isSendingAudioData) {
info("Queuing event " + eventName + " until we're done sending audio data");
queuedEventRequests.push(eventName);
return;
}
info("requesting " + eventName);
Services.obs.notifyObservers(null,
SPEECH_RECOGNITION_TEST_REQUEST_EVENT_TOPIC,
eventName);
}
self.requestTestEnd = function EventManager_requestTestEnd() {
Services.obs.notifyObservers(null, SPEECH_RECOGNITION_TEST_END_TOPIC, null);
}
}
function buildResultCallback(transcript) {
return (function(evt) {
is(evt.results[0][0].transcript, transcript, "expect correct transcript");
});
}
function buildErrorCallback(errcode) {
return (function(err) {
is(err.error, errcode, "expect correct error code");
});
}
function performTest(options) {
var prefs = options.prefs;
prefs.unshift(
["media.webspeech.recognition.enable", true],
["media.webspeech.test.enable", true]
);
SpecialPowers.pushPrefEnv({set: prefs}, function() {
var sr = new SpeechRecognition();
var em = new EventManager(sr);
for (var eventName in options.expectedEvents) {
var cb = options.expectedEvents[eventName];
em.expect(eventName, cb);
}
em.doneFunc = function() {
em.requestTestEnd();
if (options.doneFunc) {
options.doneFunc();
}
}
em.audioSampleFile = DEFAULT_AUDIO_SAMPLE_FILE;
if (options.audioSampleFile) {
em.audioSampleFile = options.audioSampleFile;
}
em.start();
for (var i = 0; i < options.eventsToRequest.length; i++) {
em.requestFSMEvent(options.eventsToRequest[i]);
}
});
}

View File

@ -1 +0,0 @@
Cache-Control: no-store

View File

@ -1,21 +0,0 @@
[DEFAULT]
tags=msg
subsuite = media
support-files =
head.js
hello.ogg
hello.ogg^headers^
silence.ogg
silence.ogg^headers^
[test_abort.html]
skip-if = toolkit == 'android' # bug 1037287
[test_audio_capture_error.html]
[test_call_start_from_end_handler.html]
tags=capturestream
skip-if = (android_version == '18' && debug) # bug 967606
[test_nested_eventloop.html]
skip-if = toolkit == 'android'
[test_preference_enable.html]
[test_recognition_service_error.html]
[test_success_without_recognition_service.html]
[test_timeout.html]

View File

@ -1 +0,0 @@
Cache-Control: no-store

View File

@ -1,71 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295 -- Call abort from inside handlers</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="head.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
// Abort inside event handlers, should't get a
// result after that
var nextEventIdx = 0;
var eventsToAbortOn = [
"start",
"audiostart",
"speechstart",
"speechend",
"audioend"
];
function doNextTest() {
var nextEvent = eventsToAbortOn[nextEventIdx];
var expectedEvents = {
"start": null,
"audiostart": null,
"audioend": null,
"end": null
};
if (nextEventIdx >= eventsToAbortOn.indexOf("speechstart")) {
expectedEvents["speechstart"] = null;
}
if (nextEventIdx >= eventsToAbortOn.indexOf("speechend")) {
expectedEvents["speechend"] = null;
}
info("Aborting on " + nextEvent);
expectedEvents[nextEvent] = function(evt, sr) {
sr.abort();
};
nextEventIdx++;
performTest({
eventsToRequest: [],
expectedEvents: expectedEvents,
doneFunc: (nextEventIdx < eventsToAbortOn.length) ? doNextTest : SimpleTest.finish,
prefs: [["media.webspeech.test.fake_fsm_events", true], ["media.webspeech.test.fake_recognition_service", true]]
});
}
doNextTest();
</script>
</pre>
</body>
</html>

View File

@ -1,40 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295 -- Behavior on audio error</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="head.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
performTest({
eventsToRequest: ['EVENT_AUDIO_ERROR'],
expectedEvents: {
'start': null,
'audiostart': null,
'speechstart': null,
'speechend': null,
'audioend': null,
'error': buildErrorCallback(errorCodes.AUDIO_CAPTURE),
'end': null
},
doneFunc: SimpleTest.finish,
prefs: [["media.webspeech.test.fake_fsm_events", true], ["media.webspeech.test.fake_recognition_service", true]]
});
</script>
</pre>
</body>
</html>

View File

@ -1,100 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295 -- Restart recognition from end handler</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="head.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
function createAudioStream() {
var audioTag = document.createElement("audio");
audioTag.src = DEFAULT_AUDIO_SAMPLE_FILE;
var stream = audioTag.mozCaptureStreamUntilEnded();
audioTag.play();
return stream;
}
var done = false;
function endHandler(evt, sr) {
if (done) {
SimpleTest.finish();
return;
}
try {
var stream = createAudioStream();
sr.start(stream); // shouldn't fail
} catch (err) {
ok(false, "Failed to start() from end() callback");
}
// calling start() may cause some callbacks to fire, but we're
// no longer interested in them, except for onend, which is where
// we'll conclude the test.
sr.onstart = null;
sr.onaudiostart = null;
sr.onspeechstart = null;
sr.onspeechend = null;
sr.onaudioend = null;
sr.onresult = null;
// FIXME(ggp) the state transition caused by start() is async,
// but abort() is sync (see bug 1055093). until we normalize
// state transitions, we need to setTimeout here to make sure
// abort() finds the speech recognition object in the correct
// state (namely, STATE_STARTING).
setTimeout(function() {
sr.abort();
done = true;
});
info("Successfully start() from end() callback");
}
function expectExceptionHandler(evt, sr) {
try {
sr.start(createAudioStream());
} catch (err) {
is(err.name, "InvalidStateError");
return;
}
ok(false, "Calling start() didn't raise InvalidStateError");
}
performTest({
eventsToRequest: [
'EVENT_RECOGNITIONSERVICE_FINAL_RESULT'
],
expectedEvents: {
'start': expectExceptionHandler,
'audiostart': expectExceptionHandler,
'speechstart': expectExceptionHandler,
'speechend': expectExceptionHandler,
'audioend': expectExceptionHandler,
'result': buildResultCallback("Mock final result"),
'end': endHandler,
},
prefs: [["media.webspeech.test.fake_fsm_events", true], ["media.webspeech.test.fake_recognition_service", true]]
});
</script>
</pre>
</body>
</html>

View File

@ -1,81 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295 -- Spin the event loop from inside a callback</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="head.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
/*
* SpecialPowers.spinEventLoop can be used to spin the event loop, causing
* queued SpeechEvents (such as those created by calls to start(), stop()
* or abort()) to be processed immediately.
* When this is done from inside DOM event handlers, it is possible to
* cause reentrancy in our C++ code, which we should be able to withstand.
*/
function abortAndSpinEventLoop(evt, sr) {
sr.abort();
SpecialPowers.spinEventLoop(window);
}
function doneFunc() {
// Trigger gc now and wait some time to make sure this test gets the blame
// for any assertions caused by spinning the event loop.
//
// NB - The assertions should be gone, but this looks too scary to touch
// during batch cleanup.
var count = 0, GC_COUNT = 4;
function triggerGCOrFinish() {
SpecialPowers.gc();
count++;
if (count == GC_COUNT) {
SimpleTest.finish();
}
}
for (var i = 0; i < GC_COUNT; i++) {
setTimeout(triggerGCOrFinish, 0);
}
}
/*
* We start by performing a normal start, then abort from the audiostart
* callback and force the EVENT_ABORT to be processed while still inside
* the event handler. This causes the recording to stop, which raises
* the audioend and (later on) end events.
* Then, we abort (once again spinning the event loop) from the audioend
* handler, attempting to cause a re-entry into the abort code. This second
* call should be ignored, and we get the end callback and finish.
*/
performTest({
eventsToRequest: [],
expectedEvents: {
"audiostart": abortAndSpinEventLoop,
"audioend": abortAndSpinEventLoop,
"end": null
},
doneFunc: doneFunc,
prefs: [["media.webspeech.test.fake_fsm_events", true],
["media.webspeech.test.fake_recognition_service", true]]
});
</script>
</pre>
</body>
</html>

View File

@ -1,43 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295 -- No objects should be visible with preference disabled</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({
set: [["media.webspeech.recognition.enable", false]]
}, function() {
var objects = [
"SpeechRecognition",
"SpeechGrammar",
"SpeechRecognitionResult",
"SpeechRecognitionResultList",
"SpeechRecognitionAlternative"
];
for (var i = 0; i < objects.length; i++) {
is(window[objects[i]], undefined,
objects[i] + " should be undefined with pref off");
}
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -1,43 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295 -- Behavior on recognition service error</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="head.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
performTest({
eventsToRequest: [
'EVENT_RECOGNITIONSERVICE_ERROR'
],
expectedEvents: {
'start': null,
'audiostart': null,
'speechstart': null,
'speechend': null,
'audioend': null,
'error': buildErrorCallback(errorCodes.NETWORK),
'end': null
},
doneFunc: SimpleTest.finish,
prefs: [["media.webspeech.test.fake_fsm_events", true], ["media.webspeech.test.fake_recognition_service", true]]
});
</script>
</pre>
</body>
</html>

View File

@ -1,43 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295 -- Success with fake recognition service</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="head.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
performTest({
eventsToRequest: [
'EVENT_RECOGNITIONSERVICE_FINAL_RESULT'
],
expectedEvents: {
'start': null,
'audiostart': null,
'speechstart': null,
'speechend': null,
'audioend': null,
'result': buildResultCallback("Mock final result"),
'end': null
},
doneFunc:SimpleTest.finish,
prefs: [["media.webspeech.test.fake_fsm_events", true], ["media.webspeech.test.fake_recognition_service", true]]
});
</script>
</pre>
</body>
</html>

View File

@ -1,40 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295 -- Timeout for user speech</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript" src="head.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="text/javascript">
SimpleTest.waitForExplicitFinish();
performTest({
eventsToRequest: [],
expectedEvents: {
"start": null,
"audiostart": null,
"audioend": null,
"error": buildErrorCallback(errorCodes.NO_SPEECH),
"end": null
},
doneFunc: SimpleTest.finish,
audioSampleFile: "silence.ogg",
prefs: [["media.webspeech.test.fake_fsm_events", true], ["media.webspeech.test.fake_recognition_service", true]]
});
</script>
</pre>
</body>
</html>

View File

@ -3,56 +3,44 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
if CONFIG['MOZ_WEBSPEECH']:
MOCHITEST_MANIFESTS += [
'test/mochitest.ini',
'test/startup/mochitest.ini',
]
XPIDL_MODULE = 'dom_webspeechsynth'
XPIDL_MODULE = 'dom_webspeechsynth'
XPIDL_SOURCES += [
'nsISpeechService.idl',
'nsISynthVoiceRegistry.idl'
]
XPIDL_SOURCES += [
'nsISpeechService.idl',
'nsISynthVoiceRegistry.idl'
]
EXPORTS.mozilla.dom += [
'ipc/SpeechSynthesisChild.h',
'ipc/SpeechSynthesisParent.h',
'nsSpeechTask.h',
'nsSynthVoiceRegistry.h',
'SpeechSynthesis.h',
'SpeechSynthesisUtterance.h',
'SpeechSynthesisVoice.h',
]
EXPORTS.mozilla.dom += [
'ipc/SpeechSynthesisChild.h',
'ipc/SpeechSynthesisParent.h',
'nsSpeechTask.h',
'nsSynthVoiceRegistry.h',
'SpeechSynthesis.h',
'SpeechSynthesisUtterance.h',
'SpeechSynthesisVoice.h',
]
SOURCES += [
'ipc/SpeechSynthesisChild.cpp',
'ipc/SpeechSynthesisParent.cpp',
'nsSpeechTask.cpp',
'nsSynthVoiceRegistry.cpp',
'SpeechSynthesis.cpp',
'SpeechSynthesisUtterance.cpp',
'SpeechSynthesisVoice.cpp',
]
SOURCES += [
'ipc/SpeechSynthesisChild.cpp',
'ipc/SpeechSynthesisParent.cpp',
'nsSpeechTask.cpp',
'nsSynthVoiceRegistry.cpp',
'SpeechSynthesis.cpp',
'SpeechSynthesisUtterance.cpp',
'SpeechSynthesisVoice.cpp',
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
DIRS += ['windows']
if CONFIG['MOZ_WEBSPEECH_TEST_BACKEND']:
SOURCES += [
'test/FakeSynthModule.cpp',
'test/nsFakeSynthServices.cpp'
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
DIRS += ['cocoa']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
DIRS += ['windows']
if CONFIG['MOZ_SYNTH_SPEECHD']:
DIRS += ['speechd']
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
DIRS += ['cocoa']
if CONFIG['MOZ_SYNTH_SPEECHD']:
DIRS += ['speechd']
if CONFIG['MOZ_SYNTH_PICO']:
DIRS += ['pico']
if CONFIG['MOZ_SYNTH_PICO']:
DIRS += ['pico']
IPDL_SOURCES += [
'ipc/PSpeechSynthesis.ipdl',

View File

@ -1,55 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/ModuleUtils.h"
#include "nsIClassInfoImpl.h"
#include "nsFakeSynthServices.h"
using namespace mozilla::dom;
#define FAKESYNTHSERVICE_CID \
{0xe7d52d9e, 0xc148, 0x47d8, {0xab, 0x2a, 0x95, 0xd7, 0xf4, 0x0e, 0xa5, 0x3d}}
#define FAKESYNTHSERVICE_CONTRACTID "@mozilla.org/fakesynth;1"
// Defines nsFakeSynthServicesConstructor
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsFakeSynthServices,
nsFakeSynthServices::GetInstanceForService)
// Defines kFAKESYNTHSERVICE_CID
NS_DEFINE_NAMED_CID(FAKESYNTHSERVICE_CID);
static const mozilla::Module::CIDEntry kCIDs[] = {
{ &kFAKESYNTHSERVICE_CID, true, nullptr, nsFakeSynthServicesConstructor },
{ nullptr }
};
static const mozilla::Module::ContractIDEntry kContracts[] = {
{ FAKESYNTHSERVICE_CONTRACTID, &kFAKESYNTHSERVICE_CID },
{ nullptr }
};
static const mozilla::Module::CategoryEntry kCategories[] = {
{ "speech-synth-started", "Fake Speech Synth", FAKESYNTHSERVICE_CONTRACTID },
{ nullptr }
};
static void
UnloadFakeSynthmodule()
{
nsFakeSynthServices::Shutdown();
}
static const mozilla::Module kModule = {
mozilla::Module::kVersion,
kCIDs,
kContracts,
kCategories,
nullptr,
nullptr,
UnloadFakeSynthmodule
};
NSMODULE_DEFN(fakesynth) = &kModule;

View File

@ -1,91 +0,0 @@
function synthTestQueue(aTestArgs, aEndFunc) {
var utterances = [];
for (var i in aTestArgs) {
var uargs = aTestArgs[i][0];
var win = uargs.win || window;
var u = new win.SpeechSynthesisUtterance(uargs.text);
if (uargs.args) {
for (var attr in uargs.args)
u[attr] = uargs.args[attr];
}
function onend_handler(e) {
is(e.target, utterances.shift(), "Target matches utterances");
ok(!speechSynthesis.speaking, "speechSynthesis is not speaking.");
if (utterances.length) {
ok(speechSynthesis.pending, "other utterances queued");
} else {
ok(!speechSynthesis.pending, "queue is empty, nothing pending.");
if (aEndFunc)
aEndFunc();
}
}
u.addEventListener('start',
(function (expectedUri) {
return function (e) {
if (expectedUri) {
var chosenVoice = SpecialPowers.wrap(e).target.chosenVoiceURI;
is(chosenVoice, expectedUri, "Incorrect URI is used");
}
};
})(aTestArgs[i][1] ? aTestArgs[i][1].uri : null));
u.addEventListener('end', onend_handler);
u.addEventListener('error', onend_handler);
u.addEventListener('error',
(function (expectedError) {
return function onerror_handler(e) {
ok(expectedError, "Error in speech utterance '" + e.target.text + "'");
};
})(aTestArgs[i][1] ? aTestArgs[i][1].err : false));
utterances.push(u);
win.speechSynthesis.speak(u);
}
ok(!speechSynthesis.speaking, "speechSynthesis is not speaking yet.");
ok(speechSynthesis.pending, "speechSynthesis has an utterance queued.");
}
function loadFrame(frameId) {
return new Promise(function(resolve, reject) {
var frame = document.getElementById(frameId);
frame.addEventListener('load', function (e) {
frame.contentWindow.document.title = frameId;
resolve(frame);
});
frame.src = 'data:text/html,' + encodeURI('<html><head></head><body></body></html>');
});
}
function waitForVoices(win) {
return new Promise(resolve => {
function resolver() {
if (win.speechSynthesis.getVoices().length) {
win.speechSynthesis.removeEventListener('voiceschanged', resolver);
resolve();
}
}
win.speechSynthesis.addEventListener('voiceschanged', resolver);
resolver();
});
}
function loadSpeechTest(fileName, prefs, frameId="testFrame") {
loadFrame(frameId).then(frame => {
waitForVoices(frame.contentWindow).then(
() => document.getElementById("testFrame").src = fileName);
});
}
function testSynthState(win, expectedState) {
for (var attr in expectedState) {
is(win.speechSynthesis[attr], expectedState[attr],
win.document.title + ": '" + attr + '" does not match');
}
}

View File

@ -1,28 +0,0 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="application/javascript">
var frameUnloaded = function() {
var u = new SpeechSynthesisUtterance('hi');
u.addEventListener('end', function () {
parent.ok(true, 'Successfully spoke utterance from new frame.');
parent.onDone();
});
speechSynthesis.speak(u);
}
addEventListener('pageshow', function onshow(evt) {
var u = new SpeechSynthesisUtterance('hello');
u.lang = 'it-IT-noend';
u.addEventListener('start', function() {
location =
'data:text/html,<html><body onpageshow="' +
frameUnloaded.toSource() + '()"></body></html>';
});
speechSynthesis.speak(u);
});
</script>
</head>
<body>
</body>
</html>

View File

@ -1,69 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1188099
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1188099: Global queue should correctly schedule utterances</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.info = parent.info;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
window.todo = parent.todo;
</script>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1188099">Mozilla Bug 1188099</a>
<iframe id="frame1"></iframe>
<iframe id="frame2"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
Promise.all([loadFrame('frame1'), loadFrame('frame2')]).then(function ([frame1, frame2]) {
var win1 = frame1.contentWindow;
var win2 = frame2.contentWindow;
var utterance1 = new win1.SpeechSynthesisUtterance("hello, losers");
var utterance2 = new win1.SpeechSynthesisUtterance("hello, losers three");
var utterance3 = new win2.SpeechSynthesisUtterance("hello, losers too");
var eventOrder = ['start1', 'end1', 'start3', 'end3', 'start2', 'end2'];
utterance1.addEventListener('start', function(e) {
is(eventOrder.shift(), 'start1', 'start1');
testSynthState(win1, { speaking: true, pending: true });
testSynthState(win2, { speaking: true, pending: true });
});
utterance1.addEventListener('end', function(e) {
is(eventOrder.shift(), 'end1', 'end1');
});
utterance3.addEventListener('start', function(e) {
is(eventOrder.shift(), 'start3', 'start3');
testSynthState(win1, { speaking: true, pending: true });
testSynthState(win2, { speaking: true, pending: false });
});
utterance3.addEventListener('end', function(e) {
is(eventOrder.shift(), 'end3', 'end3');
});
utterance2.addEventListener('start', function(e) {
is(eventOrder.shift(), 'start2', 'start2');
testSynthState(win1, { speaking: true, pending: false });
testSynthState(win2, { speaking: true, pending: false });
});
utterance2.addEventListener('end', function(e) {
is(eventOrder.shift(), 'end2', 'end2');
testSynthState(win1, { speaking: false, pending: false });
testSynthState(win2, { speaking: false, pending: false });
SimpleTest.finish();
});
win1.speechSynthesis.speak(utterance1);
win1.speechSynthesis.speak(utterance2);
win2.speechSynthesis.speak(utterance3);
});
</script>
</pre>
</body>
</html>

View File

@ -1,88 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1188099
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1188099: Calling cancel() should work correctly with global queue</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.info = parent.info;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
window.todo = parent.todo;
</script>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1188099">Mozilla Bug 1188099</a>
<iframe id="frame1"></iframe>
<iframe id="frame2"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
Promise.all([loadFrame('frame1'), loadFrame('frame2')]).then(function ([frame1, frame2]) {
var win1 = frame1.contentWindow;
var win2 = frame2.contentWindow;
var utterance1 = new win1.SpeechSynthesisUtterance(
"u1: Donec ac nunc feugiat, posuere");
utterance1.lang = 'it-IT-noend';
var utterance2 = new win1.SpeechSynthesisUtterance("u2: hello, losers too");
utterance2.lang = 'it-IT-noend';
var utterance3 = new win1.SpeechSynthesisUtterance("u3: hello, losers three");
var utterance4 = new win2.SpeechSynthesisUtterance("u4: hello, losers same!");
utterance4.lang = 'it-IT-noend';
var utterance5 = new win2.SpeechSynthesisUtterance("u5: hello, losers too");
utterance5.lang = 'it-IT-noend';
var eventOrder = ['start1', 'end1', 'start2', 'end2'];
utterance1.addEventListener('start', function(e) {
is(eventOrder.shift(), 'start1', 'start1');
testSynthState(win1, { speaking: true, pending: true });
testSynthState(win2, { speaking: true, pending: true });
win2.speechSynthesis.cancel();
SpecialPowers.wrap(win1.speechSynthesis).forceEnd();
});
utterance1.addEventListener('end', function(e) {
is(eventOrder.shift(), 'end1', 'end1');
testSynthState(win1, { pending: true });
testSynthState(win2, { pending: false });
});
utterance2.addEventListener('start', function(e) {
is(eventOrder.shift(), 'start2', 'start2');
testSynthState(win1, { speaking: true, pending: true });
testSynthState(win2, { speaking: true, pending: false });
win1.speechSynthesis.cancel();
});
utterance2.addEventListener('end', function(e) {
is(eventOrder.shift(), 'end2', 'end2');
testSynthState(win1, { speaking: false, pending: false });
testSynthState(win2, { speaking: false, pending: false });
SimpleTest.finish();
});
function wrongUtterance(e) {
ok(false, 'This shall not be uttered: "' + e.target.text + '"');
}
utterance3.addEventListener('start', wrongUtterance);
utterance4.addEventListener('start', wrongUtterance);
utterance5.addEventListener('start', wrongUtterance);
win1.speechSynthesis.speak(utterance1);
win1.speechSynthesis.speak(utterance2);
win1.speechSynthesis.speak(utterance3);
win2.speechSynthesis.speak(utterance4);
win2.speechSynthesis.speak(utterance5);
});
</script>
</pre>
</body>
</html>

View File

@ -1,131 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1188099
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1188099: Calling pause() should work correctly with global queue</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.info = parent.info;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
window.todo = parent.todo;
</script>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1188099">Mozilla Bug 1188099</a>
<iframe id="frame1"></iframe>
<iframe id="frame2"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
Promise.all([loadFrame('frame1'), loadFrame('frame2')]).then(function ([frame1, frame2]) {
var win1 = frame1.contentWindow;
var win2 = frame2.contentWindow;
var utterance1 = new win1.SpeechSynthesisUtterance("Speak utterance 1.");
utterance1.lang = 'it-IT-noend';
var utterance2 = new win2.SpeechSynthesisUtterance("Speak utterance 2.");
var utterance3 = new win1.SpeechSynthesisUtterance("Speak utterance 3.");
var utterance4 = new win2.SpeechSynthesisUtterance("Speak utterance 4.");
var eventOrder = ['start1', 'pause1', 'resume1', 'end1', 'start2', 'end2',
'start4', 'end4', 'start3', 'end3'];
utterance1.addEventListener('start', function(e) {
is(eventOrder.shift(), 'start1', 'start1');
win1.speechSynthesis.pause();
});
utterance1.addEventListener('pause', function(e) {
var expectedEvent = eventOrder.shift()
is(expectedEvent, 'pause1', 'pause1');
testSynthState(win1, { speaking: true, pending: false, paused: true});
testSynthState(win2, { speaking: true, pending: true, paused: false});
if (expectedEvent == 'pause1') {
win1.speechSynthesis.resume();
}
});
utterance1.addEventListener('resume', function(e) {
is(eventOrder.shift(), 'resume1', 'resume1');
testSynthState(win1, { speaking: true, pending: false, paused: false});
testSynthState(win2, { speaking: true, pending: true, paused: false});
win2.speechSynthesis.pause();
testSynthState(win1, { speaking: true, pending: false, paused: false});
// 1188099: currently, paused state is not gaurenteed to be immediate.
testSynthState(win2, { speaking: true, pending: true });
// We now make the utterance end.
SpecialPowers.wrap(win1.speechSynthesis).forceEnd();
});
utterance1.addEventListener('end', function(e) {
is(eventOrder.shift(), 'end1', 'end1');
testSynthState(win1, { speaking: false, pending: false, paused: false});
testSynthState(win2, { speaking: false, pending: true, paused: true});
win2.speechSynthesis.resume();
});
utterance2.addEventListener('start', function(e) {
is(eventOrder.shift(), 'start2', 'start2');
testSynthState(win1, { speaking: true, pending: false, paused: false});
testSynthState(win2, { speaking: true, pending: false, paused: false});
});
utterance2.addEventListener('end', function(e) {
is(eventOrder.shift(), 'end2', 'end2');
testSynthState(win1, { speaking: false, pending: false, paused: false});
testSynthState(win2, { speaking: false, pending: false, paused: false});
win1.speechSynthesis.pause();
testSynthState(win1, { speaking: false, pending: false, paused: true});
testSynthState(win2, { speaking: false, pending: false, paused: false});
win1.speechSynthesis.speak(utterance3);
win2.speechSynthesis.speak(utterance4);
testSynthState(win1, { speaking: false, pending: true, paused: true});
testSynthState(win2, { speaking: false, pending: true, paused: false});
});
utterance4.addEventListener('start', function(e) {
is(eventOrder.shift(), 'start4', 'start4');
testSynthState(win1, { speaking: true, pending: true, paused: true});
testSynthState(win2, { speaking: true, pending: false, paused: false});
win1.speechSynthesis.resume();
});
utterance4.addEventListener('end', function(e) {
is(eventOrder.shift(), 'end4', 'end4');
testSynthState(win1, { speaking: false, pending: true, paused: false});
testSynthState(win2, { speaking: false, pending: false, paused: false});
});
utterance3.addEventListener('start', function(e) {
is(eventOrder.shift(), 'start3', 'start3');
testSynthState(win1, { speaking: true, pending: false, paused: false});
testSynthState(win2, { speaking: true, pending: false, paused: false});
});
utterance3.addEventListener('end', function(e) {
is(eventOrder.shift(), 'end3', 'end3');
testSynthState(win1, { speaking: false, pending: false, paused: false});
testSynthState(win2, { speaking: false, pending: false, paused: false});
SimpleTest.finish();
});
win1.speechSynthesis.speak(utterance1);
win2.speechSynthesis.speak(utterance2);
});
</script>
</pre>
</body>
</html>

View File

@ -1,102 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1155034
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1155034: Check that indirect audio services dispatch their own events</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.info = parent.info;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
</script>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1155034">Mozilla Bug 1155034</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1155034 **/
function testFunc(done_cb) {
function test_with_events() {
info('test_with_events');
var utterance = new SpeechSynthesisUtterance("never end, callback events");
utterance.lang = 'it-IT-noend';
utterance.addEventListener('start', function(e) {
info('start test_with_events');
speechSynthesis.pause();
// Wait to see if we get some bad events we didn't expect.
});
utterance.addEventListener('pause', function(e) {
is(e.charIndex, 1, 'pause event charIndex matches service arguments');
is(e.elapsedTime, 1.5, 'pause event elapsedTime matches service arguments');
speechSynthesis.resume();
});
utterance.addEventListener('resume', function(e) {
is(e.charIndex, 1, 'resume event charIndex matches service arguments');
is(e.elapsedTime, 1.5, 'resume event elapsedTime matches service arguments');
speechSynthesis.cancel();
});
utterance.addEventListener('end', function(e) {
ok(e.charIndex, 1, 'resume event charIndex matches service arguments');
ok(e.elapsedTime, 1.5, 'end event elapsedTime matches service arguments');
test_no_events();
});
info('start speak');
speechSynthesis.speak(utterance);
}
function forbiddenEvent(e) {
ok(false, 'no "' + e.type + '" event was explicitly dispatched from the service')
}
function test_no_events() {
info('test_no_events');
var utterance = new SpeechSynthesisUtterance("never end");
utterance.lang = "it-IT-noevents-noend";
utterance.addEventListener('start', function(e) {
speechSynthesis.pause();
// Wait to see if we get some bad events we didn't expect.
setTimeout(function() {
ok(true, 'didn\'t get any unwanted events');
utterance.removeEventListener('end', forbiddenEvent);
SpecialPowers.wrap(speechSynthesis).forceEnd();
done_cb();
}, 1000);
});
utterance.addEventListener('pause', forbiddenEvent);
utterance.addEventListener('end', forbiddenEvent);
speechSynthesis.speak(utterance);
}
test_with_events();
}
// Run test with no global queue, and then run it with a global queue.
testFunc(function() {
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.force_global_queue', true]] }, function() {
testFunc(SimpleTest.finish)
});
});
</script>
</pre>
</body>
</html>

View File

@ -1,95 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=525444
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 525444: Web Speech API check all classes are present</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
</script>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
ok(SpeechSynthesis, "SpeechSynthesis exists in global scope");
ok(SpeechSynthesisVoice, "SpeechSynthesisVoice exists in global scope");
ok(SpeechSynthesisErrorEvent, "SpeechSynthesisErrorEvent exists in global scope");
ok(SpeechSynthesisEvent, "SpeechSynthesisEvent exists in global scope");
// SpeechSynthesisUtterance is the only type that has a constructor
// and writable properties
ok(SpeechSynthesisUtterance, "SpeechSynthesisUtterance exists in global scope");
var ssu = new SpeechSynthesisUtterance("hello world");
is(typeof ssu, "object", "SpeechSynthesisUtterance instance is an object");
is(ssu.text, "hello world", "SpeechSynthesisUtterance.text is correct");
is(ssu.volume, 1, "SpeechSynthesisUtterance.volume default is correct");
is(ssu.rate, 1, "SpeechSynthesisUtterance.rate default is correct");
is(ssu.pitch, 1, "SpeechSynthesisUtterance.pitch default is correct");
ssu.lang = "he-IL";
ssu.volume = 0.5;
ssu.rate = 2.0;
ssu.pitch = 1.5;
is(ssu.lang, "he-IL", "SpeechSynthesisUtterance.lang is correct");
is(ssu.volume, 0.5, "SpeechSynthesisUtterance.volume is correct");
is(ssu.rate, 2.0, "SpeechSynthesisUtterance.rate is correct");
is(ssu.pitch, 1.5, "SpeechSynthesisUtterance.pitch is correct");
// Assign a rate that is out of bounds
ssu.rate = 20;
is(ssu.rate, 10, "SpeechSynthesisUtterance.rate enforces max of 10");
ssu.rate = 0;
is(ssu.rate.toPrecision(1), "0.1", "SpeechSynthesisUtterance.rate enforces min of 0.1");
// Assign a volume which is out of bounds
ssu.volume = 2;
is(ssu.volume, 1, "SpeechSynthesisUtterance.volume enforces max of 1");
ssu.volume = -1;
is(ssu.volume, 0, "SpeechSynthesisUtterance.volume enforces min of 0");
// Assign a pitch which is out of bounds
ssu.pitch = 2.1;
is(ssu.pitch, 2, "SpeechSynthesisUtterance.pitch enforces max of 2");
ssu.pitch = -1;
is(ssu.pitch, 0, "SpeechSynthesisUtterance.pitch enforces min of 0");
// Test for singleton instance hanging off of window.
ok(speechSynthesis, "speechSynthesis exists in global scope");
is(typeof speechSynthesis, "object", "speechSynthesis instance is an object");
is(typeof speechSynthesis.speak, "function", "speechSynthesis.speak is a function");
is(typeof speechSynthesis.cancel, "function", "speechSynthesis.cancel is a function");
is(typeof speechSynthesis.pause, "function", "speechSynthesis.pause is a function");
is(typeof speechSynthesis.resume, "function", "speechSynthesis.resume is a function");
is(typeof speechSynthesis.getVoices, "function", "speechSynthesis.getVoices is a function");
is(typeof speechSynthesis.pending, "boolean", "speechSynthesis.pending is a boolean");
is(typeof speechSynthesis.speaking, "boolean", "speechSynthesis.speaking is a boolean");
is(typeof speechSynthesis.paused, "boolean", "speechSynthesis.paused is a boolean");
var voices1 = speechSynthesis.getVoices();
var voices2 = speechSynthesis.getVoices();
ok(voices1.length == voices2.length, "Voice count matches");
for (var i in voices1) {
ok(voices1[i] == voices2[i], "Voice instance matches");
}
SimpleTest.finish();
</script>
</pre>
</body>
</html>

View File

@ -1,100 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1150315
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1150315: Check that successive cancel/speak calls work</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.info = parent.info;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
</script>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1150315">Mozilla Bug 1150315</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1150315 **/
function testFunc(done_cb) {
var gotEndEvent = false;
// A long utterance that we will interrupt.
var utterance = new SpeechSynthesisUtterance("Donec ac nunc feugiat, posuere " +
"mauris id, pharetra velit. Donec fermentum orci nunc, sit amet maximus" +
"dui tincidunt ut. Sed ultricies ac nisi a laoreet. Proin interdum," +
"libero maximus hendrerit posuere, lorem risus egestas nisl, a" +
"ultricies massa justo eu nisi. Duis mattis nibh a ligula tincidunt" +
"tincidunt non eu erat. Sed bibendum varius vulputate. Cras leo magna," +
"ornare ac posuere vel, luctus id metus. Mauris nec quam ac augue" +
"consectetur bibendum. Integer a commodo tortor. Duis semper dolor eu" +
"facilisis facilisis. Etiam venenatis turpis est, quis tincidunt velit" +
"suscipit a. Cras semper orci in sapien rhoncus bibendum. Suspendisse" +
"eu ex lobortis, finibus enim in, condimentum quam. Maecenas eget dui" +
"ipsum. Aliquam tortor leo, interdum eget congue ut, tempor id elit.");
utterance.addEventListener('start', function(e) {
ok(true, 'start utterance 1');
speechSynthesis.cancel();
info('cancel!');
speechSynthesis.speak(utterance2);
info('speak??');
});
var utterance2 = new SpeechSynthesisUtterance("Proin ornare neque vitae " +
"risus mattis rutrum. Suspendisse a velit ut est convallis aliquet." +
"Nullam ante elit, malesuada vel luctus rutrum, ultricies nec libero." +
"Praesent eu iaculis orci. Sed nisl diam, sodales ac purus et," +
"volutpat interdum tortor. Nullam aliquam porta elit et maximus. Cras" +
"risus lectus, elementum vel sodales vel, ultricies eget lectus." +
"Curabitur velit lacus, mollis vel finibus et, molestie sit amet" +
"sapien. Proin vitae dolor ac augue posuere efficitur ac scelerisque" +
"diam. Nulla sed odio elit.");
utterance2.addEventListener('start', function() {
info('start');
speechSynthesis.cancel();
speechSynthesis.speak(utterance3);
});
utterance2.addEventListener('end', function(e) {
gotEndEvent = true;
});
var utterance3 = new SpeechSynthesisUtterance("Hello, world 3!");
utterance3.addEventListener('start', function() {
ok(gotEndEvent, "didn't get start event for this utterance");
});
utterance3.addEventListener('end', done_cb);
// Speak/cancel while paused (Bug 1187105)
speechSynthesis.pause();
speechSynthesis.speak(new SpeechSynthesisUtterance("hello."));
ok(speechSynthesis.pending, "paused speechSynthesis has an utterance queued.");
speechSynthesis.cancel();
ok(!speechSynthesis.pending, "paused speechSynthesis has no utterance queued.");
speechSynthesis.resume();
speechSynthesis.speak(utterance);
ok(!speechSynthesis.speaking, "speechSynthesis is not speaking yet.");
ok(speechSynthesis.pending, "speechSynthesis has an utterance queued.");
}
// Run test with no global queue, and then run it with a global queue.
testFunc(function() {
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.force_global_queue', true]] }, function() {
testFunc(SimpleTest.finish)
});
});
</script>
</pre>
</body>
</html>

View File

@ -1,46 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1226015
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1226015</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.info = parent.info;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
</script>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1226015">Mozilla Bug 1226015</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1226015 **/
function testFunc(done_cb) {
var utterance = new SpeechSynthesisUtterance();
utterance.lang = 'it-IT-failatstart';
speechSynthesis.speak(utterance);
speechSynthesis.cancel();
ok(true, "we didn't crash, that is good.")
SimpleTest.finish();
}
// Run test with no global queue, and then run it with a global queue.
testFunc();
</script>
</pre>
</body>
</html>

View File

@ -1,85 +0,0 @@
<!DOCTYPE HTML>
<html lang="en-US">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=525444
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 525444: Web Speech API, check speech synth queue</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
</script>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=525444">Mozilla Bug 525444</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
// XXX: Rate and pitch are not tested.
var langUriMap = {};
for (var voice of speechSynthesis.getVoices()) {
langUriMap[voice.lang] = voice.voiceURI;
ok(true, voice.lang + ' ' + voice.voiceURI + ' ' + voice.default);
is(voice.default, voice.lang == 'en-JM', 'Only Jamaican voice should be default');
}
ok(langUriMap['en-JM'], 'No English-Jamaican voice');
ok(langUriMap['en-GB'], 'No English-British voice');
ok(langUriMap['en-CA'], 'No English-Canadian voice');
ok(langUriMap['fr-CA'], 'No French-Canadian voice');
ok(langUriMap['es-MX'], 'No Spanish-Mexican voice');
ok(langUriMap['it-IT-fail'], 'No Failing Italian voice');
function testFunc(done_cb) {
synthTestQueue(
[[{text: "Hello, world."},
{ uri: langUriMap['en-JM'] }],
[{text: "Bonjour tout le monde .",
args: { lang: "fr", rate: 0.5, pitch: 0.75 }},
{ uri: langUriMap['fr-CA'], rate: 0.5, pitch: 0.75}],
[{text: "How are you doing?", args: { lang: "en-GB" } },
{ rate: 1, pitch: 1, uri: langUriMap['en-GB']}],
[{text: "Come stai?", args: { lang: "it-IT-fail" } },
{ rate: 1, pitch: 1, uri: langUriMap['it-IT-fail'], err: true }],
[{text: "¡hasta mañana!", args: { lang: "es-MX" } },
{ uri: langUriMap['es-MX'] }]],
function () {
var test_data = [];
var voices = speechSynthesis.getVoices();
for (var voice of voices) {
if (voice.voiceURI.indexOf('urn:moz-tts:fake-direct') < 0) {
continue;
}
test_data.push([{text: "Hello world", args: { voice: voice} },
{uri: voice.voiceURI}]);
}
synthTestQueue(test_data, done_cb);
});
}
// Run test with no global queue, and then run it with a global queue.
testFunc(function() {
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.force_global_queue', true]] }, function() {
testFunc(SimpleTest.finish)
});
});
</script>
</pre>
</body>
</html>

View File

@ -1,53 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295: Web Speech API check all classes are present</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.info = parent.info;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
</script>
<script type="application/javascript" src="common.js"></script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
var gotStartEvent = false;
var gotBoundaryEvent = false;
var utterance = new SpeechSynthesisUtterance("Hello, world!");
utterance.addEventListener('start', function(e) {
ok(speechSynthesis.speaking, "speechSynthesis is speaking.");
ok(!speechSynthesis.pending, "speechSynthesis has no other utterances queued.");
gotStartEvent = true;
});
utterance.addEventListener('end', function(e) {
ok(!speechSynthesis.speaking, "speechSynthesis is not speaking.");
ok(!speechSynthesis.pending, "speechSynthesis has no other utterances queued.");
ok(gotStartEvent, "Got 'start' event.");
info('end ' + e.elapsedTime);
SimpleTest.finish();
});
speechSynthesis.speak(utterance);
ok(!speechSynthesis.speaking, "speechSynthesis is not speaking yet.");
ok(speechSynthesis.pending, "speechSynthesis has an utterance queued.");
</script>
</pre>
</body>
</html>

View File

@ -1,26 +0,0 @@
[DEFAULT]
tags=msg
subsuite = media
support-files =
common.js
file_bfcache_frame.html
file_setup.html
file_speech_queue.html
file_speech_simple.html
file_speech_cancel.html
file_speech_error.html
file_indirect_service_events.html
file_global_queue.html
file_global_queue_cancel.html
file_global_queue_pause.html
[test_setup.html]
[test_speech_queue.html]
[test_speech_simple.html]
[test_speech_cancel.html]
[test_speech_error.html]
[test_indirect_service_events.html]
[test_global_queue.html]
[test_global_queue_cancel.html]
[test_global_queue_pause.html]
[test_bfcache.html]

View File

@ -1,401 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.h"
#include "nsFakeSynthServices.h"
#include "nsPrintfCString.h"
#include "nsIWeakReferenceUtils.h"
#include "SharedBuffer.h"
#include "nsISimpleEnumerator.h"
#include "mozilla/dom/nsSynthVoiceRegistry.h"
#include "mozilla/dom/nsSpeechTask.h"
#include "nsThreadUtils.h"
#include "prenv.h"
#include "mozilla/Preferences.h"
#include "mozilla/DebugOnly.h"
#define CHANNELS 1
#define SAMPLERATE 1600
namespace mozilla {
namespace dom {
StaticRefPtr<nsFakeSynthServices> nsFakeSynthServices::sSingleton;
enum VoiceFlags
{
eSuppressEvents = 1,
eSuppressEnd = 2,
eFailAtStart = 4,
eFail = 8
};
struct VoiceDetails
{
const char* uri;
const char* name;
const char* lang;
bool defaultVoice;
uint32_t flags;
};
static const VoiceDetails sDirectVoices[] = {
{"urn:moz-tts:fake-direct:bob", "Bob Marley", "en-JM", true, 0},
{"urn:moz-tts:fake-direct:amy", "Amy Winehouse", "en-GB", false, 0},
{"urn:moz-tts:fake-direct:lenny", "Leonard Cohen", "en-CA", false, 0},
{"urn:moz-tts:fake-direct:celine", "Celine Dion", "fr-CA", false, 0},
{"urn:moz-tts:fake-direct:julie", "Julieta Venegas", "es-MX", false, },
};
static const VoiceDetails sIndirectVoices[] = {
{"urn:moz-tts:fake-indirect:zanetta", "Zanetta Farussi", "it-IT", false, 0},
{"urn:moz-tts:fake-indirect:margherita", "Margherita Durastanti", "it-IT-noevents-noend", false, eSuppressEvents | eSuppressEnd},
{"urn:moz-tts:fake-indirect:teresa", "Teresa Cornelys", "it-IT-noend", false, eSuppressEnd},
{"urn:moz-tts:fake-indirect:cecilia", "Cecilia Bartoli", "it-IT-failatstart", false, eFailAtStart},
{"urn:moz-tts:fake-indirect:gottardo", "Gottardo Aldighieri", "it-IT-fail", false, eFail},
};
// FakeSynthCallback
class FakeSynthCallback : public nsISpeechTaskCallback
{
public:
explicit FakeSynthCallback(nsISpeechTask* aTask) : mTask(aTask) { }
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(FakeSynthCallback, nsISpeechTaskCallback)
NS_IMETHOD OnPause() override
{
if (mTask) {
mTask->DispatchPause(1.5, 1);
}
return NS_OK;
}
NS_IMETHOD OnResume() override
{
if (mTask) {
mTask->DispatchResume(1.5, 1);
}
return NS_OK;
}
NS_IMETHOD OnCancel() override
{
if (mTask) {
mTask->DispatchEnd(1.5, 1);
}
return NS_OK;
}
NS_IMETHOD OnVolumeChanged(float aVolume) override
{
return NS_OK;
}
private:
virtual ~FakeSynthCallback() { }
nsCOMPtr<nsISpeechTask> mTask;
};
NS_IMPL_CYCLE_COLLECTION(FakeSynthCallback, mTask);
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FakeSynthCallback)
NS_INTERFACE_MAP_ENTRY(nsISpeechTaskCallback)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsISpeechTaskCallback)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(FakeSynthCallback)
NS_IMPL_CYCLE_COLLECTING_RELEASE(FakeSynthCallback)
// FakeDirectAudioSynth
class FakeDirectAudioSynth : public nsISpeechService
{
public:
FakeDirectAudioSynth() { }
NS_DECL_ISUPPORTS
NS_DECL_NSISPEECHSERVICE
private:
virtual ~FakeDirectAudioSynth() { }
};
NS_IMPL_ISUPPORTS(FakeDirectAudioSynth, nsISpeechService)
NS_IMETHODIMP
FakeDirectAudioSynth::Speak(const nsAString& aText, const nsAString& aUri,
float aVolume, float aRate, float aPitch,
nsISpeechTask* aTask)
{
class Runnable final : public mozilla::Runnable
{
public:
Runnable(nsISpeechTask* aTask, const nsAString& aText) :
mTask(aTask), mText(aText)
{
}
NS_IMETHOD Run() override
{
RefPtr<FakeSynthCallback> cb = new FakeSynthCallback(nullptr);
mTask->Setup(cb, CHANNELS, SAMPLERATE, 2);
// Just an arbitrary multiplier. Pretend that each character is
// synthesized to 40 frames.
uint32_t frames_length = 40 * mText.Length();
auto frames = MakeUnique<int16_t[]>(frames_length);
mTask->SendAudioNative(frames.get(), frames_length);
mTask->SendAudioNative(nullptr, 0);
return NS_OK;
}
private:
nsCOMPtr<nsISpeechTask> mTask;
nsString mText;
};
nsCOMPtr<nsIRunnable> runnable = new Runnable(aTask, aText);
NS_DispatchToMainThread(runnable);
return NS_OK;
}
NS_IMETHODIMP
FakeDirectAudioSynth::GetServiceType(SpeechServiceType* aServiceType)
{
*aServiceType = nsISpeechService::SERVICETYPE_DIRECT_AUDIO;
return NS_OK;
}
// FakeDirectAudioSynth
class FakeIndirectAudioSynth : public nsISpeechService
{
public:
FakeIndirectAudioSynth() {}
NS_DECL_ISUPPORTS
NS_DECL_NSISPEECHSERVICE
private:
virtual ~FakeIndirectAudioSynth() { }
};
NS_IMPL_ISUPPORTS(FakeIndirectAudioSynth, nsISpeechService)
NS_IMETHODIMP
FakeIndirectAudioSynth::Speak(const nsAString& aText, const nsAString& aUri,
float aVolume, float aRate, float aPitch,
nsISpeechTask* aTask)
{
class DispatchStart final : public Runnable
{
public:
explicit DispatchStart(nsISpeechTask* aTask) :
mTask(aTask)
{
}
NS_IMETHOD Run() override
{
mTask->DispatchStart();
return NS_OK;
}
private:
nsCOMPtr<nsISpeechTask> mTask;
};
class DispatchEnd final : public Runnable
{
public:
DispatchEnd(nsISpeechTask* aTask, const nsAString& aText) :
mTask(aTask), mText(aText)
{
}
NS_IMETHOD Run() override
{
mTask->DispatchEnd(mText.Length()/2, mText.Length());
return NS_OK;
}
private:
nsCOMPtr<nsISpeechTask> mTask;
nsString mText;
};
class DispatchError final : public Runnable
{
public:
DispatchError(nsISpeechTask* aTask, const nsAString& aText) :
mTask(aTask), mText(aText)
{
}
NS_IMETHOD Run() override
{
mTask->DispatchError(mText.Length()/2, mText.Length());
return NS_OK;
}
private:
nsCOMPtr<nsISpeechTask> mTask;
nsString mText;
};
uint32_t flags = 0;
for (uint32_t i = 0; i < ArrayLength(sIndirectVoices); i++) {
if (aUri.EqualsASCII(sIndirectVoices[i].uri)) {
flags = sIndirectVoices[i].flags;
}
}
if (flags & eFailAtStart) {
return NS_ERROR_FAILURE;
}
RefPtr<FakeSynthCallback> cb = new FakeSynthCallback(
(flags & eSuppressEvents) ? nullptr : aTask);
aTask->Setup(cb, 0, 0, 0);
nsCOMPtr<nsIRunnable> runnable = new DispatchStart(aTask);
NS_DispatchToMainThread(runnable);
if (flags & eFail) {
runnable = new DispatchError(aTask, aText);
NS_DispatchToMainThread(runnable);
} else if ((flags & eSuppressEnd) == 0) {
runnable = new DispatchEnd(aTask, aText);
NS_DispatchToMainThread(runnable);
}
return NS_OK;
}
NS_IMETHODIMP
FakeIndirectAudioSynth::GetServiceType(SpeechServiceType* aServiceType)
{
*aServiceType = nsISpeechService::SERVICETYPE_INDIRECT_AUDIO;
return NS_OK;
}
// nsFakeSynthService
NS_INTERFACE_MAP_BEGIN(nsFakeSynthServices)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsFakeSynthServices)
NS_IMPL_RELEASE(nsFakeSynthServices)
nsFakeSynthServices::nsFakeSynthServices()
{
}
nsFakeSynthServices::~nsFakeSynthServices()
{
}
static void
AddVoices(nsISpeechService* aService, const VoiceDetails* aVoices, uint32_t aLength)
{
RefPtr<nsSynthVoiceRegistry> registry = nsSynthVoiceRegistry::GetInstance();
for (uint32_t i = 0; i < aLength; i++) {
NS_ConvertUTF8toUTF16 name(aVoices[i].name);
NS_ConvertUTF8toUTF16 uri(aVoices[i].uri);
NS_ConvertUTF8toUTF16 lang(aVoices[i].lang);
// These services can handle more than one utterance at a time and have
// several speaking simultaniously. So, aQueuesUtterances == false
registry->AddVoice(aService, uri, name, lang, true, false);
if (aVoices[i].defaultVoice) {
registry->SetDefaultVoice(uri, true);
}
}
registry->NotifyVoicesChanged();
}
void
nsFakeSynthServices::Init()
{
mDirectService = new FakeDirectAudioSynth();
AddVoices(mDirectService, sDirectVoices, ArrayLength(sDirectVoices));
mIndirectService = new FakeIndirectAudioSynth();
AddVoices(mIndirectService, sIndirectVoices, ArrayLength(sIndirectVoices));
}
// nsIObserver
NS_IMETHODIMP
nsFakeSynthServices::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData)
{
MOZ_ASSERT(NS_IsMainThread());
if(NS_WARN_IF(!(!strcmp(aTopic, "speech-synth-started")))) {
return NS_ERROR_UNEXPECTED;
}
if (Preferences::GetBool("media.webspeech.synth.test")) {
NS_DispatchToMainThread(NewRunnableMethod(this, &nsFakeSynthServices::Init));
}
return NS_OK;
}
// static methods
nsFakeSynthServices*
nsFakeSynthServices::GetInstance()
{
MOZ_ASSERT(NS_IsMainThread());
if (!XRE_IsParentProcess()) {
MOZ_ASSERT(false, "nsFakeSynthServices can only be started on main gecko process");
return nullptr;
}
if (!sSingleton) {
sSingleton = new nsFakeSynthServices();
}
return sSingleton;
}
already_AddRefed<nsFakeSynthServices>
nsFakeSynthServices::GetInstanceForService()
{
RefPtr<nsFakeSynthServices> picoService = GetInstance();
return picoService.forget();
}
void
nsFakeSynthServices::Shutdown()
{
if (!sSingleton) {
return;
}
sSingleton = nullptr;
}
} // namespace dom
} // namespace mozilla

View File

@ -1,52 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsFakeSynthServices_h
#define nsFakeSynthServices_h
#include "nsTArray.h"
#include "nsIObserver.h"
#include "nsIThread.h"
#include "nsISpeechService.h"
#include "nsRefPtrHashtable.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Monitor.h"
namespace mozilla {
namespace dom {
class nsFakeSynthServices : public nsIObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
nsFakeSynthServices();
static nsFakeSynthServices* GetInstance();
static already_AddRefed<nsFakeSynthServices> GetInstanceForService();
static void Shutdown();
private:
virtual ~nsFakeSynthServices();
void Init();
nsCOMPtr<nsISpeechService> mDirectService;
nsCOMPtr<nsISpeechService> mIndirectService;
static StaticRefPtr<nsFakeSynthServices> sSingleton;
};
} // namespace dom
} // namespace mozilla
#endif

View File

@ -1,32 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1254378
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1254378: Web Speech API check all classes are present</title>
<script type="application/javascript">
window.SimpleTest = parent.SimpleTest;
window.is = parent.is;
window.isnot = parent.isnot;
window.ok = parent.ok;
</script>
</head>
<body>
<script type="application/javascript">
/** Test for Bug 1254378 **/
function onVoicesChanged() {
isnot(speechSynthesis.getVoices().length, 0, "Voices added");
speechSynthesis.removeEventListener("voiceschanged", onVoicesChanged);
SimpleTest.finish();
}
speechSynthesis.addEventListener("voiceschanged", onVoicesChanged);
is(speechSynthesis.getVoices().length, 0, "No voices added initially");
</script>
</body>
</html>

View File

@ -1,7 +0,0 @@
[DEFAULT]
tags=msg
subsuite = media
support-files =
file_voiceschanged.html
[test_voiceschanged.html]

View File

@ -1,32 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1254378
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1254378: Emit onvoiceschanged when voices first added</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1254378">Mozilla Bug 1254378</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1254378 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({ set: [['media.webspeech.synth.enabled', true]] },
function() { document.getElementById("testFrame").src = "file_voiceschanged.html"; });
</script>
</pre>
</body>
</html>

View File

@ -1,45 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1230533
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1230533: Test speech is stopped from a window when unloaded</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1230533">Mozilla Bug 1230533</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
SimpleTest.waitForExplicitFinish();
var iframe;
function onDone() {
SimpleTest.finish();
}
SpecialPowers.pushPrefEnv({ set: [
['media.webspeech.synth.enabled', true],
['media.webspeech.synth.force_global_queue', true],
['browser.sessionhistory.cache_subframes', true],
['browser.sessionhistory.max_total_viewers', 10]] },
function() {
loadSpeechTest("file_bfcache_frame.html");
});
</script>
</pre>
</body>
</html>

View File

@ -1,35 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1188099
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1188099: Global queue should correctly schedule utterances</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1188099">Mozilla Bug 1188099</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.enabled', true],
['media.webspeech.synth.force_global_queue', true]] },
function() { loadSpeechTest("file_global_queue.html"); });
</script>
</pre>
</body>
</html>

View File

@ -1,35 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1188099
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1188099: Calling cancel() should work correctly with global queue</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1188099">Mozilla Bug 1188099</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.enabled', true],
['media.webspeech.synth.force_global_queue', true]] },
function() { loadSpeechTest("file_global_queue_cancel.html"); });
</script>
</pre>
</body>
</html>

View File

@ -1,35 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1188099
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1188099: Calling pause() should work correctly with global queue</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1188099">Mozilla Bug 1188099</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.enabled', true],
['media.webspeech.synth.force_global_queue', true]] },
function() { loadSpeechTest("file_global_queue_pause.html"); });
</script>
</pre>
</body>
</html>

View File

@ -1,36 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1155034
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1155034: Check that indirect audio services dispatch their own events</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1155034">Mozilla Bug 1155034</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1155034 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.enabled', true],
['media.webspeech.synth.force_global_queue', false]] },
function() { loadSpeechTest("file_indirect_service_events.html"); });
</script>
</pre>
</body>
</html>

View File

@ -1,32 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=525444
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 525444: Web Speech API check all classes are present</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv({ set: [['media.webspeech.synth.enabled', true]] },
function() { document.getElementById("testFrame").src = "file_setup.html"; });
</script>
</pre>
</body>
</html>

View File

@ -1,35 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1150315
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1150315: Web Speech API check all classes are present</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1150315">Mozilla Bug 1150315</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1150315 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.enabled', true],
['media.webspeech.synth.force_global_queue', false]] },
function() { loadSpeechTest("file_speech_cancel.html"); });
</script>
</pre>
</body>
</html>

View File

@ -1,35 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1226015
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1150315: Web Speech API check all classes are present</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1226015">Mozilla Bug 1226015</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 1226015 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.enabled', true],
['media.webspeech.synth.force_global_queue', false]] },
function() { loadSpeechTest("file_speech_error.html"); });
</script>
</pre>
</body>
</html>

View File

@ -1,37 +0,0 @@
<!DOCTYPE HTML>
<html lang="en-US">
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=525444
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 525444: Web Speech API, check speech synth queue</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=525444">Mozilla Bug 525444</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.enabled', true],
['media.webspeech.synth.force_global_queue', false]] },
function() {
loadSpeechTest("file_speech_queue.html");
});
</script>
</pre>
</body>
</html>

View File

@ -1,34 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=650295
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 650295: Web Speech API check all classes are present</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=650295">Mozilla Bug 650295</a>
<p id="display"></p>
<iframe id="testFrame"></iframe>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 525444 **/
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ set: [['media.webspeech.synth.enabled', true]] },
function() { loadSpeechTest("file_speech_simple.html"); });
</script>
</pre>
</body>
</html>

View File

@ -1,22 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Constructor,
Pref="media.webspeech.recognition.enable",
Func="SpeechRecognition::IsAuthorized"]
interface SpeechGrammar {
[Throws]
attribute DOMString src;
[Throws]
attribute float weight;
};

View File

@ -1,23 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Constructor, Pref="media.webspeech.recognition.enable",
Func="SpeechRecognition::IsAuthorized"]
interface SpeechGrammarList {
readonly attribute unsigned long length;
[Throws]
getter SpeechGrammar item(unsigned long index);
[Throws]
void addFromURI(DOMString src, optional float weight);
[Throws]
void addFromString(DOMString string, optional float weight);
};

View File

@ -1,45 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Constructor,
Pref="media.webspeech.recognition.enable",
Func="SpeechRecognition::IsAuthorized"]
interface SpeechRecognition : EventTarget {
// recognition parameters
attribute SpeechGrammarList grammars;
attribute DOMString lang;
[Throws]
attribute boolean continuous;
attribute boolean interimResults;
attribute unsigned long maxAlternatives;
[Throws]
attribute DOMString serviceURI;
// methods to drive the speech interaction
[Throws, UnsafeInPrerendering]
void start(optional MediaStream stream);
void stop();
void abort();
// event methods
attribute EventHandler onaudiostart;
attribute EventHandler onsoundstart;
attribute EventHandler onspeechstart;
attribute EventHandler onspeechend;
attribute EventHandler onsoundend;
attribute EventHandler onaudioend;
attribute EventHandler onresult;
attribute EventHandler onnomatch;
attribute EventHandler onerror;
attribute EventHandler onstart;
attribute EventHandler onend;
};

View File

@ -1,18 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Pref="media.webspeech.recognition.enable",
Func="SpeechRecognition::IsAuthorized"]
interface SpeechRecognitionAlternative {
readonly attribute DOMString transcript;
readonly attribute float confidence;
};

View File

@ -1,31 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
enum SpeechRecognitionErrorCode {
"no-speech",
"aborted",
"audio-capture",
"network",
"not-allowed",
"service-not-allowed",
"bad-grammar",
"language-not-supported"
};
[Pref="media.webspeech.recognition.enable",
Func="SpeechRecognition::IsAuthorized",
Constructor(DOMString type, optional SpeechRecognitionErrorInit eventInitDict)]
interface SpeechRecognitionError : Event
{
readonly attribute SpeechRecognitionErrorCode error;
readonly attribute DOMString? message;
};
dictionary SpeechRecognitionErrorInit : EventInit
{
SpeechRecognitionErrorCode error = "no-speech";
DOMString message = "";
};

View File

@ -1,25 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
interface nsISupports;
[Pref="media.webspeech.recognition.enable",
Func="SpeechRecognition::IsAuthorized",
Constructor(DOMString type, optional SpeechRecognitionEventInit eventInitDict)]
interface SpeechRecognitionEvent : Event
{
readonly attribute unsigned long resultIndex;
readonly attribute SpeechRecognitionResultList? results;
readonly attribute any interpretation;
readonly attribute Document? emma;
};
dictionary SpeechRecognitionEventInit : EventInit
{
unsigned long resultIndex = 0;
SpeechRecognitionResultList? results = null;
any interpretation = null;
Document? emma = null;
};

View File

@ -1,19 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Pref="media.webspeech.recognition.enable",
Func="SpeechRecognition::IsAuthorized"]
interface SpeechRecognitionResult {
readonly attribute unsigned long length;
getter SpeechRecognitionAlternative item(unsigned long index);
readonly attribute boolean isFinal;
};

View File

@ -1,18 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://dvcs.w3.org/hg/speech-api/raw-file/tip/speechapi.html
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[Pref="media.webspeech.recognition.enable",
Func="SpeechRecognition::IsAuthorized"]
interface SpeechRecognitionResultList {
readonly attribute unsigned long length;
getter SpeechRecognitionResult item(unsigned long index);
};

View File

@ -616,14 +616,6 @@ if CONFIG['MOZ_WEBRTC']:
if CONFIG['MOZ_WEBSPEECH']:
WEBIDL_FILES += [
'SpeechGrammar.webidl',
'SpeechGrammarList.webidl',
'SpeechRecognition.webidl',
'SpeechRecognitionAlternative.webidl',
'SpeechRecognitionError.webidl',
'SpeechRecognitionEvent.webidl',
'SpeechRecognitionResult.webidl',
'SpeechRecognitionResultList.webidl',
'SpeechSynthesis.webidl',
'SpeechSynthesisErrorEvent.webidl',
'SpeechSynthesisEvent.webidl',
@ -725,7 +717,6 @@ if CONFIG['MOZ_WEBRTC']:
if CONFIG['MOZ_WEBSPEECH']:
GENERATED_EVENTS_WEBIDL_FILES += [
'SpeechRecognitionEvent.webidl',
'SpeechSynthesisErrorEvent.webidl',
'SpeechSynthesisEvent.webidl',
]

View File

@ -76,16 +76,9 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
if CONFIG['MOZ_WEBSPEECH']:
LOCAL_INCLUDES += [
'/dom/media/webspeech/recognition',
'/dom/media/webspeech/synth',
]
if CONFIG['MOZ_WEBSPEECH_POCKETSPHINX']:
LOCAL_INCLUDES += [
'/media/pocketsphinx',
'/media/sphinxbase',
]
if CONFIG['MOZ_SECUREELEMENT']:
LOCAL_INCLUDES += [
'/dom/secureelement',

View File

@ -91,12 +91,6 @@
#include "mozilla/OSFileConstants.h"
#include "mozilla/Services.h"
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
#include "mozilla/dom/FakeSpeechRecognitionService.h"
#endif
#ifdef MOZ_WEBSPEECH_POCKETSPHINX
#include "mozilla/dom/PocketSphinxSpeechRecognitionService.h"
#endif
#ifdef MOZ_WEBSPEECH
#include "mozilla/dom/nsSynthVoiceRegistry.h"
#endif
@ -518,13 +512,6 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AudioChannelService, AudioChannelServic
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WebSocketEventService, WebSocketEventService::GetOrCreate)
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
NS_GENERIC_FACTORY_CONSTRUCTOR(FakeSpeechRecognitionService)
#endif
#ifdef MOZ_WEBSPEECH_POCKETSPHINX
NS_GENERIC_FACTORY_CONSTRUCTOR(PocketSphinxSpeechRecognitionService)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(nsContentSecurityManager)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCSPContext)
NS_GENERIC_FACTORY_CONSTRUCTOR(CSPService)
@ -681,12 +668,6 @@ NS_DEFINE_NAMED_CID(UDPSOCKETCHILD_CID);
NS_DEFINE_NAMED_CID(NS_TIMESERVICE_CID);
NS_DEFINE_NAMED_CID(NS_MEDIASTREAMCONTROLLERSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_MEDIAMANAGERSERVICE_CID);
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
NS_DEFINE_NAMED_CID(NS_FAKE_SPEECH_RECOGNITION_SERVICE_CID);
#endif
#ifdef MOZ_WEBSPEECH_POCKETSPHINX
NS_DEFINE_NAMED_CID(NS_POCKETSPHINX_SPEECH_RECOGNITION_SERVICE_CID);
#endif
#ifdef MOZ_WEBSPEECH
NS_DEFINE_NAMED_CID(NS_SYNTHVOICEREGISTRY_CID);
#endif
@ -917,12 +898,6 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kNS_AUDIOCHANNEL_SERVICE_CID, false, nullptr, AudioChannelServiceConstructor },
{ &kNS_WEBSOCKETEVENT_SERVICE_CID, false, nullptr, WebSocketEventServiceConstructor },
{ &kNS_FOCUSMANAGER_CID, false, nullptr, CreateFocusManager },
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
{ &kNS_FAKE_SPEECH_RECOGNITION_SERVICE_CID, false, nullptr, FakeSpeechRecognitionServiceConstructor },
#endif
#ifdef MOZ_WEBSPEECH_POCKETSPHINX
{ &kNS_POCKETSPHINX_SPEECH_RECOGNITION_SERVICE_CID, false, nullptr, PocketSphinxSpeechRecognitionServiceConstructor },
#endif
#ifdef MOZ_WEBSPEECH
{ &kNS_SYNTHVOICEREGISTRY_CID, true, nullptr, nsSynthVoiceRegistryConstructor },
#endif
@ -1045,12 +1020,6 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ "@mozilla.org/audiochannel/service;1", &kNS_AUDIOCHANNEL_SERVICE_CID },
{ "@mozilla.org/websocketevent/service;1", &kNS_WEBSOCKETEVENT_SERVICE_CID },
{ "@mozilla.org/focus-manager;1", &kNS_FOCUSMANAGER_CID },
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
{ NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX "fake", &kNS_FAKE_SPEECH_RECOGNITION_SERVICE_CID },
#endif
#ifdef MOZ_WEBSPEECH_POCKETSPHINX
{ NS_SPEECH_RECOGNITION_SERVICE_CONTRACTID_PREFIX "pocketsphinx-en-US", &kNS_POCKETSPHINX_SPEECH_RECOGNITION_SERVICE_CID },
#endif
#ifdef MOZ_WEBSPEECH
{ NS_SYNTHVOICEREGISTRY_CONTRACTID, &kNS_SYNTHVOICEREGISTRY_CID },
#endif

View File

@ -1,386 +0,0 @@
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 2006 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* This work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
*/
/* cmdln_macro.h - Command line definitions for PocketSphinx */
#ifndef __PS_CMDLN_MACRO_H__
#define __PS_CMDLN_MACRO_H__
#include <sphinxbase/cmd_ln.h>
#include <sphinxbase/feat.h>
#include <sphinxbase/fe.h>
/** Minimal set of command-line options for PocketSphinx. */
#define POCKETSPHINX_OPTIONS \
waveform_to_cepstral_command_line_macro(), \
cepstral_to_feature_command_line_macro(), \
POCKETSPHINX_ACMOD_OPTIONS, \
POCKETSPHINX_BEAM_OPTIONS, \
POCKETSPHINX_SEARCH_OPTIONS, \
POCKETSPHINX_DICT_OPTIONS, \
POCKETSPHINX_NGRAM_OPTIONS, \
POCKETSPHINX_FSG_OPTIONS, \
POCKETSPHINX_KWS_OPTIONS, \
POCKETSPHINX_DEBUG_OPTIONS
/** Options for debugging and logging. */
#define POCKETSPHINX_DEBUG_OPTIONS \
{ "-logfn", \
ARG_STRING, \
NULL, \
"File to write log messages in" \
}, \
{ "-debug", \
ARG_INT32, \
NULL, \
"Verbosity level for debugging messages" \
}, \
{ "-mfclogdir", \
ARG_STRING, \
NULL, \
"Directory to log feature files to" \
}, \
{ "-rawlogdir", \
ARG_STRING, \
NULL, \
"Directory to log raw audio files to" }, \
{ "-senlogdir", \
ARG_STRING, \
NULL, \
"Directory to log senone score files to" \
}
/** Options defining beam width parameters for tuning the search. */
#define POCKETSPHINX_BEAM_OPTIONS \
{ "-beam", \
ARG_FLOAT64, \
"1e-48", \
"Beam width applied to every frame in Viterbi search (smaller values mean wider beam)" }, \
{ "-wbeam", \
ARG_FLOAT64, \
"7e-29", \
"Beam width applied to word exits" }, \
{ "-pbeam", \
ARG_FLOAT64, \
"1e-48", \
"Beam width applied to phone transitions" }, \
{ "-lpbeam", \
ARG_FLOAT64, \
"1e-40", \
"Beam width applied to last phone in words" }, \
{ "-lponlybeam", \
ARG_FLOAT64, \
"7e-29", \
"Beam width applied to last phone in single-phone words" }, \
{ "-fwdflatbeam", \
ARG_FLOAT64, \
"1e-64", \
"Beam width applied to every frame in second-pass flat search" }, \
{ "-fwdflatwbeam", \
ARG_FLOAT64, \
"7e-29", \
"Beam width applied to word exits in second-pass flat search" }, \
{ "-pl_window", \
ARG_INT32, \
"5", \
"Phoneme lookahead window size, in frames" }, \
{ "-pl_beam", \
ARG_FLOAT64, \
"1e-10", \
"Beam width applied to phone loop search for lookahead" }, \
{ "-pl_pbeam", \
ARG_FLOAT64, \
"1e-10", \
"Beam width applied to phone loop transitions for lookahead" }, \
{ "-pl_pip", \
ARG_FLOAT32, \
"1.0", \
"Phone insertion penalty for phone loop" }, \
{ "-pl_weight", \
ARG_FLOAT64, \
"3.0", \
"Weight for phoneme lookahead penalties" } \
/** Options defining other parameters for tuning the search. */
#define POCKETSPHINX_SEARCH_OPTIONS \
{ "-compallsen", \
ARG_BOOLEAN, \
"no", \
"Compute all senone scores in every frame (can be faster when there are many senones)" }, \
{ "-fwdtree", \
ARG_BOOLEAN, \
"yes", \
"Run forward lexicon-tree search (1st pass)" }, \
{ "-fwdflat", \
ARG_BOOLEAN, \
"yes", \
"Run forward flat-lexicon search over word lattice (2nd pass)" }, \
{ "-bestpath", \
ARG_BOOLEAN, \
"yes", \
"Run bestpath (Dijkstra) search over word lattice (3rd pass)" }, \
{ "-backtrace", \
ARG_BOOLEAN, \
"no", \
"Print results and backtraces to log file." }, \
{ "-latsize", \
ARG_INT32, \
"5000", \
"Initial backpointer table size" }, \
{ "-maxwpf", \
ARG_INT32, \
"-1", \
"Maximum number of distinct word exits at each frame (or -1 for no pruning)" }, \
{ "-maxhmmpf", \
ARG_INT32, \
"30000", \
"Maximum number of active HMMs to maintain at each frame (or -1 for no pruning)" }, \
{ "-min_endfr", \
ARG_INT32, \
"0", \
"Nodes ignored in lattice construction if they persist for fewer than N frames" }, \
{ "-fwdflatefwid", \
ARG_INT32, \
"4", \
"Minimum number of end frames for a word to be searched in fwdflat search" }, \
{ "-fwdflatsfwin", \
ARG_INT32, \
"25", \
"Window of frames in lattice to search for successor words in fwdflat search " }
/** Command-line options for keyword spotting */
#define POCKETSPHINX_KWS_OPTIONS \
{ "-keyphrase", \
ARG_STRING, \
NULL, \
"Keyphrase to spot"}, \
{ "-kws", \
ARG_STRING, \
NULL, \
"A file with keyphrases to spot, one per line"}, \
{ "-kws_plp", \
ARG_FLOAT64, \
"1e-1", \
"Phone loop probability for keyword spotting" }, \
{ "-kws_threshold", \
ARG_FLOAT64, \
"1", \
"Threshold for p(hyp)/p(alternatives) ratio" }
/** Command-line options for finite state grammars. */
#define POCKETSPHINX_FSG_OPTIONS \
{ "-fsg", \
ARG_STRING, \
NULL, \
"Sphinx format finite state grammar file"}, \
{ "-jsgf", \
ARG_STRING, \
NULL, \
"JSGF grammar file" }, \
{ "-toprule", \
ARG_STRING, \
NULL, \
"Start rule for JSGF (first public rule is default)" }, \
{ "-fsgusealtpron", \
ARG_BOOLEAN, \
"yes", \
"Add alternate pronunciations to FSG"}, \
{ "-fsgusefiller", \
ARG_BOOLEAN, \
"yes", \
"Insert filler words at each state."}
/** Command-line options for statistical language models. */
#define POCKETSPHINX_NGRAM_OPTIONS \
{ "-allphone", \
ARG_STRING, \
NULL, \
"Perform phoneme decoding with phonetic lm" }, \
{ "-allphone_ci", \
ARG_BOOLEAN, \
"no", \
"Perform phoneme decoding with phonetic lm and context-independent units only" }, \
{ "-lm", \
ARG_STRING, \
NULL, \
"Word trigram language model input file" }, \
{ "-lmctl", \
ARG_STRING, \
NULL, \
"Specify a set of language model\n"}, \
{ "-lmname", \
ARG_STRING, \
NULL, \
"Which language model in -lmctl to use by default"}, \
{ "-lw", \
ARG_FLOAT32, \
"6.5", \
"Language model probability weight" }, \
{ "-fwdflatlw", \
ARG_FLOAT32, \
"8.5", \
"Language model probability weight for flat lexicon (2nd pass) decoding" }, \
{ "-bestpathlw", \
ARG_FLOAT32, \
"9.5", \
"Language model probability weight for bestpath search" }, \
{ "-ascale", \
ARG_FLOAT32, \
"20.0", \
"Inverse of acoustic model scale for confidence score calculation" }, \
{ "-wip", \
ARG_FLOAT32, \
"0.65", \
"Word insertion penalty" }, \
{ "-nwpen", \
ARG_FLOAT32, \
"1.0", \
"New word transition penalty" }, \
{ "-pip", \
ARG_FLOAT32, \
"1.0", \
"Phone insertion penalty" }, \
{ "-uw", \
ARG_FLOAT32, \
"1.0", \
"Unigram weight" }, \
{ "-silprob", \
ARG_FLOAT32, \
"0.005", \
"Silence word transition probability" }, \
{ "-fillprob", \
ARG_FLOAT32, \
"1e-8", \
"Filler word transition probability" } \
/** Command-line options for dictionaries. */
#define POCKETSPHINX_DICT_OPTIONS \
{ "-dict", \
REQARG_STRING, \
NULL, \
"Main pronunciation dictionary (lexicon) input file" }, \
{ "-fdict", \
ARG_STRING, \
NULL, \
"Noise word pronunciation dictionary input file" }, \
{ "-dictcase", \
ARG_BOOLEAN, \
"no", \
"Dictionary is case sensitive (NOTE: case insensitivity applies to ASCII characters only)" } \
/** Command-line options for acoustic modeling */
#define POCKETSPHINX_ACMOD_OPTIONS \
{ "-hmm", \
ARG_STRING, \
NULL, \
"Directory containing acoustic model files."}, \
{ "-featparams", \
ARG_STRING, \
NULL, \
"File containing feature extraction parameters."}, \
{ "-mdef", \
ARG_STRING, \
NULL, \
"Model definition input file" }, \
{ "-senmgau", \
ARG_STRING, \
NULL, \
"Senone to codebook mapping input file (usually not needed)" }, \
{ "-tmat", \
ARG_STRING, \
NULL, \
"HMM state transition matrix input file" }, \
{ "-tmatfloor", \
ARG_FLOAT32, \
"0.0001", \
"HMM state transition probability floor (applied to -tmat file)" }, \
{ "-mean", \
ARG_STRING, \
NULL, \
"Mixture gaussian means input file" }, \
{ "-var", \
ARG_STRING, \
NULL, \
"Mixture gaussian variances input file" }, \
{ "-varfloor", \
ARG_FLOAT32, \
"0.0001", \
"Mixture gaussian variance floor (applied to data from -var file)" }, \
{ "-mixw", \
ARG_STRING, \
NULL, \
"Senone mixture weights input file (uncompressed)" }, \
{ "-mixwfloor", \
ARG_FLOAT32, \
"0.0000001", \
"Senone mixture weights floor (applied to data from -mixw file)" }, \
{ "-aw", \
ARG_INT32, \
"1", \
"Inverse weight applied to acoustic scores." }, \
{ "-sendump", \
ARG_STRING, \
NULL, \
"Senone dump (compressed mixture weights) input file" }, \
{ "-mllr", \
ARG_STRING, \
NULL, \
"MLLR transformation to apply to means and variances" }, \
{ "-mmap", \
ARG_BOOLEAN, \
"yes", \
"Use memory-mapped I/O (if possible) for model files" }, \
{ "-ds", \
ARG_INT32, \
"1", \
"Frame GMM computation downsampling ratio" }, \
{ "-topn", \
ARG_INT32, \
"4", \
"Maximum number of top Gaussians to use in scoring." }, \
{ "-topn_beam", \
ARG_STRING, \
"0", \
"Beam width used to determine top-N Gaussians (or a list, per-feature)" },\
{ "-logbase", \
ARG_FLOAT32, \
"1.0001", \
"Base in which all log-likelihoods calculated" }
#define CMDLN_EMPTY_OPTION { NULL, 0, NULL, NULL }
#endif /* __PS_CMDLN_MACRO_H__ */

View File

@ -1,61 +0,0 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
LOCAL_INCLUDES += [
'/media/sphinxbase',
]
EXPORTS.pocketsphinx += [
'pocketsphinx.h',
]
UNIFIED_SOURCES += [
'src/acmod.c',
'src/bin_mdef.c',
'src/blkarray_list.c',
'src/dict.c',
'src/dict2pid.c',
'src/fsg_history.c',
'src/fsg_lextree.c',
'src/fsg_search.c',
'src/hmm.c',
'src/kws_detections.c',
'src/kws_search.c',
'src/mdef.c',
'src/ms_gauden.c',
'src/ms_mgau.c',
'src/ms_senone.c',
'src/ngram_search_fwdflat.c',
'src/ngram_search_fwdtree.c',
'src/phone_loop_search.c',
'src/pocketsphinx.c',
'src/ps_alignment.c',
'src/ps_lattice.c',
'src/ps_mllr.c',
'src/ptm_mgau.c',
'src/tmat.c',
'src/vector.c',
]
SOURCES += [
'src/allphone_search.c',
'src/ngram_search.c',
'src/s2_semi_mgau.c',
'src/state_align_search.c',
]
# Suppress warnings in third-party code.
if CONFIG['GNU_CC']:
CFLAGS += [
'-Wno-sign-compare',
]
if CONFIG['CLANG_CXX']:
CFLAGS += ['-Wno-incompatible-pointer-types-discards-qualifiers']
# We allow warnings for third-party code that can be updated from upstream.
ALLOW_COMPILER_WARNINGS = True
FINAL_LIBRARY = 'gkmedias'

View File

@ -1,36 +0,0 @@
/* ====================================================================
* Copyright (c) 1999-2015 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* This work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
*/

Some files were not shown because too many files have changed in this diff Show More