Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "SpeechStreamListener.h"
8 :
9 : #include "SpeechRecognition.h"
10 : #include "nsProxyRelease.h"
11 :
12 : namespace mozilla {
13 : namespace dom {
14 :
15 0 : SpeechStreamListener::SpeechStreamListener(SpeechRecognition* aRecognition)
16 0 : : mRecognition(aRecognition)
17 : {
18 0 : }
19 :
20 0 : SpeechStreamListener::~SpeechStreamListener()
21 : {
22 : NS_ReleaseOnMainThread(
23 0 : "SpeechStreamListener::mRecognition", mRecognition.forget());
24 0 : }
25 :
26 : void
27 0 : SpeechStreamListener::NotifyQueuedAudioData(MediaStreamGraph* aGraph, TrackID aID,
28 : StreamTime aTrackOffset,
29 : const AudioSegment& aQueuedMedia,
30 : MediaStream* aInputStream,
31 : TrackID aInputTrackID)
32 : {
33 : AudioSegment* audio = const_cast<AudioSegment*>(
34 0 : static_cast<const AudioSegment*>(&aQueuedMedia));
35 :
36 0 : AudioSegment::ChunkIterator iterator(*audio);
37 0 : while (!iterator.IsEnded()) {
38 : // Skip over-large chunks so we don't crash!
39 0 : if (iterator->GetDuration() > INT_MAX) {
40 0 : continue;
41 : }
42 0 : int duration = int(iterator->GetDuration());
43 :
44 0 : if (iterator->IsNull()) {
45 0 : nsTArray<int16_t> nullData;
46 0 : PodZero(nullData.AppendElements(duration), duration);
47 0 : ConvertAndDispatchAudioChunk(duration, iterator->mVolume,
48 0 : nullData.Elements(), aGraph->GraphRate());
49 : } else {
50 0 : AudioSampleFormat format = iterator->mBufferFormat;
51 :
52 0 : MOZ_ASSERT(format == AUDIO_FORMAT_S16 || format == AUDIO_FORMAT_FLOAT32);
53 :
54 0 : if (format == AUDIO_FORMAT_S16) {
55 0 : ConvertAndDispatchAudioChunk(duration,iterator->mVolume,
56 0 : static_cast<const int16_t*>(iterator->mChannelData[0]),
57 0 : aGraph->GraphRate());
58 0 : } else if (format == AUDIO_FORMAT_FLOAT32) {
59 0 : ConvertAndDispatchAudioChunk(duration,iterator->mVolume,
60 0 : static_cast<const float*>(iterator->mChannelData[0]),
61 0 : aGraph->GraphRate());
62 : }
63 : }
64 :
65 0 : iterator.Next();
66 : }
67 0 : }
68 :
69 : template<typename SampleFormatType> void
70 0 : SpeechStreamListener::ConvertAndDispatchAudioChunk(int aDuration, float aVolume,
71 : SampleFormatType* aData,
72 : TrackRate aTrackRate)
73 : {
74 0 : RefPtr<SharedBuffer> samples(SharedBuffer::Create(aDuration *
75 : 1 * // channel
76 0 : sizeof(int16_t)));
77 :
78 0 : int16_t* to = static_cast<int16_t*>(samples->Data());
79 0 : ConvertAudioSamplesWithScale(aData, to, aDuration, aVolume);
80 :
81 0 : mRecognition->FeedAudioData(samples.forget(), aDuration, this, aTrackRate);
82 0 : }
83 :
84 : void
85 0 : SpeechStreamListener::NotifyEvent(MediaStreamGraph* aGraph,
86 : MediaStreamGraphEvent event)
87 : {
88 : // TODO dispatch SpeechEnd event so services can be informed
89 0 : }
90 :
91 : } // namespace dom
92 : } // namespace mozilla
|