Bug 1331696 - P1. Remove WebSpeech Pico service. r?eeejay, r?Build draft
authorJean-Yves Avenard <jyavenard@mozilla.com>
Sat, 02 Dec 2017 09:17:39 +0100
changeset 708356 4a155e4bb66fda75f0c85618ec8267d849cf4c73
parent 708198 79d3e25106f8eb369dde6a47199547d131af8d3d
child 708357 9a3ed521a2d8f0c7bb52a06ff99f5813af4d333c
push id92375
push userbmo:jyavenard@mozilla.com
push dateWed, 06 Dec 2017 19:11:20 +0000
reviewerseeejay, Build
bugs1331696
milestone59.0a1
Bug 1331696 - P1. Remove WebSpeech Pico service. r?eeejay, r?Build It's no longer used, and won't be able to work with the removal of speech synth direct audio support. MozReview-Commit-ID: BMdeRJHes0R
dom/media/webspeech/synth/moz.build
dom/media/webspeech/synth/pico/PicoModule.cpp
dom/media/webspeech/synth/pico/moz.build
dom/media/webspeech/synth/pico/nsPicoService.cpp
dom/media/webspeech/synth/pico/nsPicoService.h
old-configure.in
--- a/dom/media/webspeech/synth/moz.build
+++ b/dom/media/webspeech/synth/moz.build
@@ -46,19 +46,16 @@ if CONFIG['MOZ_WEBSPEECH']:
         DIRS += ['windows']
 
     if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
         DIRS += ['cocoa']
 
     if CONFIG['MOZ_SYNTH_SPEECHD']:
         DIRS += ['speechd']
 
