Bug 858529 - Add nsISpeechTask.SendAudioNative. r=smaug

This commit is contained in:
Eitan Isaacson 2013-08-21 12:39:27 -07:00
parent 566ad3643e
commit 57f8a1270b
5 changed files with 50 additions and 14 deletions

View File

@ -158,6 +158,12 @@ SpeechTaskChild::SendAudio(const JS::Value& aData, const JS::Value& aLandmarks,
MOZ_CRASH("Should never be called from child");
}
NS_IMETHODIMP
SpeechTaskChild::SendAudioNative(int16_t* aData, uint32_t aDataLen)
{
MOZ_CRASH("Should never be called from child");
}
void
SpeechTaskChild::Pause()
{

View File

@ -78,8 +78,10 @@ public:
NS_IMETHOD Setup(nsISpeechTaskCallback* aCallback,
uint32_t aChannels, uint32_t aRate, uint8_t argc) MOZ_OVERRIDE;
NS_IMETHOD SendAudio (const JS::Value& aData, const JS::Value& aLandmarks,
JSContext* aCx) MOZ_OVERRIDE;
NS_IMETHOD SendAudio(const JS::Value& aData, const JS::Value& aLandmarks,
JSContext* aCx) MOZ_OVERRIDE;
NS_IMETHOD SendAudioNative(int16_t* aData, uint32_t aDataLen) MOZ_OVERRIDE;
virtual void Pause();

View File

@ -36,7 +36,7 @@ interface nsISpeechTaskCallback : nsISupports
* A task is associated with a single utterance. It is provided by the browser
* to the service in the speak() method.
*/
[scriptable, builtinclass, uuid(3a60c397-7a04-4cf7-99ea-7432e7a0a1c1)]
[scriptable, builtinclass, uuid(ad59949c-2437-4b35-8eeb-d760caab75c5)]
interface nsISpeechTask : nsISupports
{
/**
@ -61,6 +61,9 @@ interface nsISpeechTask : nsISupports
[implicit_jscontext]
void sendAudio(in jsval aData, in jsval aLandmarks);
[noscript]
void sendAudioNative([array, size_is(aDataLen)] in short aData, in unsigned long aDataLen);
/**
* Dispatch start event.
*/

View File

@ -175,31 +175,54 @@ nsSpeechTask::SendAudio(const JS::Value& aData, const JS::Value& aLandmarks,
return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
}
uint32_t dataLength = JS_GetTypedArrayLength(tsrc);
SendAudioImpl(JS_GetInt16ArrayData(tsrc),
JS_GetTypedArrayLength(tsrc));
if (dataLength == 0) {
return NS_OK;
}
NS_IMETHODIMP
nsSpeechTask::SendAudioNative(int16_t* aData, uint32_t aDataLen)
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
NS_ENSURE_TRUE(mStream, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_FALSE(mStream->IsDestroyed(), NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(mChannels, NS_ERROR_FAILURE);
if (mIndirectAudio) {
NS_WARNING("Can't call SendAudio from an indirect audio speech service.");
return NS_ERROR_FAILURE;
}
SendAudioImpl(aData, aDataLen);
return NS_OK;
}
void
nsSpeechTask::SendAudioImpl(int16_t* aData, uint32_t aDataLen)
{
if (aDataLen == 0) {
// XXX: We should end the track too, an undetermined bug does not allow that.
mStream->Finish();
return NS_OK;
return;
}
nsRefPtr<mozilla::SharedBuffer> samples =
SharedBuffer::Create(dataLength * sizeof(int16_t));
SharedBuffer::Create(aDataLen * sizeof(int16_t));
int16_t* frames = static_cast<int16_t*>(samples->Data());
int16_t* sframes = JS_GetInt16ArrayData(tsrc);
for (uint32_t i = 0; i < dataLength; i++) {
frames[i] = sframes[i];
for (uint32_t i = 0; i < aDataLen; i++) {
frames[i] = aData[i];
}
AudioSegment segment;
nsAutoTArray<const int16_t*, 1> channelData;
channelData.AppendElement(frames);
segment.AppendFrames(samples.forget(), channelData, dataLength);
segment.AppendFrames(samples.forget(), channelData, aDataLen);
mStream->AppendToTrack(1, &segment);
mStream->AdvanceKnownTracksTime(STREAM_TIME_MAX);
return NS_OK;
}
NS_IMETHODIMP
@ -360,7 +383,7 @@ nsSpeechTask::DispatchBoundary(const nsAString& aName,
nsresult
nsSpeechTask::DispatchBoundaryImpl(const nsAString& aName,
float aElapsedTime, uint32_t aCharIndex)
float aElapsedTime, uint32_t aCharIndex)
{
MOZ_ASSERT(mUtterance);
NS_ENSURE_TRUE(mUtterance->mState == SpeechSynthesisUtterance::STATE_SPEAKING,

View File

@ -73,6 +73,8 @@ protected:
private:
void End();
void SendAudioImpl(int16_t* aData, uint32_t aDataLen);
nsRefPtr<SourceMediaStream> mStream;
nsCOMPtr<nsISpeechTaskCallback> mCallback;