Apollo 10.0
自动驾驶开放平台
respeaker.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2020 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
16
18
19namespace apollo {
20namespace drivers {
21namespace microphone {
22
23PaError err;
24
25// Helper functions
26void report_error(PaError err, const std::string &func_name) {
27 AERROR << "an error occured while calling " << func_name;
28 AERROR << "error number: " << err;
29 AERROR << "error message: " << Pa_GetErrorText(err);
30}
31
32// Stream
34 Pa_CloseStream(pastream_ptr_);
35 delete input_parameters_ptr_;
36}
37
38void Stream::init_stream(int rate, int channels, int chunk,
39 int input_device_index, PaSampleFormat format) {
40 // Init parameters of input device
41 input_parameters_ptr_ = new PaStreamParameters;
42 input_parameters_ptr_->device = input_device_index;
43 input_parameters_ptr_->channelCount = channels;
44 input_parameters_ptr_->sampleFormat = format;
45 input_parameters_ptr_->suggestedLatency =
46 Pa_GetDeviceInfo(input_parameters_ptr_->device)->defaultLowInputLatency;
47 input_parameters_ptr_->hostApiSpecificStreamInfo = nullptr;
48
49 err = Pa_OpenStream(
50 &pastream_ptr_, input_parameters_ptr_, nullptr, rate, chunk,
51 paClipOff, // we only use input so don't bother clipping them *
52 nullptr, nullptr);
53 if (err != paNoError) {
54 report_error(err, "Pa_OpenStream");
55 }
56 err = Pa_StartStream(pastream_ptr_);
57 if (err != paNoError) {
58 report_error(err, "Pa_StartStream");
59 }
60}
61
62void Stream::read_stream(int n_frames, char *buffer) const {
63 err =
64 Pa_ReadStream(pastream_ptr_, reinterpret_cast<void *>(buffer), n_frames);
65 if (err != paNoError) {
66 report_error(err, "Pa_ReadStream");
67 throw std::runtime_error("");
68 }
69}
70
71// Respeaker
72Respeaker::~Respeaker() { Pa_Terminate(); }
74 const std::shared_ptr<const MicrophoneConfig> &microphone_config) {
75 if (microphone_config->microphone_model() != MicrophoneConfig::RESPEAKER) {
76 AERROR << "Microphone driver only supports respeaker model in config file";
77 }
78 err = Pa_Initialize();
79 if (err != paNoError) {
80 Pa_Terminate();
81 report_error(err, "Pa_Initialize");
82 }
83
84 const PaDeviceIndex device_index = get_respeaker_index();
85 stream_ptr_.reset(new Stream());
86 stream_ptr_->init_stream(
87 microphone_config->sample_rate(), microphone_config->channel_type_size(),
88 microphone_config->chunk(), device_index,
89 get_format_from_width(microphone_config->sample_width()));
90}
91
92const PaSampleFormat Respeaker::get_format_from_width(int width,
93 bool is_unsigned) const {
94 switch (width) {
95 case 1:
96 return is_unsigned ? paUInt8 : paInt8;
97 case 2:
98 return paInt16;
99 case 3:
100 return paInt24;
101 case 4:
102 return paFloat32;
103 default:
104 break;
105 }
106 AERROR << "invalid width: " << width;
107 return -1;
108}
109
110const PaDeviceIndex Respeaker::get_respeaker_index() const {
111 // return index of respeaker
112 const PaHostApiInfo *host_api_info = get_host_api_info(0);
113 const PaDeviceInfo *device_info = nullptr;
114 PaDeviceIndex real_index;
115 for (PaDeviceIndex i = 0; i < host_api_info->deviceCount; ++i) {
116 real_index = host_api_device_index_to_device_index(0, i);
117 device_info = get_device_info(real_index);
118 if (std::string(device_info->name).find("ReSpeaker") != std::string::npos) {
119 return real_index;
120 }
121 }
122 AERROR << "respeaker device not found";
123 return -1;
124}
125
126const PaDeviceInfo *Respeaker::get_device_info(
127 const PaDeviceIndex index) const {
128 const PaDeviceInfo *device_info =
129 reinterpret_cast<const PaDeviceInfo *>(Pa_GetDeviceInfo(index));
130 if (!device_info) {
131 AERROR << "internal error: invalid device index" << index;
132 }
133
134 return device_info;
135}
136
137const PaDeviceIndex Respeaker::host_api_device_index_to_device_index(
138 const PaHostApiIndex host_api, const int host_api_device_index) const {
139 // Get standard device index from host-API-specific device index
140 PaDeviceIndex device_index =
141 Pa_HostApiDeviceIndexToDeviceIndex(host_api, host_api_device_index);
142 if (device_index < 0) {
143 report_error(device_index, "Pa_HostApiDeviceIndexToDeviceIndex");
144 }
145 return device_index;
146}
147
148const PaHostApiInfo *Respeaker::get_host_api_info(
149 const PaHostApiIndex index) const {
150 // Get host api info by it's index
151 const PaHostApiInfo *pa_host_api_info =
152 reinterpret_cast<const PaHostApiInfo *>(Pa_GetHostApiInfo(index));
153 if (!pa_host_api_info) {
154 AERROR << "internal error: invalid Host Api Index " << index;
155 }
156 return pa_host_api_info;
157}
158
159void Respeaker::read_stream(int n_frames, char *buffer) const {
160 stream_ptr_->read_stream(n_frames, buffer);
161}
162
163} // namespace microphone
164} // namespace drivers
165} // namespace apollo
void init(const std::shared_ptr< const MicrophoneConfig > &microphone_config)
Definition respeaker.cc:73
void read_stream(int n_frames, char *buffer) const
Definition respeaker.cc:159
void read_stream(int n_frames, char *buffer) const
Definition respeaker.cc:62
void init_stream(int rate, int channels, int chunk, int input_device_index, PaSampleFormat format)
Definition respeaker.cc:38
#define AERROR
Definition log.h:44
void report_error(PaError err, const std::string &func_name)
Definition respeaker.cc:26
class register implement
Definition arena_queue.h:37