mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-20 05:23:12 -07:00
Init Audio Output correctly
This commit is contained in:
parent
d8226f2693
commit
c8ce9f899e
4 changed files with 67 additions and 29 deletions
|
@ -79,6 +79,9 @@ class StreamSession : public QObject
|
||||||
void PushVideoSample(uint8_t *buf, size_t buf_size);
|
void PushVideoSample(uint8_t *buf, size_t buf_size);
|
||||||
void Event(ChiakiEvent *event);
|
void Event(ChiakiEvent *event);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void InitAudio(unsigned int channels, unsigned int rate);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StreamSession(const StreamSessionConnectInfo &connect_info, QObject *parent = nullptr);
|
explicit StreamSession(const StreamSessionConnectInfo &connect_info, QObject *parent = nullptr);
|
||||||
~StreamSession();
|
~StreamSession();
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
static void AudioSettingsCb(uint32_t channels, uint32_t rate, void *user);
|
||||||
static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user);
|
static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user);
|
||||||
static void VideoSampleCb(uint8_t *buf, size_t buf_size, void *user);
|
static void VideoSampleCb(uint8_t *buf, size_t buf_size, void *user);
|
||||||
static void EventCb(ChiakiEvent *event, void *user);
|
static void EventCb(ChiakiEvent *event, void *user);
|
||||||
|
@ -39,7 +40,9 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
|
||||||
#if CHIAKI_GUI_ENABLE_QT_GAMEPAD
|
#if CHIAKI_GUI_ENABLE_QT_GAMEPAD
|
||||||
gamepad(nullptr),
|
gamepad(nullptr),
|
||||||
#endif
|
#endif
|
||||||
video_decoder(log.GetChiakiLog())
|
video_decoder(log.GetChiakiLog()),
|
||||||
|
audio_output(nullptr),
|
||||||
|
audio_io(nullptr)
|
||||||
{
|
{
|
||||||
QByteArray host_str = connect_info.host.toUtf8();
|
QByteArray host_str = connect_info.host.toUtf8();
|
||||||
QByteArray registkey_str = connect_info.registkey.toUtf8();
|
QByteArray registkey_str = connect_info.registkey.toUtf8();
|
||||||
|
@ -71,30 +74,13 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
|
||||||
if(err != CHIAKI_ERR_SUCCESS || did_size != sizeof(chiaki_connect_info.did))
|
if(err != CHIAKI_ERR_SUCCESS || did_size != sizeof(chiaki_connect_info.did))
|
||||||
throw ChiakiException("Did invalid");
|
throw ChiakiException("Did invalid");
|
||||||
|
|
||||||
// TODO: move audio init out of here and use values from audio header
|
|
||||||
QAudioFormat audio_format;
|
|
||||||
audio_format.setSampleRate(48000);
|
|
||||||
audio_format.setChannelCount(2);
|
|
||||||
audio_format.setSampleSize(16);
|
|
||||||
audio_format.setCodec("audio/pcm");
|
|
||||||
audio_format.setSampleType(QAudioFormat::SignedInt);
|
|
||||||
|
|
||||||
QAudioDeviceInfo audio_device_info(QAudioDeviceInfo::defaultOutputDevice());
|
|
||||||
if(!audio_device_info.isFormatSupported(audio_format))
|
|
||||||
{
|
|
||||||
printf("audio output format not supported\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
audio_output = new QAudioOutput(audio_format, this);
|
|
||||||
audio_io = audio_output->start();
|
|
||||||
|
|
||||||
memset(&keyboard_state, 0, sizeof(keyboard_state));
|
memset(&keyboard_state, 0, sizeof(keyboard_state));
|
||||||
|
|
||||||
err = chiaki_session_init(&session, &chiaki_connect_info, log.GetChiakiLog());
|
err = chiaki_session_init(&session, &chiaki_connect_info, log.GetChiakiLog());
|
||||||
if(err != CHIAKI_ERR_SUCCESS)
|
if(err != CHIAKI_ERR_SUCCESS)
|
||||||
throw ChiakiException("Chiaki Session Init failed: " + QString::fromLocal8Bit(chiaki_error_string(err)));
|
throw ChiakiException("Chiaki Session Init failed: " + QString::fromLocal8Bit(chiaki_error_string(err)));
|
||||||
|
|
||||||
chiaki_session_set_audio_frame_cb(&session, AudioFrameCb, this);
|
chiaki_session_set_audio_cb(&session, AudioSettingsCb, AudioFrameCb, this);
|
||||||
chiaki_session_set_video_sample_cb(&session, VideoSampleCb, this);
|
chiaki_session_set_video_sample_cb(&session, VideoSampleCb, this);
|
||||||
chiaki_session_set_event_cb(&session, EventCb, this);
|
chiaki_session_set_event_cb(&session, EventCb, this);
|
||||||
|
|
||||||
|
@ -106,11 +92,11 @@ StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObje
|
||||||
|
|
||||||
StreamSession::~StreamSession()
|
StreamSession::~StreamSession()
|
||||||
{
|
{
|
||||||
|
chiaki_session_join(&session);
|
||||||
|
chiaki_session_fini(&session);
|
||||||
#if CHIAKI_GUI_ENABLE_QT_GAMEPAD
|
#if CHIAKI_GUI_ENABLE_QT_GAMEPAD
|
||||||
delete gamepad;
|
delete gamepad;
|
||||||
#endif
|
#endif
|
||||||
chiaki_session_join(&session);
|
|
||||||
chiaki_session_fini(&session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StreamSession::Start()
|
void StreamSession::Start()
|
||||||
|
@ -243,8 +229,40 @@ void StreamSession::SendFeedbackState()
|
||||||
chiaki_session_set_controller_state(&session, &state);
|
chiaki_session_set_controller_state(&session, &state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StreamSession::InitAudio(unsigned int channels, unsigned int rate)
|
||||||
|
{
|
||||||
|
delete audio_output;
|
||||||
|
audio_output = nullptr;
|
||||||
|
audio_io = nullptr;
|
||||||
|
|
||||||
|
QAudioFormat audio_format;
|
||||||
|
audio_format.setSampleRate(rate);
|
||||||
|
audio_format.setChannelCount(channels);
|
||||||
|
audio_format.setSampleSize(16);
|
||||||
|
audio_format.setCodec("audio/pcm");
|
||||||
|
audio_format.setSampleType(QAudioFormat::SignedInt);
|
||||||
|
|
||||||
|
QAudioDeviceInfo audio_device_info(QAudioDeviceInfo::defaultOutputDevice());
|
||||||
|
if(!audio_device_info.isFormatSupported(audio_format))
|
||||||
|
{
|
||||||
|
CHIAKI_LOGE(log.GetChiakiLog(), "Audio Format with %u channels @ %u Hz not supported by Audio Device %s",
|
||||||
|
channels, rate,
|
||||||
|
audio_device_info.deviceName().toLocal8Bit().constData());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
audio_output = new QAudioOutput(audio_format, this);
|
||||||
|
audio_io = audio_output->start();
|
||||||
|
|
||||||
|
CHIAKI_LOGI(log.GetChiakiLog(), "Audio Device %s opened with %u channels @ %u Hz",
|
||||||
|
audio_device_info.deviceName().toLocal8Bit().constData(),
|
||||||
|
channels, rate);
|
||||||
|
}
|
||||||
|
|
||||||
void StreamSession::PushAudioFrame(int16_t *buf, size_t samples_count)
|
void StreamSession::PushAudioFrame(int16_t *buf, size_t samples_count)
|
||||||
{
|
{
|
||||||
|
if(!audio_io)
|
||||||
|
return;
|
||||||
audio_io->write((const char *)buf, static_cast<qint64>(samples_count * 2 * 2));
|
audio_io->write((const char *)buf, static_cast<qint64>(samples_count * 2 * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -266,11 +284,22 @@ void StreamSession::Event(ChiakiEvent *event)
|
||||||
class StreamSessionPrivate
|
class StreamSessionPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void PushAudioFrame(StreamSession *session, int16_t *buf, size_t samples_count) { session->PushAudioFrame(buf, samples_count); }
|
static void InitAudio(StreamSession *session, uint32_t channels, uint32_t rate)
|
||||||
static void PushVideoSample(StreamSession *session, uint8_t *buf, size_t buf_size) { session->PushVideoSample(buf, buf_size); }
|
{
|
||||||
static void Event(StreamSession *session, ChiakiEvent *event) { session->Event(event); }
|
QMetaObject::invokeMethod(session, "InitAudio", Qt::ConnectionType::BlockingQueuedConnection, Q_ARG(unsigned int, channels), Q_ARG(unsigned int, rate));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PushAudioFrame(StreamSession *session, int16_t *buf, size_t samples_count) { session->PushAudioFrame(buf, samples_count); }
|
||||||
|
static void PushVideoSample(StreamSession *session, uint8_t *buf, size_t buf_size) { session->PushVideoSample(buf, buf_size); }
|
||||||
|
static void Event(StreamSession *session, ChiakiEvent *event) { session->Event(event); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void AudioSettingsCb(uint32_t channels, uint32_t rate, void *user)
|
||||||
|
{
|
||||||
|
auto session = reinterpret_cast<StreamSession *>(user);
|
||||||
|
StreamSessionPrivate::InitAudio(session, channels, rate);
|
||||||
|
}
|
||||||
|
|
||||||
static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user)
|
static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user)
|
||||||
{
|
{
|
||||||
auto session = reinterpret_cast<StreamSession *>(user);
|
auto session = reinterpret_cast<StreamSession *>(user);
|
||||||
|
|
|
@ -118,6 +118,7 @@ typedef struct chiaki_event_t
|
||||||
} ChiakiEvent;
|
} ChiakiEvent;
|
||||||
|
|
||||||
typedef void (*ChiakiEventCallback)(ChiakiEvent *event, void *user);
|
typedef void (*ChiakiEventCallback)(ChiakiEvent *event, void *user);
|
||||||
|
typedef void (*ChiakiAudioSettingsCallback)(uint32_t channels, uint32_t rate, void *user);
|
||||||
typedef void (*ChiakiAudioFrameCallback)(int16_t *buf, size_t samples_count, void *user);
|
typedef void (*ChiakiAudioFrameCallback)(int16_t *buf, size_t samples_count, void *user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,8 +156,9 @@ typedef struct chiaki_session_t
|
||||||
|
|
||||||
ChiakiEventCallback event_cb;
|
ChiakiEventCallback event_cb;
|
||||||
void *event_cb_user;
|
void *event_cb_user;
|
||||||
|
ChiakiAudioSettingsCallback audio_settings_cb;
|
||||||
ChiakiAudioFrameCallback audio_frame_cb;
|
ChiakiAudioFrameCallback audio_frame_cb;
|
||||||
void *audio_frame_cb_user;
|
void *audio_cb_user;
|
||||||
ChiakiVideoSampleCallback video_sample_cb;
|
ChiakiVideoSampleCallback video_sample_cb;
|
||||||
void *video_sample_cb_user;
|
void *video_sample_cb_user;
|
||||||
|
|
||||||
|
@ -193,10 +195,11 @@ static inline void chiaki_session_set_event_cb(ChiakiSession *session, ChiakiEve
|
||||||
session->event_cb_user = user;
|
session->event_cb_user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void chiaki_session_set_audio_frame_cb(ChiakiSession *session, ChiakiAudioFrameCallback cb, void *user)
|
static inline void chiaki_session_set_audio_cb(ChiakiSession *session, ChiakiAudioSettingsCallback settings_cb, ChiakiAudioFrameCallback frame_cb, void *user)
|
||||||
{
|
{
|
||||||
session->audio_frame_cb = cb;
|
session->audio_settings_cb = settings_cb;
|
||||||
session->audio_frame_cb_user = user;
|
session->audio_frame_cb = frame_cb;
|
||||||
|
session->audio_cb_user = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void chiaki_session_set_video_sample_cb(ChiakiSession *session, ChiakiVideoSampleCallback cb, void *user)
|
static inline void chiaki_session_set_video_sample_cb(ChiakiSession *session, ChiakiVideoSampleCallback cb, void *user)
|
||||||
|
|
|
@ -95,6 +95,9 @@ CHIAKI_EXPORT void chiaki_audio_receiver_stream_info(ChiakiAudioReceiver *audio_
|
||||||
|
|
||||||
audio_receiver->pcm_buf_size = pcm_buf_size_required;
|
audio_receiver->pcm_buf_size = pcm_buf_size_required;
|
||||||
|
|
||||||
|
if(audio_receiver->session->audio_settings_cb)
|
||||||
|
audio_receiver->session->audio_settings_cb(audio_header->channels, audio_header->rate, audio_receiver->session->audio_cb_user);
|
||||||
|
|
||||||
beach:
|
beach:
|
||||||
chiaki_mutex_unlock(&audio_receiver->mutex);
|
chiaki_mutex_unlock(&audio_receiver->mutex);
|
||||||
}
|
}
|
||||||
|
@ -174,7 +177,7 @@ static void chiaki_audio_receiver_frame(ChiakiAudioReceiver *audio_receiver, Chi
|
||||||
if(r < 1)
|
if(r < 1)
|
||||||
CHIAKI_LOGE(audio_receiver->log, "Decoding audio frame with opus failed: %s", opus_strerror(r));
|
CHIAKI_LOGE(audio_receiver->log, "Decoding audio frame with opus failed: %s", opus_strerror(r));
|
||||||
else
|
else
|
||||||
audio_receiver->session->audio_frame_cb(audio_receiver->pcm_buf, (size_t)r, audio_receiver->session->audio_frame_cb_user);
|
audio_receiver->session->audio_frame_cb(audio_receiver->pcm_buf, (size_t)r, audio_receiver->session->audio_cb_user);
|
||||||
|
|
||||||
beach:
|
beach:
|
||||||
chiaki_mutex_unlock(&audio_receiver->mutex);
|
chiaki_mutex_unlock(&audio_receiver->mutex);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue