record_audio.cc
Go to the documentation of this file.
1 // Copyright (c) 2017, The Regents of the University of California
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name of the University of California nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 // ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OF THE UNIVERSITY OF CALIFORNIA
19 // BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 // POSSIBILITY OF SUCH DAMAGE.
26 
28 
29 #include <cmath>
30 #include <memory>
31 #include <string>
32 #include <thread>
33 #include <utility>
34 #include <vector>
35 
37 #include "third_party/portaudio.h"
38 #include "third_party/glog.h"
39 #include "third_party/gflags.h"
40 
41 DEFINE_string(mic, "USB", "Name of the microphone");
42 
43 using std::unique_ptr;
44 using std::string;
45 
46 namespace cogrob {
47 namespace cloud {
48 namespace speech {
49 
51  queue_ = output_queue;
53 }
54 
56  StopRecording();
57 }
58 
60  PaError pa_err = paNoError;
61 
62  // Intialize PortAudio
63  pa_err = Pa_Initialize();
64  if (pa_err != paNoError) {
65  LOG(FATAL) << "PortAudio init error: " << Pa_GetErrorText(pa_err);
66  }
67 
68  // Find the microphone
69  PaDeviceIndex num_devices;
70  num_devices = Pa_GetDeviceCount();
71  if (num_devices < 0) {
72  LOG(FATAL) << "Pa_CountDevices returned " << num_devices;
73  }
74  bool found_mic = false;
75  PaDeviceIndex device_index = 0;
76  const PaDeviceInfo* device_info;
77  for (PaDeviceIndex i = 0; i < num_devices; ++i) {
78  device_info = Pa_GetDeviceInfo(i);
79  LOG(INFO) << "Device " << device_info->name << " has "
80  << device_info->maxInputChannels << " input channels.";
81  if (string(device_info->name).find(FLAGS_mic) != string::npos) {
82  found_mic = true;
83  device_index = i;
84  LOG(INFO) << "Use device " << device_info->name;
85  break;
86  }
87  }
88  if (!found_mic) {
89  LOG(FATAL) << "Can not find device " << FLAGS_mic;
90  }
91 
92  // Open an audio I/O stream
93  PaStreamParameters input_param = {
94  .device = device_index,
95  .channelCount = 1,
96  .sampleFormat = paInt16,
97  .suggestedLatency = 0,
98  .hostApiSpecificStreamInfo = nullptr
99  };
100 
101  pa_err = Pa_OpenStream(&pa_stream_, &input_param, nullptr, SAMPLE_RATE,
102  SAMPLES_PER_SLICE, paNoFlag,
104 
105  if (pa_err != paNoError) {
106  LOG(FATAL) << "PortAudio open stream error: " << Pa_GetErrorText(pa_err);
107  }
108  // Start the stream
109  Pa_StartStream(pa_stream_);
110  if (pa_err != paNoError) {
111  LOG(FATAL) << "PortAudio start stream error: " << Pa_GetErrorText(pa_err);
112  }
113 
114 }
115 
117  PaError pa_err = paNoError;
118  Pa_StopStream(pa_stream_);
119  if (pa_err != paNoError) {
120  LOG(FATAL) << "PortAudio stop stream error: " << Pa_GetErrorText(pa_err);
121  }
122  Pa_CloseStream(pa_stream_);
123  if (pa_err != paNoError) {
124  LOG(FATAL) << "PortAudio close stream error: " << Pa_GetErrorText(pa_err);
125  }
126 }
127 
129  const void* input, void* output, unsigned long frame_count,
130  const PaStreamCallbackTimeInfo* time_info,
131  PaStreamCallbackFlags status_flags, void* user_data) {
132  AudioRecorder* recorder = static_cast<AudioRecorder*>(user_data);
133 
134  LOG_IF(ERROR, frame_count != SAMPLES_PER_SLICE) << "Callback frame_count is "
135  << frame_count << ", which is not " << SAMPLES_PER_SLICE;
136  LOG_IF(ERROR, status_flags) << "Callback status flag is " << status_flags;
137 
138  std::unique_ptr<AudioSample> audio_sample(new AudioSample());
139  audio_sample->resize(frame_count * 2);
140 
141  memcpy(audio_sample->data(), input, frame_count * 2);
142 
143  recorder->queue_->push(std::move(audio_sample));
144 
145  return paContinue;
146 }
147 
148 } // namespace speech
149 } // namespace cloud
150 } // namespace cogrob
DEFINE_string(mic,"USB","Name of the microphone")
constexpr size_t SAMPLE_RATE
Definition: audio_sample.h:39
static int PortAudioCallback(const void *input, void *output, unsigned long frame_count, const PaStreamCallbackTimeInfo *time_info, PaStreamCallbackFlags status_flags, void *user_data)
AudioRecorder(AudioQueue *output_queue)
Definition: record_audio.cc:50
std::vector< uint8_t > AudioSample
Definition: audio_sample.h:43
constexpr size_t SAMPLES_PER_SLICE
Definition: audio_sample.h:40


gcloud_speech
Author(s):
autogenerated on Mon Jun 10 2019 13:20:53