-    if CONFIG['MOZ_SYNTH_PICO']:
-        DIRS += ['pico']
-
 IPDL_SOURCES += [
     'ipc/PSpeechSynthesis.ipdl',
     'ipc/PSpeechSynthesisRequest.ipdl',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
deleted file mode 100644
--- a/dom/media/webspeech/synth/pico/PicoModule.cpp
+++ /dev/null
@@ -1,58 +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"
-
-#ifdef MOZ_WEBRTC
-
-#include "nsPicoService.h"
-
-using namespace mozilla::dom;
-
-#define PICOSERVICE_CID \
-  {0x346c4fc8, 0x12fe, 0x459c, {0x81, 0x19, 0x9a, 0xa7, 0x73, 0x37, 0x7f, 0xf4}}
-
-#define PICOSERVICE_CONTRACTID "@mozilla.org/synthpico;1"
-
-// Defines nsPicoServiceConstructor
-NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsPicoService,
-                                         nsPicoService::GetInstanceForService)
-
-// Defines kPICOSERVICE_CID
-NS_DEFINE_NAMED_CID(PICOSERVICE_CID);
-
-static const mozilla::Module::CIDEntry kCIDs[] = {
-  { &kPICOSERVICE_CID, true, nullptr, nsPicoServiceConstructor },
-  { nullptr }
-};
-
-static const mozilla::Module::ContractIDEntry kContracts[] = {
-  { PICOSERVICE_CONTRACTID, &kPICOSERVICE_CID },
-  { nullptr }
-};
-
-static const mozilla::Module::CategoryEntry kCategories[] = {
-  { "profile-after-change", "Pico Speech Synth", PICOSERVICE_CONTRACTID },
-  { nullptr }
-};
-
-static void
-UnloadPicoModule()
-{
-  nsPicoService::Shutdown();
-}
-
-static const mozilla::Module kModule = {
-  mozilla::Module::kVersion,
-  kCIDs,
-  kContracts,
-  kCategories,
-  nullptr,
-  nullptr,
-  UnloadPicoModule
-};
-
-NSMODULE_DEFN(synthpico) = &kModule;
-#endif
deleted file mode 100644
--- a/dom/media/webspeech/synth/pico/moz.build
+++ /dev/null
@@ -1,13 +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/.
-
-UNIFIED_SOURCES += [
-    'nsPicoService.cpp',
-    'PicoModule.cpp'
-]
-include('/ipc/chromium/chromium-config.mozbuild')
-
-FINAL_LIBRARY = 'xul'
deleted file mode 100644
--- a/dom/media/webspeech/synth/pico/nsPicoService.cpp
+++ /dev/null
@@ -1,762 +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 "nsPicoService.h"
-#include "nsPrintfCString.h"
-#include "nsIWeakReferenceUtils.h"
-#include "SharedBuffer.h"
-#include "nsISimpleEnumerator.h"
-
-#include "mozilla/dom/nsSynthVoiceRegistry.h"
-#include "mozilla/dom/nsSpeechTask.h"
-
-#include "nsIFile.h"
-#include "nsThreadUtils.h"
-#include "prenv.h"
-#include "mozilla/Preferences.h"
-#include "mozilla/DebugOnly.h"
-#include <dlfcn.h>
-
-// Pico API constants
-
-// Size of memory allocated for pico engine and voice resources.
-// We only have one voice and its resources loaded at once, so this
-// should always be enough.
-#define PICO_MEM_SIZE 2500000
-
-// Max length of returned strings. Pico will never return longer strings,
-// so this amount should be good enough for preallocating.
-#define PICO_RETSTRINGSIZE 200
-
-// Max amount we want from a single call of pico_getData
-#define PICO_MAX_CHUNK_SIZE 128
-
-// Arbitrary name for loaded voice, it doesn't mean anything outside of Pico
-#define PICO_VOICE_NAME "pico"
-
-// Return status from pico_getData meaning there is more data in the pipeline
-// to get from more calls to pico_getData
-#define PICO_STEP_BUSY 201
-
-// For performing a "soft" reset between utterances. This is used when one
-// utterance is interrupted by a new one.
-#define PICO_RESET_SOFT 0x10
-
-// Currently, Pico only provides mono output.
-#define PICO_CHANNELS_NUM 1
-
-// Pico's sample rate is always 16000
-#define PICO_SAMPLE_RATE 16000
-
-// The path to the language files in Android
-#define PICO_LANG_PATH "/system/tts/lang_pico"
-
-namespace mozilla {
-namespace dom {
-
-StaticRefPtr<nsPicoService> nsPicoService::sSingleton;
-
-class PicoApi
-{
-public:
-
-  PicoApi() : mInitialized(false) {}
-
-  bool Init()
-  {
-    if (mInitialized) {
-      return true;
-    }
-
-    void* handle = dlopen("libttspico.so", RTLD_LAZY);
-
-    if (!handle) {
-      NS_WARNING("Failed to open libttspico.so, pico cannot run");
-      return false;
-    }
-
-    pico_initialize =
-      (pico_Status (*)(void*, uint32_t, pico_System*))dlsym(
-        handle, "pico_initialize");
-
-    pico_terminate =
-      (pico_Status (*)(pico_System*))dlsym(handle, "pico_terminate");
-
-    pico_getSystemStatusMessage =
-      (pico_Status (*)(pico_System, pico_Status, pico_Retstring))dlsym(
-        handle, "pico_getSystemStatusMessage");;
-
-    pico_loadResource =
-      (pico_Status (*)(pico_System, const char*, pico_Resource*))dlsym(
-        handle, "pico_loadResource");
-
-    pico_unloadResource =
-      (pico_Status (*)(pico_System, pico_Resource*))dlsym(
-        handle, "pico_unloadResource");
-
-    pico_getResourceName =
-      (pico_Status (*)(pico_System, pico_Resource, pico_Retstring))dlsym(
-        handle, "pico_getResourceName");
-
-    pico_createVoiceDefinition =
-      (pico_Status (*)(pico_System, const char*))dlsym(
-        handle, "pico_createVoiceDefinition");
-
-    pico_addResourceToVoiceDefinition =
-      (pico_Status (*)(pico_System, const char*, const char*))dlsym(
-        handle, "pico_addResourceToVoiceDefinition");
-
-    pico_releaseVoiceDefinition =
-      (pico_Status (*)(pico_System, const char*))dlsym(
-        handle, "pico_releaseVoiceDefinition");
-
-    pico_newEngine =
-      (pico_Status (*)(pico_System, const char*, pico_Engine*))dlsym(
-        handle, "pico_newEngine");
-
-    pico_disposeEngine =
-      (pico_Status (*)(pico_System, pico_Engine*))dlsym(
-        handle, "pico_disposeEngine");
-
-    pico_resetEngine =
-      (pico_Status (*)(pico_Engine, int32_t))dlsym(handle, "pico_resetEngine");
-
-    pico_putTextUtf8 =
-      (pico_Status (*)(pico_Engine, const char*, const int16_t, int16_t*))dlsym(
-        handle, "pico_putTextUtf8");
-
-    pico_getData =
-      (pico_Status (*)(pico_Engine, void*, int16_t, int16_t*, int16_t*))dlsym(
-        handle, "pico_getData");
-
-    mInitialized = true;
-    return true;
-  }
-
-  typedef signed int pico_Status;
-  typedef char pico_Retstring[PICO_RETSTRINGSIZE];
-
-  pico_Status (* pico_initialize)(void*, uint32_t, pico_System*);
-  pico_Status (* pico_terminate)(pico_System*);
-  pico_Status (* pico_getSystemStatusMessage)(
-    pico_System, pico_Status, pico_Retstring);
-
-  pico_Status (* pico_loadResource)(pico_System, const char*, pico_Resource*);
-  pico_Status (* pico_unloadResource)(pico_System, pico_Resource*);
-  pico_Status (* pico_getResourceName)(
-    pico_System, pico_Resource, pico_Retstring);
-  pico_Status (* pico_createVoiceDefinition)(pico_System, const char*);
-  pico_Status (* pico_addResourceToVoiceDefinition)(
-    pico_System, const char*, const char*);
-  pico_Status (* pico_releaseVoiceDefinition)(pico_System, const char*);
-  pico_Status (* pico_newEngine)(pico_System, const char*, pico_Engine*);
-  pico_Status (* pico_disposeEngine)(pico_System, pico_Engine*);
-
-  pico_Status (* pico_resetEngine)(pico_Engine, int32_t);
-  pico_Status (* pico_putTextUtf8)(
-    pico_Engine, const char*, const int16_t, int16_t*);
-  pico_Status (* pico_getData)(
-    pico_Engine, void*, const int16_t, int16_t*, int16_t*);
-
-private:
-
-  bool mInitialized;
-
-} sPicoApi;
-
-#define PICO_ENSURE_SUCCESS_VOID(_funcName, _status)                      \
-  if (_status < 0) {                                                      \
-    PicoApi::pico_Retstring message;                                      \
-    sPicoApi.pico_getSystemStatusMessage(                                 \
-      nsPicoService::sSingleton->mPicoSystem, _status, message);          \
-    NS_WARNING(                                                           \
-      nsPrintfCString("Error running %s: %s", _funcName, message).get()); \
-    return;                                                               \
-  }
-
-#define PICO_ENSURE_SUCCESS(_funcName, _status, _rv)                      \
-  if (_status < 0) {                                                      \
-    PicoApi::pico_Retstring message;                                      \
-    sPicoApi.pico_getSystemStatusMessage(                                 \
-      nsPicoService::sSingleton->mPicoSystem, _status, message);          \
-    NS_WARNING(                                                           \
-      nsPrintfCString("Error running %s: %s", _funcName, message).get()); \
-    return _rv;                                                           \
-  }
-
-class PicoVoice
-{
-public:
-
-  PicoVoice(const nsAString& aLanguage)
-    : mLanguage(aLanguage) {}
-
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PicoVoice)
-
-  // Voice language, in BCB-47 syntax
-  nsString mLanguage;
-
-  // Language resource file
-  nsCString mTaFile;
-
-  // Speaker resource file
-  nsCString mSgFile;
-
-private:
-    ~PicoVoice() {}
-};
-
-class PicoCallbackRunnable : public Runnable,
-                             public nsISpeechTaskCallback
-{
-  friend class PicoSynthDataRunnable;
-
-public:
-  PicoCallbackRunnable(const nsAString& aText, PicoVoice* aVoice,
-                       float aRate, float aPitch, nsISpeechTask* aTask,
-                       nsPicoService* aService)
-    : mText(NS_ConvertUTF16toUTF8(aText))
-    , mRate(aRate)
-    , mPitch(aPitch)
-    , mFirstData(true)
-    , mTask(aTask)
-    , mVoice(aVoice)
-    , mService(aService) { }
-
-  NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_NSISPEECHTASKCALLBACK
-
-  NS_IMETHOD Run() override;
-
-  bool IsCurrentTask() { return mService->mCurrentTask == mTask; }
-
-private:
-  ~PicoCallbackRunnable() { }
-
-  void DispatchSynthDataRunnable(already_AddRefed<SharedBuffer>&& aBuffer,
-                                 size_t aBufferSize);
-
-  nsCString mText;
-
-  float mRate;
-
-  float mPitch;
-
-  bool mFirstData;
-
-  // We use this pointer to compare it with the current service task.
-  // If they differ, this runnable should stop.
-  nsISpeechTask* mTask;
-
-  // We hold a strong reference to the service, which in turn holds
-  // a strong reference to this voice.
-  PicoVoice* mVoice;
-
-  // By holding a strong reference to the service we guarantee that it won't be
-  // destroyed before this runnable.
-  RefPtr<nsPicoService> mService;
-};
-
-NS_IMPL_ISUPPORTS_INHERITED(PicoCallbackRunnable, Runnable, nsISpeechTaskCallback)
-
-// Runnable
-
-NS_IMETHODIMP
-PicoCallbackRunnable::Run()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-  PicoApi::pico_Status status = 0;
-
-  if (mService->CurrentVoice() != mVoice) {
-    mService->LoadEngine(mVoice);
-  } else {
-    status = sPicoApi.pico_resetEngine(mService->mPicoEngine, PICO_RESET_SOFT);
-    PICO_ENSURE_SUCCESS("pico_unloadResource", status, NS_ERROR_FAILURE);
-  }
-
-  // Add SSML markup for pitch and rate. Pico uses a minimal parser,
-  // so no namespace is needed.
-  nsPrintfCString markedUpText(
-    "<pitch level=\"%0.0f\"><speed level=\"%0.0f\">%s</speed></pitch>",
-    std::min(std::max(50.0f, mPitch * 100), 200.0f),
-    std::min(std::max(20.0f, mRate * 100), 500.0f),
-    mText.get());
-
-  const char* text = markedUpText.get();
-  size_t buffer_size = 512, buffer_offset = 0;
-  RefPtr<SharedBuffer> buffer = SharedBuffer::Create(buffer_size);
-  int16_t text_offset = 0, bytes_recv = 0, bytes_sent = 0, out_data_type = 0;
-  int16_t text_remaining = markedUpText.Length() + 1;
-
-  // Run this loop while this is the current task
-  while (IsCurrentTask()) {
-    if (text_remaining) {
-      status = sPicoApi.pico_putTextUtf8(mService->mPicoEngine,
-                                         text + text_offset, text_remaining,
-                                         &bytes_sent);
-      PICO_ENSURE_SUCCESS("pico_putTextUtf8", status, NS_ERROR_FAILURE);
-      // XXX: End speech task on error
-      text_remaining -= bytes_sent;
-      text_offset += bytes_sent;
-    } else {
-      // If we already fed all the text to the engine, send a zero length buffer
-      // and quit.
-      DispatchSynthDataRunnable(already_AddRefed<SharedBuffer>(), 0);
-      break;
-    }
-
-    do {
-      // Run this loop while the result of getData is STEP_BUSY, when it finishes
-      // synthesizing audio for the given text, it returns STEP_IDLE. We then
-      // break to the outer loop and feed more text, if there is any left.
-      if (!IsCurrentTask()) {
-        // If the task has changed, quit.
-        break;
-      }
-
-      if (buffer_size - buffer_offset < PICO_MAX_CHUNK_SIZE) {
-        // The next audio chunk retrieved may be bigger than our buffer,
-        // so send the data and flush the buffer.
-        DispatchSynthDataRunnable(buffer.forget(), buffer_offset);
-        buffer_offset = 0;
-        buffer = SharedBuffer::Create(buffer_size);
-      }
-
-      status = sPicoApi.pico_getData(mService->mPicoEngine,
-                                     (uint8_t*)buffer->Data() + buffer_offset,
-                                     PICO_MAX_CHUNK_SIZE,
-                                     &bytes_recv, &out_data_type);
-      PICO_ENSURE_SUCCESS("pico_getData", status, NS_ERROR_FAILURE);
-      buffer_offset += bytes_recv;
-    } while (status == PICO_STEP_BUSY);
-  }
-
-  return NS_OK;
-}
-
-void
-PicoCallbackRunnable::DispatchSynthDataRunnable(
-  already_AddRefed<SharedBuffer>&& aBuffer, size_t aBufferSize)
-{
-  class PicoSynthDataRunnable final : public Runnable
-  {
-  public:
-    PicoSynthDataRunnable(already_AddRefed<SharedBuffer>& aBuffer,
-                          size_t aBufferSize, bool aFirstData,
-                          PicoCallbackRunnable* aCallback)
-      : mBuffer(aBuffer)
-      , mBufferSize(aBufferSize)
-      , mFirstData(aFirstData)
-      , mCallback(aCallback) {
-    }
-
-    NS_IMETHOD Run() override
-    {
-      MOZ_ASSERT(NS_IsMainThread());
-
-      if (!mCallback->IsCurrentTask()) {
-        return NS_ERROR_NOT_AVAILABLE;
-      }
-
-      nsISpeechTask* task = mCallback->mTask;
-
-      if (mFirstData) {
-        task->Setup(mCallback, PICO_CHANNELS_NUM, PICO_SAMPLE_RATE, 2);
-      }
-
-      return task->SendAudioNative(
-        mBufferSize ? static_cast<short*>(mBuffer->Data()) : nullptr, mBufferSize / 2);
-    }
-
-  private:
-    RefPtr<SharedBuffer> mBuffer;
-
-    size_t mBufferSize;
-
-    bool mFirstData;
-
-    RefPtr<PicoCallbackRunnable> mCallback;
-  };
-
-  nsCOMPtr<nsIRunnable> sendEvent =
-    new PicoSynthDataRunnable(aBuffer, aBufferSize, mFirstData, this);
-  NS_DispatchToMainThread(sendEvent);
-  mFirstData = false;
-}
-
-// nsISpeechTaskCallback
-
-NS_IMETHODIMP
-PicoCallbackRunnable::OnPause()
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-PicoCallbackRunnable::OnResume()
-{
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-PicoCallbackRunnable::OnCancel()
-{
-  mService->mCurrentTask = nullptr;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-PicoCallbackRunnable::OnVolumeChanged(float aVolume)
-{
-  return NS_OK;
-}
-
-NS_INTERFACE_MAP_BEGIN(nsPicoService)
-  NS_INTERFACE_MAP_ENTRY(nsISpeechService)
-  NS_INTERFACE_MAP_ENTRY(nsIObserver)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver)
-NS_INTERFACE_MAP_END
-
-NS_IMPL_ADDREF(nsPicoService)
-NS_IMPL_RELEASE(nsPicoService)
-
-nsPicoService::nsPicoService()
-  : mInitialized(false)
-  , mVoicesMonitor("nsPicoService::mVoices")
-  , mCurrentTask(nullptr)
-  , mPicoSystem(nullptr)
-  , mPicoEngine(nullptr)
-  , mSgResource(nullptr)
-  , mTaResource(nullptr)
-  , mPicoMemArea(nullptr)
-{
-}
-
-nsPicoService::~nsPicoService()
-{
-  // We don't worry about removing the voices because this gets
-  // destructed at shutdown along with the voice registry.
-  MonitorAutoLock autoLock(mVoicesMonitor);
-  mVoices.Clear();
-
-  if (mThread) {
-    mThread->Shutdown();
-  }
-
-  UnloadEngine();
-}
-
-// nsIObserver
-
-NS_IMETHODIMP
-nsPicoService::Observe(nsISupports* aSubject, const char* aTopic,
-                       const char16_t* aData)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  if(NS_WARN_IF(!(!strcmp(aTopic, "profile-after-change")))) {
-    return NS_ERROR_UNEXPECTED;
-  }
-
-  if (!Preferences::GetBool("media.webspeech.synth.enabled") ||
-      Preferences::GetBool("media.webspeech.synth.test")) {
-    return NS_OK;
-  }
-
-  DebugOnly<nsresult> rv = NS_NewNamedThread("Pico Worker", getter_AddRefs(mThread));
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
-  return mThread->Dispatch(
-    NewRunnableMethod("nsPicoService::Init", this, &nsPicoService::Init), NS_DISPATCH_NORMAL);
-}
-// nsISpeechService
-
-NS_IMETHODIMP
-nsPicoService::Speak(const nsAString& aText, const nsAString& aUri,
-                     float aVolume, float aRate, float aPitch,
-                     nsISpeechTask* aTask)
-{
-  if(NS_WARN_IF(!(mInitialized))) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  MonitorAutoLock autoLock(mVoicesMonitor);
-  bool found = false;
-  PicoVoice* voice = mVoices.GetWeak(aUri, &found);
-  if(NS_WARN_IF(!(found))) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-
-  mCurrentTask = aTask;
-  RefPtr<PicoCallbackRunnable> cb = new PicoCallbackRunnable(aText, voice, aRate, aPitch, aTask, this);
-  return mThread->Dispatch(cb, NS_DISPATCH_NORMAL);
-}
-
-NS_IMETHODIMP
-nsPicoService::GetServiceType(SpeechServiceType* aServiceType)
-{
-  *aServiceType = nsISpeechService::SERVICETYPE_DIRECT_AUDIO;
-  return NS_OK;
-}
-
-// private methods
-
-void
-nsPicoService::Init()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-  MOZ_ASSERT(!mInitialized);
-
-  if (!sPicoApi.Init()) {
-    NS_WARNING("Failed to initialize pico library");
-    return;
-  }
-
-  // Use environment variable, or default android path
-  nsAutoCString langPath(PR_GetEnv("PICO_LANG_PATH"));
-
-  if (langPath.IsEmpty()) {
-    langPath.AssignLiteral(PICO_LANG_PATH);
-  }
-
-  nsCOMPtr<nsIFile> voicesDir;
-  NS_NewNativeLocalFile(langPath, true, getter_AddRefs(voicesDir));
-
-  nsCOMPtr<nsISimpleEnumerator> dirIterator;
-  nsresult rv = voicesDir->GetDirectoryEntries(getter_AddRefs(dirIterator));
-
-  if (NS_FAILED(rv)) {
-    NS_WARNING(nsPrintfCString("Failed to get contents of directory: %s", langPath.get()).get());
-    return;
-  }
-
-  bool hasMoreElements = false;
-  rv = dirIterator->HasMoreElements(&hasMoreElements);
-  MOZ_ASSERT(NS_SUCCEEDED(rv));
-
-  MonitorAutoLock autoLock(mVoicesMonitor);
-
-  while (hasMoreElements && NS_SUCCEEDED(rv)) {
-    nsCOMPtr<nsISupports> supports;
-    rv = dirIterator->GetNext(getter_AddRefs(supports));
-    MOZ_ASSERT(NS_SUCCEEDED(rv));
-
-    nsCOMPtr<nsIFile> voiceFile = do_QueryInterface(supports);
-    MOZ_ASSERT(voiceFile);
-
-    nsAutoCString leafName;
-    voiceFile->GetNativeLeafName(leafName);
-
-    nsAutoString lang;
-
-    if (GetVoiceFileLanguage(leafName, lang)) {
-      nsAutoString uri;
-      uri.AssignLiteral("urn:moz-tts:pico:");
-      uri.Append(lang);
-
-      bool found = false;
-      PicoVoice* voice = mVoices.GetWeak(uri, &found);
-
-      if (!found) {
-        voice = new PicoVoice(lang);
-        mVoices.Put(uri, voice);
-      }
-
-      // Each voice consists of two lingware files: A language resource file,
-      // suffixed by _ta.bin, and a speaker resource file, suffixed by _sb.bin.
-      // We currently assume that there is a pair of files for each language.
-      if (StringEndsWith(leafName, NS_LITERAL_CSTRING("_ta.bin"))) {
-        rv = voiceFile->GetPersistentDescriptor(voice->mTaFile);
-        MOZ_ASSERT(NS_SUCCEEDED(rv));
-      } else if (StringEndsWith(leafName, NS_LITERAL_CSTRING("_sg.bin"))) {
-        rv = voiceFile->GetPersistentDescriptor(voice->mSgFile);
-        MOZ_ASSERT(NS_SUCCEEDED(rv));
-      }
-    }
-
-    rv = dirIterator->HasMoreElements(&hasMoreElements);
-  }
-
-  NS_DispatchToMainThread(NewRunnableMethod("nsPicoService::RegisterVoices",
-                                            this, &nsPicoService::RegisterVoices));
-}
-
-void
-nsPicoService::RegisterVoices()
-{
-  nsSynthVoiceRegistry* registry = nsSynthVoiceRegistry::GetInstance();
-
-  for (auto iter = mVoices.Iter(); !iter.Done(); iter.Next()) {
-    const nsAString& uri = iter.Key();
-    RefPtr<PicoVoice>& voice = iter.Data();
-
-    // If we are missing either a language or a voice resource, it is invalid.
-    if (voice->mTaFile.IsEmpty() || voice->mSgFile.IsEmpty()) {
-      iter.Remove();
-      continue;
-    }
-
-    nsAutoString name;
-    name.AssignLiteral("Pico ");
-    name.Append(voice->mLanguage);
-
-    // This service is multi-threaded and can handle more than one utterance at a
-    // time before previous utterances end. So, aQueuesUtterances == false
-    DebugOnly<nsresult> rv =
-      registry->AddVoice(this, uri, name, voice->mLanguage, true, false);
-    NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to add voice");
-  }
-
-  mInitialized = true;
-}
-
-bool
-nsPicoService::GetVoiceFileLanguage(const nsACString& aFileName, nsAString& aLang)
-{
-  nsACString::const_iterator start, end;
-  aFileName.BeginReading(start);
-  aFileName.EndReading(end);
-
-  // The lingware filename syntax is language_(ta/sg).bin,
-  // we extract the language prefix here.
-  if (FindInReadable(NS_LITERAL_CSTRING("_"), start, end)) {
-    end = start;
-    aFileName.BeginReading(start);
-    aLang.Assign(NS_ConvertUTF8toUTF16(Substring(start, end)));
-    return true;
-  }
-
-  return false;
-}
-
-void
-nsPicoService::LoadEngine(PicoVoice* aVoice)
-{
-  PicoApi::pico_Status status = 0;
-
-  if (mPicoSystem) {
-    UnloadEngine();
-  }
-
-  if (!mPicoMemArea) {
-    mPicoMemArea = MakeUnique<uint8_t[]>(PICO_MEM_SIZE);
-  }
-
-  status = sPicoApi.pico_initialize(mPicoMemArea.get(),
-                                    PICO_MEM_SIZE, &mPicoSystem);
-  PICO_ENSURE_SUCCESS_VOID("pico_initialize", status);
-
-  status = sPicoApi.pico_loadResource(mPicoSystem, aVoice->mTaFile.get(), &mTaResource);
-  PICO_ENSURE_SUCCESS_VOID("pico_loadResource", status);
-
-  status = sPicoApi.pico_loadResource(mPicoSystem, aVoice->mSgFile.get(), &mSgResource);
-  PICO_ENSURE_SUCCESS_VOID("pico_loadResource", status);
-
-  status = sPicoApi.pico_createVoiceDefinition(mPicoSystem, PICO_VOICE_NAME);
-  PICO_ENSURE_SUCCESS_VOID("pico_createVoiceDefinition", status);
-
-  char taName[PICO_RETSTRINGSIZE];
-  status = sPicoApi.pico_getResourceName(mPicoSystem, mTaResource, taName);
-  PICO_ENSURE_SUCCESS_VOID("pico_getResourceName", status);
-
-  status = sPicoApi.pico_addResourceToVoiceDefinition(
-    mPicoSystem, PICO_VOICE_NAME, taName);
-  PICO_ENSURE_SUCCESS_VOID("pico_addResourceToVoiceDefinition", status);
-
-  char sgName[PICO_RETSTRINGSIZE];
-  status = sPicoApi.pico_getResourceName(mPicoSystem, mSgResource, sgName);
-  PICO_ENSURE_SUCCESS_VOID("pico_getResourceName", status);
-
-  status = sPicoApi.pico_addResourceToVoiceDefinition(
-    mPicoSystem, PICO_VOICE_NAME, sgName);
-  PICO_ENSURE_SUCCESS_VOID("pico_addResourceToVoiceDefinition", status);
-
-  status = sPicoApi.pico_newEngine(mPicoSystem, PICO_VOICE_NAME, &mPicoEngine);
-  PICO_ENSURE_SUCCESS_VOID("pico_newEngine", status);
-
-  if (sSingleton) {
-    sSingleton->mCurrentVoice = aVoice;
-  }
-}
-
-void
-nsPicoService::UnloadEngine()
-{
-  PicoApi::pico_Status status = 0;
-
-  if (mPicoEngine) {
-    status = sPicoApi.pico_disposeEngine(mPicoSystem, &mPicoEngine);
-    PICO_ENSURE_SUCCESS_VOID("pico_disposeEngine", status);
-    status = sPicoApi.pico_releaseVoiceDefinition(mPicoSystem, PICO_VOICE_NAME);
-    PICO_ENSURE_SUCCESS_VOID("pico_releaseVoiceDefinition", status);
-    mPicoEngine = nullptr;
-  }
-
-  if (mSgResource) {
-    status = sPicoApi.pico_unloadResource(mPicoSystem, &mSgResource);
-    PICO_ENSURE_SUCCESS_VOID("pico_unloadResource", status);
-    mSgResource = nullptr;
-  }
-
-  if (mTaResource) {
-    status = sPicoApi.pico_unloadResource(mPicoSystem, &mTaResource);
-    PICO_ENSURE_SUCCESS_VOID("pico_unloadResource", status);
-    mTaResource = nullptr;
-  }
-
-  if (mPicoSystem) {
-    status = sPicoApi.pico_terminate(&mPicoSystem);
-    PICO_ENSURE_SUCCESS_VOID("pico_terminate", status);
-    mPicoSystem = nullptr;
-  }
-}
-
-PicoVoice*
-nsPicoService::CurrentVoice()
-{
-  MOZ_ASSERT(!NS_IsMainThread());
-
-  return mCurrentVoice;
-}
-
-// static methods
-
-nsPicoService*
-nsPicoService::GetInstance()
-{
-  MOZ_ASSERT(NS_IsMainThread());
-  if (!XRE_IsParentProcess()) {
-    MOZ_ASSERT(false, "nsPicoService can only be started on main gecko process");
-    return nullptr;
-  }
-
-  if (!sSingleton) {
-    sSingleton = new nsPicoService();
-  }
-
-  return sSingleton;
-}
-
-already_AddRefed<nsPicoService>
-nsPicoService::GetInstanceForService()
-{
-  RefPtr<nsPicoService> picoService = GetInstance();
-  return picoService.forget();
-}
-
-void
-nsPicoService::Shutdown()
-{
-  if (!sSingleton) {
-    return;
-  }
-
-  sSingleton->mCurrentTask = nullptr;
-
-  sSingleton = nullptr;
-}
-
-} // namespace dom
-} // namespace mozilla
deleted file mode 100644
--- a/dom/media/webspeech/synth/pico/nsPicoService.h
+++ /dev/null
@@ -1,93 +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 nsPicoService_h
-#define nsPicoService_h
-
-#include "mozilla/Mutex.h"
-#include "nsTArray.h"
-#include "nsIObserver.h"
-#include "nsIThread.h"
-#include "nsISpeechService.h"
-#include "nsRefPtrHashtable.h"
-#include "mozilla/StaticPtr.h"
-#include "mozilla/Monitor.h"
-#include "mozilla/UniquePtr.h"
-
-namespace mozilla {
-namespace dom {
-
-class PicoVoice;
-class PicoCallbackRunnable;
-
-typedef void* pico_System;
-typedef void* pico_Resource;
-typedef void* pico_Engine;
-
-class nsPicoService : public nsIObserver,
-                      public nsISpeechService
-{
-  friend class PicoCallbackRunnable;
-  friend class PicoInitRunnable;
-
-public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSISPEECHSERVICE
-  NS_DECL_NSIOBSERVER
-
-  nsPicoService();
-
-  static nsPicoService* GetInstance();
-
-  static already_AddRefed<nsPicoService> GetInstanceForService();
-
-  static void Shutdown();
-
-private:
-
-  virtual ~nsPicoService();
-
-  void Init();
-
-  void RegisterVoices();
-
-  bool GetVoiceFileLanguage(const nsACString& aFileName, nsAString& aLang);
-
-  void LoadEngine(PicoVoice* aVoice);
-
-  void UnloadEngine();
-
-  PicoVoice* CurrentVoice();
-
-  bool mInitialized;
-
-  nsCOMPtr<nsIThread> mThread;
-
-  nsRefPtrHashtable<nsStringHashKey, PicoVoice> mVoices;
-
-  Monitor mVoicesMonitor;
-
-  PicoVoice* mCurrentVoice;
-
-  Atomic<nsISpeechTask*> mCurrentTask;
-
-  pico_System mPicoSystem;
-
-  pico_Engine mPicoEngine;
-
-  pico_Resource mSgResource;
-
-  pico_Resource mTaResource;
-
-  mozilla::UniquePtr<uint8_t[]> mPicoMemArea;
-
-  static StaticRefPtr<nsPicoService> sSingleton;
-};
-
-} // namespace dom
-} // namespace mozilla
-
-#endif
--- a/old-configure.in
+++ b/old-configure.in
@@ -2567,18 +2567,16 @@ if test -n "$MOZ_WEBRTC"; then
     MOZ_RAW=1
     MOZ_SCTP=1
     MOZ_SRTP=1
     AC_DEFINE(MOZ_SCTP)
     AC_DEFINE(MOZ_SRTP)
     if test -n "$MOZ_X11"; then
       MOZ_WEBRTC_X11_LIBS="-lXext -lXdamage -lXfixes -lXcomposite"
     fi
