Compare commits
2 Commits
45c97e4503
...
36c74af588
| Author | SHA1 | Date | |
|---|---|---|---|
| 36c74af588 | |||
| aa69aa78ef |
@ -79,7 +79,7 @@ device_manager {
|
||||
id: "ethercat_motors"
|
||||
type: DEVICE_TYPE_MOTOR_SYSTEM
|
||||
config_file: "devices/motor/ethercat_motors.pb.txt"
|
||||
enable: true
|
||||
enable: false
|
||||
}
|
||||
|
||||
devices {
|
||||
@ -93,14 +93,14 @@ device_manager {
|
||||
id: "eyou_arm"
|
||||
type: DEVICE_TYPE_ROBOT_ARM
|
||||
config_file: "devices/arm/arm.pb.txt"
|
||||
enable: true
|
||||
enable: false
|
||||
}
|
||||
|
||||
devices {
|
||||
id: "eyou_left_arm"
|
||||
type: DEVICE_TYPE_ROBOT_ARM
|
||||
config_file: "devices/arm/arm_eyou_left.pb.txt"
|
||||
enable: true
|
||||
enable: false
|
||||
}
|
||||
|
||||
devices {
|
||||
@ -168,13 +168,13 @@ device_manager {
|
||||
type: DEVICE_TYPE_CAMERA
|
||||
config_file: "devices/camera/camera.pb.txt"
|
||||
# Host-development default: keep physical cameras disabled.
|
||||
enable: true
|
||||
enable: false
|
||||
}
|
||||
devices {
|
||||
id: "usb_cam1"
|
||||
type: DEVICE_TYPE_CAMERA
|
||||
config_file: "devices/camera/camera.pb.txt"
|
||||
# Host-development default: keep physical cameras disabled.
|
||||
enable: true
|
||||
enable: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,6 @@ task_manager {
|
||||
type: TASK_TYPE_QUIC_EDGE
|
||||
run_mode: TASK_RUN_MODE_BLOCKING_SERVICE
|
||||
config_file: "tasks/quic_edge_task/quic_edge_task.pb.txt"
|
||||
# Host-development default: no QUIC Gateway or physical media devices.
|
||||
enable: false
|
||||
enable: true
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
add_library(ffmpeg_microphone SHARED src/ffmpeg_microphone.cpp)
|
||||
add_library(ffmpeg_microphone SHARED
|
||||
src/ffmpeg_microphone.cpp
|
||||
src/microphone_device_discovery.cpp
|
||||
)
|
||||
|
||||
target_include_directories(ffmpeg_microphone PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
|
||||
@ -0,0 +1,74 @@
|
||||
#include "devices/microphone/microphone_device_discovery.h"
|
||||
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
extern "C" {
|
||||
#include <libavdevice/avdevice.h>
|
||||
#include <libavutil/error.h>
|
||||
}
|
||||
|
||||
namespace cmvr::device {
|
||||
namespace {
|
||||
|
||||
std::string avErrorToString(int error)
|
||||
{
|
||||
char buffer[AV_ERROR_MAX_STRING_SIZE] = {0};
|
||||
av_strerror(error, buffer, sizeof(buffer));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
struct DeviceListDeleter {
|
||||
void operator()(AVDeviceInfoList* list) const
|
||||
{
|
||||
avdevice_free_list_devices(&list);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
std::vector<MicrophoneInputDeviceInfo> listAvailableMicrophoneInputDevices()
|
||||
{
|
||||
constexpr const char* kBackend = "alsa";
|
||||
|
||||
avdevice_register_all();
|
||||
const AVInputFormat* input_format = av_find_input_format(kBackend);
|
||||
if (!input_format) {
|
||||
throw std::runtime_error("FFmpeg ALSA input backend is unavailable");
|
||||
}
|
||||
|
||||
AVDeviceInfoList* raw_device_list = nullptr;
|
||||
const int result = avdevice_list_input_sources(
|
||||
input_format, nullptr, nullptr, &raw_device_list);
|
||||
std::unique_ptr<AVDeviceInfoList, DeviceListDeleter> device_list(raw_device_list);
|
||||
if (result < 0) {
|
||||
throw std::runtime_error(
|
||||
"Failed to list ALSA microphone devices: " + avErrorToString(result));
|
||||
}
|
||||
|
||||
std::vector<MicrophoneInputDeviceInfo> devices;
|
||||
if (!device_list) {
|
||||
return devices;
|
||||
}
|
||||
devices.reserve(static_cast<std::size_t>(device_list->nb_devices));
|
||||
|
||||
for (int index = 0; index < device_list->nb_devices; ++index) {
|
||||
const AVDeviceInfo* source = device_list->devices[index];
|
||||
if (!source || !source->device_name || source->device_name[0] == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
MicrophoneInputDeviceInfo device;
|
||||
device.input_device = source->device_name;
|
||||
device.display_name = source->device_description && source->device_description[0] != '\0'
|
||||
? source->device_description
|
||||
: source->device_name;
|
||||
device.backend = kBackend;
|
||||
device.is_default = index == device_list->default_device;
|
||||
devices.push_back(std::move(device));
|
||||
}
|
||||
return devices;
|
||||
}
|
||||
|
||||
} // namespace cmvr::device
|
||||
19
cmvr-es/devices/microphone/microphone_device_discovery.h
Normal file
19
cmvr-es/devices/microphone/microphone_device_discovery.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace cmvr::device {
|
||||
|
||||
struct MicrophoneInputDeviceInfo {
|
||||
std::string input_device;
|
||||
std::string display_name;
|
||||
std::string backend;
|
||||
bool is_default{false};
|
||||
};
|
||||
|
||||
// Returns the capture devices that can be used as microphone inputs.
|
||||
// Throws std::runtime_error when the platform backend cannot enumerate devices.
|
||||
std::vector<MicrophoneInputDeviceInfo> listAvailableMicrophoneInputDevices();
|
||||
|
||||
} // namespace cmvr::device
|
||||
@ -18,6 +18,7 @@ target_link_libraries(service PRIVATE
|
||||
cmvr_es::proto
|
||||
osqp
|
||||
cmvr_es::device_manager
|
||||
cmvr_es::device::microphone
|
||||
cmvr_es::task_manager
|
||||
cmvr_es::algorithms::controller
|
||||
cmvr_es::task
|
||||
|
||||
@ -17,6 +17,10 @@ namespace cmvr::service
|
||||
public:
|
||||
gRPCMicroPhoneServiceImpl();
|
||||
~gRPCMicroPhoneServiceImpl() override = default;
|
||||
grpc::Status ListDevices(
|
||||
grpc::ServerContext* context,
|
||||
const api::ListMicrophoneDevicesCommand_Request* request,
|
||||
api::ListMicrophoneDevicesCommand_Feedback* response) override;
|
||||
grpc::Status GetStatus(grpc::ServerContext* context, const api::GetMicStateCommand_Request* request,api::GetMicStateCommand_Feedback* response) override;
|
||||
grpc::Status StartRecord(grpc::ServerContext* context, const api::StartMicRecordingCommand_Request* request,api::StartMicRecordingCommand_Feedback* response) override;
|
||||
grpc::Status StopRecord(grpc::ServerContext* context, const api::StopMicRecordingCommand_Request* request,api::StopMicRecordingCommand_Feedback* response) override;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
#include "common/base/logging/logger.h"
|
||||
#include "devices/microphone/microphone_device_discovery.h"
|
||||
#include "manager/media_source_hub/include/device_media_source_adapter.h"
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
@ -28,6 +29,31 @@ grpc::Status failResponse(ResponseT* response, const std::string& message) {
|
||||
|
||||
gRPCMicroPhoneServiceImpl::gRPCMicroPhoneServiceImpl(): dmgr_(DeviceManager::getInstance()) {}
|
||||
|
||||
grpc::Status gRPCMicroPhoneServiceImpl::ListDevices(
|
||||
grpc::ServerContext* context,
|
||||
const api::ListMicrophoneDevicesCommand_Request* request,
|
||||
api::ListMicrophoneDevicesCommand_Feedback* response) {
|
||||
(void)context;
|
||||
(void)request;
|
||||
try {
|
||||
const auto devices = listAvailableMicrophoneInputDevices();
|
||||
for (const auto& device : devices) {
|
||||
auto* item = response->add_devices();
|
||||
item->set_input_device(device.input_device);
|
||||
item->set_display_name(device.display_name);
|
||||
item->set_backend(device.backend);
|
||||
item->set_is_default(device.is_default);
|
||||
}
|
||||
response->mutable_header()->set_success(true);
|
||||
setCurrentTimestamp(response->mutable_header()->mutable_timestamp());
|
||||
CMVR_LOG(INFO) << "[gRPCMicroPhoneServiceImpl] (ListDevices): found "
|
||||
<< devices.size() << " microphone input device(s)";
|
||||
return grpc::Status::OK;
|
||||
} catch (const std::exception& e) {
|
||||
return failResponse(response, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
grpc::Status gRPCMicroPhoneServiceImpl::GetStatus(grpc::ServerContext* context,
|
||||
const api::GetMicStateCommand_Request* request, api::GetMicStateCommand_Feedback* response) {
|
||||
try {
|
||||
|
||||
@ -12,6 +12,22 @@ message MicState {
|
||||
string error_message = 5;
|
||||
}
|
||||
|
||||
message MicrophoneInputDevice {
|
||||
string input_device = 1;
|
||||
string display_name = 2;
|
||||
string backend = 3;
|
||||
bool is_default = 4;
|
||||
}
|
||||
|
||||
message ListMicrophoneDevicesCommand {
|
||||
message Request {}
|
||||
|
||||
message Feedback {
|
||||
CommandHeader.Feedback header = 1;
|
||||
repeated MicrophoneInputDevice devices = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message GetMicStateCommand {
|
||||
message Request {
|
||||
CommandHeader.Request header = 1;
|
||||
|
||||
@ -5,6 +5,7 @@ import "cmvr/api/microphone_command.proto";
|
||||
package cmvr.api;
|
||||
|
||||
service MicPhoneService {
|
||||
rpc ListDevices(ListMicrophoneDevicesCommand.Request) returns (ListMicrophoneDevicesCommand.Feedback);
|
||||
rpc GetStatus(GetMicStateCommand.Request) returns (GetMicStateCommand.Feedback);
|
||||
rpc StartRecord(StartMicRecordingCommand.Request) returns (StartMicRecordingCommand.Feedback);
|
||||
rpc StopRecord(StopMicRecordingCommand.Request) returns (StopMicRecordingCommand.Feedback);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user