Bug 805254. Part 13: Make nsAudioStream::Write take an AudioDataValue* parameter instead of void. r=kinetik
authorRobert O'Callahan <robert@ocallahan.org>
Thu, 25 Oct 2012 23:10:51 +1300
changeset 111629 2b496b04c1831346a898d288f0c03ab23b5c076f
parent 111628 1eb3bd54b7bd6ed60456e790540917cad9fa7b4b
child 111630 8586bd3508750056e1b59298a59cad02bf54b29c
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewerskinetik
bugs805254
milestone19.0a1
Bug 805254. Part 13: Make nsAudioStream::Write take an AudioDataValue* parameter instead of void. r=kinetik
content/html/content/src/nsHTMLAudioElement.cpp
content/media/nsAudioStream.cpp
content/media/nsAudioStream.h
dom/ipc/AudioParent.cpp
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -176,26 +176,23 @@ nsHTMLAudioElement::MozWriteAudio(const 
   if (dataLength % mChannels != 0) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   // Don't write more than can be written without blocking.
   uint32_t writeLen = NS_MIN(mAudioStream->Available(), dataLength / mChannels);
 
   float* frames = JS_GetFloat32ArrayData(tsrc, aCx);
-  nsresult rv;
-  if (AUDIO_OUTPUT_FORMAT == AUDIO_FORMAT_S16) {
-    // Convert the samples back to integers as we are using fixed point audio in
-    // the nsAudioStream.
-    nsAutoArrayPtr<AudioDataValue> shortsArray(new AudioDataValue[writeLen * mChannels]);
-    ConvertAudioSamples(frames, shortsArray.get(), writeLen * mChannels);
-    rv = mAudioStream->Write(shortsArray.get(), writeLen);
-  } else {
-    rv = mAudioStream->Write(frames, writeLen);
-  }
+  // Convert the samples back to integers as we are using fixed point audio in
+  // the nsAudioStream.
+  // This could be optimized to avoid allocation and memcpy when
+  // AudioDataValue is 'float', but it's not worth it for this deprecated API.
+  nsAutoArrayPtr<AudioDataValue> audioData(new AudioDataValue[writeLen * mChannels]);
+  ConvertAudioSamples(frames, audioData.get(), writeLen * mChannels);
+  nsresult rv = mAudioStream->Write(audioData.get(), writeLen);
 
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   // Return the actual amount written.
   *aRetVal = writeLen * mChannels;
   return rv;
--- a/content/media/nsAudioStream.cpp
+++ b/content/media/nsAudioStream.cpp
@@ -57,17 +57,17 @@ class nsNativeAudioStream : public nsAud
  public:
   NS_DECL_ISUPPORTS
 
   ~nsNativeAudioStream();
   nsNativeAudioStream();
 
   nsresult Init(int32_t aNumChannels, int32_t aRate);
   void Shutdown();
-  nsresult Write(const void* aBuf, uint32_t aFrames);
+  nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames);
   uint32_t Available();
   void SetVolume(double aVolume);
   void Drain();
   void Pause();
   void Resume();
   int64_t GetPosition();
   int64_t GetPositionInFrames();
   bool IsPaused();
@@ -92,17 +92,17 @@ class nsRemotedAudioStream : public nsAu
  public:
   NS_DECL_ISUPPORTS
 
   nsRemotedAudioStream();
   ~nsRemotedAudioStream();
 
   nsresult Init(int32_t aNumChannels, int32_t aRate);
   void Shutdown();
-  nsresult Write(const void* aBuf, uint32_t aFrames);
+  nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames);
   uint32_t Available();
   void SetVolume(double aVolume);
   void Drain();
   void Pause();
   void Resume();
   int64_t GetPosition();
   int64_t GetPositionInFrames();
   bool IsPaused();
@@ -138,23 +138,24 @@ class AudioInitEvent : public nsRunnable
 
   nsRefPtr<nsRemotedAudioStream> mOwner;
 };
 
 class AudioWriteEvent : public nsRunnable
 {
  public:
   AudioWriteEvent(AudioChild* aChild,
-                  const void* aBuf,
+                  const AudioDataValue* aBuf,
                   uint32_t aNumberOfFrames,
                   uint32_t aBytesPerFrame)
   {
     mAudioChild = aChild;
     mBytesPerFrame = aBytesPerFrame;
-    mBuffer.Assign((const char*)aBuf, aNumberOfFrames * aBytesPerFrame);
+    mBuffer.Assign(reinterpret_cast<const char*>(aBuf),
+                   aNumberOfFrames * aBytesPerFrame);
   }
 
   NS_IMETHOD Run()
   {
     if (!mAudioChild->IsIPCOpen())
       return NS_OK;
 
     mAudioChild->SendWrite(mBuffer, mBuffer.Length() / mBytesPerFrame);
@@ -459,29 +460,28 @@ void nsNativeAudioStream::Shutdown()
   if (!mAudioHandle)
     return;
 
   sa_stream_destroy(static_cast<sa_stream_t*>(mAudioHandle));
   mAudioHandle = nullptr;
   mInError = true;
 }
 
-nsresult nsNativeAudioStream::Write(const void* aBuf, uint32_t aFrames)
+nsresult nsNativeAudioStream::Write(const AudioDataValue* aBuf, uint32_t aFrames)
 {
   NS_ASSERTION(!mPaused, "Don't write audio when paused, you'll block");
 
   if (mInError)
     return NS_ERROR_FAILURE;
 
   uint32_t samples = aFrames * mChannels;
   nsAutoArrayPtr<short> s_data(new short[samples]);
 
   float scaled_volume = float(GetVolumeScale() * mVolume);
-  const AudioDataValue* buf = static_cast<const AudioDataValue*>(aBuf);
-  ConvertAudioSamplesWithScale(buf, s_data.get(), samples, scaled_volume);
+  ConvertAudioSamplesWithScale(aBuf, s_data.get(), samples, scaled_volume);
 
   if (sa_stream_write(static_cast<sa_stream_t*>(mAudioHandle),
                       s_data.get(),
                       samples * sizeof(short)) != SA_SUCCESS)
   {
     PR_LOG(gAudioStreamLog, PR_LOG_ERROR, ("nsNativeAudioStream: sa_stream_write error"));
     mInError = true;
     return NS_ERROR_FAILURE;
@@ -625,17 +625,17 @@ nsRemotedAudioStream::Shutdown()
   if (!mAudioChild)
     return;
   nsCOMPtr<nsIRunnable> event = new AudioShutdownEvent(mAudioChild);
   NS_DispatchToMainThread(event);
   mAudioChild = nullptr;
 }
 
 nsresult
-nsRemotedAudioStream::Write(const void* aBuf, uint32_t aFrames)
+nsRemotedAudioStream::Write(const AudioDataValue* aBuf, uint32_t aFrames)
 {
   if (!mAudioChild)
     return NS_ERROR_FAILURE;
   nsCOMPtr<nsIRunnable> event = new AudioWriteEvent(mAudioChild,
                                                     aBuf,
                                                     aFrames,
                                                     mBytesPerFrame);
   NS_DispatchToMainThread(event);
@@ -807,17 +807,17 @@ class nsBufferedAudioStream : public nsA
  public:
   NS_DECL_ISUPPORTS
 
   nsBufferedAudioStream();
   ~nsBufferedAudioStream();
 
   nsresult Init(int32_t aNumChannels, int32_t aRate);
   void Shutdown();
-  nsresult Write(const void* aBuf, uint32_t aFrames);
+  nsresult Write(const AudioDataValue* aBuf, uint32_t aFrames);
   uint32_t Available();
   void SetVolume(double aVolume);
   void Drain();
   void Pause();
   void Resume();
   int64_t GetPosition();
   int64_t GetPositionInFrames();
   bool IsPaused();
@@ -962,25 +962,25 @@ nsBufferedAudioStream::Shutdown()
     Pause();
   }
   if (mCubebStream) {
     mCubebStream.reset();
   }
 }
 
 nsresult
-nsBufferedAudioStream::Write(const void* aBuf, uint32_t aFrames)
+nsBufferedAudioStream::Write(const AudioDataValue* aBuf, uint32_t aFrames)
 {
   MonitorAutoLock mon(mMonitor);
   if (!mCubebStream || mState == ERRORED) {
     return NS_ERROR_FAILURE;
   }
   NS_ASSERTION(mState == INITIALIZED || mState == STARTED, "Stream write in unexpected state.");
 
-  const uint8_t* src = static_cast<const uint8_t*>(aBuf);
+  const uint8_t* src = reinterpret_cast<const uint8_t*>(aBuf);
   uint32_t bytesToCopy = aFrames * mBytesPerFrame;
 
   while (bytesToCopy > 0) {
     uint32_t available = NS_MIN(bytesToCopy, mBuffer.Available());
     NS_ABORT_IF_FALSE(available % mBytesPerFrame == 0, "Must copy complete frames.");
 
     mBuffer.AppendElements(src, available);
     src += available;
--- a/content/media/nsAudioStream.h
+++ b/content/media/nsAudioStream.h
@@ -50,21 +50,21 @@ public:
   // on the main thread, which may attempt to acquire any held monitor.
   virtual nsresult Init(int32_t aNumChannels, int32_t aRate) = 0;
 
   // Closes the stream. All future use of the stream is an error.
   // Unsafe to call with a monitor held due to synchronous event execution
   // on the main thread, which may attempt to acquire any held monitor.
   virtual void Shutdown() = 0;
 
-  // Write audio data to the audio hardware.  aBuf is an array of frames in
-  // the format MOZ_AUDIO_DATA_FORMAT of length aCount.  If aFrames is larger
+  // Write audio data to the audio hardware.  aBuf is an array of AudioDataValues
+  // AudioDataValue of length aFrames*mChannels.  If aFrames is larger
   // than the result of Available(), the write will block until sufficient
   // buffer space is available.
-  virtual nsresult Write(const void* aBuf, uint32_t aFrames) = 0;
+  virtual nsresult Write(const mozilla::AudioDataValue* aBuf, uint32_t aFrames) = 0;
 
   // Return the number of audio frames that can be written without blocking.
   virtual uint32_t Available() = 0;
 
   // Set the current volume of the audio playback. This is a value from
   // 0 (meaning muted) to 1 (meaning full volume).  Thread-safe.
   virtual void SetVolume(double aVolume) = 0;
 
--- a/dom/ipc/AudioParent.cpp
+++ b/dom/ipc/AudioParent.cpp
@@ -38,17 +38,17 @@ class AudioWriteEvent : public nsRunnabl
     mParent = parent;
     mOwner = owner;
     mData  = data;
     mFrames = frames;
   }
 
   NS_IMETHOD Run()
   {
-    mOwner->Write(mData.get(), mFrames);
+    mOwner->Write(reinterpret_cast<const AudioDataValue*>(mData.get()), mFrames);
     nsCOMPtr<nsIRunnable> event = new AudioWriteDoneEvent(mParent);
     NS_DispatchToMainThread(event);
     return NS_OK;
   }
 
  private:
     nsRefPtr<AudioParent> mParent;
     nsRefPtr<nsAudioStream> mOwner;