blob: b53e9d24df3143cf440dad52ab07e7e69dd0be5e [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/renderer/media/chrome_speech_recognition_client.h"
#include "content/public/renderer/render_frame.h"
#include "media/mojo/mojom/media_types.mojom.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
ChromeSpeechRecognitionClient::ChromeSpeechRecognitionClient(
content::RenderFrame* render_frame) {
mojo::PendingReceiver<media::mojom::SpeechRecognitionContext>
speech_recognition_context_receiver =
speech_recognition_context_.BindNewPipeAndPassReceiver();
speech_recognition_context_->BindRecognizer(
speech_recognition_recognizer_.BindNewPipeAndPassReceiver(),
speech_recognition_client_receiver_.BindNewPipeAndPassRemote());
render_frame->GetBrowserInterfaceBroker()->GetInterface(
std::move(speech_recognition_context_receiver));
}
ChromeSpeechRecognitionClient::~ChromeSpeechRecognitionClient() = default;
void ChromeSpeechRecognitionClient::AddAudio(
scoped_refptr<media::AudioBuffer> buffer) {
DCHECK(buffer);
if (IsSpeechRecognitionAvailable()) {
speech_recognition_recognizer_->SendAudioToSpeechRecognitionService(
ConvertToAudioDataS16(std::move(buffer)));
}
}
bool ChromeSpeechRecognitionClient::IsSpeechRecognitionAvailable() {
return speech_recognition_recognizer_.is_bound() &&
speech_recognition_recognizer_.is_connected();
}
void ChromeSpeechRecognitionClient::OnSpeechRecognitionRecognitionEvent(
const std::string& transcription) {
// TODO(evliu): Pass the captions to the caption controller.
NOTIMPLEMENTED();
}
media::mojom::AudioDataS16Ptr
ChromeSpeechRecognitionClient::ConvertToAudioDataS16(
scoped_refptr<media::AudioBuffer> buffer) {
DCHECK_GT(buffer->frame_count(), 0);
DCHECK_GT(buffer->channel_count(), 0);
DCHECK_GT(buffer->sample_rate(), 0);
auto signed_buffer = media::mojom::AudioDataS16::New();
signed_buffer->channel_count = buffer->channel_count();
signed_buffer->frame_count = buffer->frame_count();
signed_buffer->sample_rate = buffer->sample_rate();
if (buffer->sample_format() == media::SampleFormat::kSampleFormatS16) {
int16_t* audio_data = reinterpret_cast<int16_t*>(buffer->channel_data()[0]);
signed_buffer->data.assign(
audio_data,
audio_data + buffer->frame_count() * buffer->channel_count());
return signed_buffer;
}
// Convert the raw audio to the interleaved signed int 16 sample type.
if (!temp_audio_bus_ ||
buffer->channel_count() != temp_audio_bus_->channels() ||
buffer->frame_count() != temp_audio_bus_->frames()) {
temp_audio_bus_ =
media::AudioBus::Create(buffer->channel_count(), buffer->frame_count());
}
buffer->ReadFrames(buffer->frame_count(),
/* source_frame_offset */ 0, /* dest_frame_offset */ 0,
temp_audio_bus_.get());
signed_buffer->data.resize(buffer->frame_count() * buffer->channel_count());
temp_audio_bus_->ToInterleaved<media::SignedInt16SampleTypeTraits>(
temp_audio_bus_->frames(), &signed_buffer->data[0]);
return signed_buffer;
}