-else
-    MOZ_SYNTH_PICO=
 fi
 
 dnl ========================================================
 dnl = Force hardware AEC, disable webrtc.org AEC
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(hardware-aec-ns,
 [  --enable-hardware-aec-ns   Enable support for hardware AEC and noise suppression],
     MOZ_WEBRTC_HARDWARE_AEC_NS=1,
@@ -3961,28 +3959,16 @@ MOZ_ARG_DISABLE_BOOL(startupcache,
     MOZ_DISABLE_STARTUPCACHE=)
 
 if test -n "$MOZ_DISABLE_STARTUPCACHE"; then
   AC_DEFINE(MOZ_DISABLE_STARTUPCACHE)
 fi
 AC_SUBST(MOZ_DISABLE_STARTUPCACHE)
 
 dnl ========================================================
-dnl = Enable Pico Speech Synthesis
-dnl ========================================================
-MOZ_ARG_ENABLE_BOOL(synth-pico,
-[  --enable-synth-pico  Set compile flags necessary for compiling Pico Web Speech API ],
-    MOZ_SYNTH_PICO=1,
-    MOZ_SYNTH_PICO= )
-if test -n "$MOZ_SYNTH_PICO"; then
-    AC_DEFINE(MOZ_SYNTH_PICO)
-fi
-AC_SUBST(MOZ_SYNTH_PICO)
-
-dnl ========================================================
 dnl = Enable Support for Time Manager API
 dnl ========================================================
 if test -n "$MOZ_TIME_MANAGER"; then
     AC_DEFINE(MOZ_TIME_MANAGER)
 fi
 AC_SUBST(MOZ_TIME_MANAGER)
 
 dnl ========================================================