diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2022-09-05 02:21:37 -0400 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2022-09-05 02:21:37 -0400 |
commit | e93b8715f9e42d25c0930becc22561f23a25a709 (patch) | |
tree | b1371f3006f11a073de050d60a540e713389252a /src/audio/manager.cpp | |
parent | b7fffb8691c6010864d88b273f346419eb5a5d2b (diff) | |
download | abaddon-portaudio-e93b8715f9e42d25c0930becc22561f23a25a709.tar.gz abaddon-portaudio-e93b8715f9e42d25c0930becc22561f23a25a709.zip |
basic voice capture + transmission
Diffstat (limited to 'src/audio/manager.cpp')
-rw-r--r-- | src/audio/manager.cpp | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/src/audio/manager.cpp b/src/audio/manager.cpp index 9d380f9..b665c81 100644 --- a/src/audio/manager.cpp +++ b/src/audio/manager.cpp @@ -39,9 +39,25 @@ void data_callback(ma_device *pDevice, void *pOutput, const void *pInput, ma_uin } } +void capture_data_callback(ma_device *pDevice, void *pOutput, const void *pInput, ma_uint32 frameCount) { + auto *mgr = reinterpret_cast<AudioManager *>(pDevice->pUserData); + if (mgr == nullptr) return; + + mgr->OnCapturedPCM(static_cast<const int16_t *>(pInput), frameCount); +} + AudioManager::AudioManager() { m_ok = true; + int err; + m_encoder = opus_encoder_create(48000, 2, OPUS_APPLICATION_VOIP, &err); + if (err != OPUS_OK) { + printf("failed to initialize opus encoder: %d\n", err); + m_ok = false; + return; + } + opus_encoder_ctl(m_encoder, OPUS_SET_BITRATE(64000)); + m_device_config = ma_device_config_init(ma_device_type_playback); m_device_config.playback.format = ma_format_f32; m_device_config.playback.channels = 2; @@ -50,7 +66,7 @@ AudioManager::AudioManager() { m_device_config.pUserData = this; if (ma_device_init(nullptr, &m_device_config, &m_device) != MA_SUCCESS) { - puts("open playabck fail"); + puts("open playback fail"); m_ok = false; return; } @@ -61,15 +77,45 @@ AudioManager::AudioManager() { m_ok = false; return; } + + m_capture_config = ma_device_config_init(ma_device_type_capture); + m_capture_config.capture.format = ma_format_s16; + m_capture_config.capture.channels = 2; + m_capture_config.sampleRate = 48000; + m_capture_config.periodSizeInFrames = 480; + m_capture_config.dataCallback = capture_data_callback; + m_capture_config.pUserData = this; + + if (ma_device_init(nullptr, &m_capture_config, &m_capture_device) != MA_SUCCESS) { + puts("open capture fail"); + m_ok = false; + return; + } + + if (ma_device_start(&m_capture_device) != MA_SUCCESS) { + puts("failed to start capture"); + ma_device_uninit(&m_capture_device); + m_ok = false; + return; + } + + char device_name[MA_MAX_DEVICE_NAME_LENGTH + 1]; + ma_device_get_name(&m_capture_device, ma_device_type_capture, device_name, sizeof(device_name), nullptr); + printf("using %s for capture\n", device_name); } AudioManager::~AudioManager() { ma_device_uninit(&m_device); + ma_device_uninit(&m_capture_device); for (auto &[ssrc, pair] : m_sources) { opus_decoder_destroy(pair.second); } } +void AudioManager::SetOpusBuffer(uint8_t *ptr) { + m_opus_buffer = ptr; +} + void AudioManager::FeedMeOpus(uint32_t ssrc, const std::vector<uint8_t> &data) { size_t payload_size = 0; const auto *opus_encoded = StripRTPExtensionHeader(data.data(), static_cast<int>(data.size()), payload_size); @@ -89,7 +135,22 @@ void AudioManager::FeedMeOpus(uint32_t ssrc, const std::vector<uint8_t> &data) { } } +void AudioManager::OnCapturedPCM(const int16_t *pcm, ma_uint32 frames) { + if (m_opus_buffer == nullptr) return; + + int payload_len = opus_encode(m_encoder, pcm, 480, static_cast<unsigned char *>(m_opus_buffer), 1275); + if (payload_len < 0) { + printf("encoding error: %d\n", payload_len); + } else { + m_signal_opus_packet.emit(payload_len); + } +} + bool AudioManager::OK() const { return m_ok; } + +AudioManager::type_signal_opus_packet AudioManager::signal_opus_packet() { + return m_signal_opus_packet; +} #endif |