mirror of
https://github.com/rock88/moonlight-nx
synced 2025-02-16 12:38:29 +00:00
Add AudoutAudioRenderer
This commit is contained in:
parent
a82bc1dfaf
commit
9b8686cc7c
6 changed files with 149 additions and 3 deletions
1
Makefile
1
Makefile
|
@ -116,6 +116,7 @@ MOONLIGHT_LIBRETRO_CXX_SOURCES = \
|
|||
MbedTLSCryptoManager.cpp \
|
||||
mbedtls_to_openssl_wrapper.cpp \
|
||||
AudrenAudioRenderer.cpp \
|
||||
AudoutAudioRenderer.cpp \
|
||||
BoxArtManager.cpp
|
||||
|
||||
MOONLIGHT_COMMON_C_SOURCES = \
|
||||
|
|
|
@ -91,6 +91,8 @@
|
|||
36BFCCF32479723E00245D40 /* http.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36BFCCF02479723E00245D40 /* http.cpp */; };
|
||||
36BFCCF62479724A00245D40 /* GameStreamClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36BFCCF52479724900245D40 /* GameStreamClient.cpp */; };
|
||||
36BFCCF82479725900245D40 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36BFCCF72479725900245D40 /* main.cpp */; };
|
||||
36BFCCFC247AAF9B00245D40 /* AudoutAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36BFCCFA247AAF9B00245D40 /* AudoutAudioRenderer.cpp */; };
|
||||
36BFCCFD247ABB6100245D40 /* AudrenAudioRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36F16476247481F200D70AD9 /* AudrenAudioRenderer.cpp */; };
|
||||
36D3F8442469B5C400CDEF9B /* MoonlightSession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 36D3F8422469B5C400CDEF9B /* MoonlightSession.cpp */; };
|
||||
36DBDE9A2450BCD50057C8D3 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36DBDE992450BCD50057C8D3 /* CoreFoundation.framework */; };
|
||||
36DBDE9C2450BCD90057C8D3 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 36DBDE9B2450BCD90057C8D3 /* CoreGraphics.framework */; };
|
||||
|
@ -293,6 +295,8 @@
|
|||
36BFCCF42479724900245D40 /* GameStreamClient.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = GameStreamClient.hpp; sourceTree = "<group>"; };
|
||||
36BFCCF52479724900245D40 /* GameStreamClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GameStreamClient.cpp; sourceTree = "<group>"; };
|
||||
36BFCCF72479725900245D40 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
|
||||
36BFCCFA247AAF9B00245D40 /* AudoutAudioRenderer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AudoutAudioRenderer.cpp; sourceTree = "<group>"; };
|
||||
36BFCCFB247AAF9B00245D40 /* AudoutAudioRenderer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AudoutAudioRenderer.hpp; sourceTree = "<group>"; };
|
||||
36D3F8422469B5C400CDEF9B /* MoonlightSession.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MoonlightSession.cpp; sourceTree = "<group>"; };
|
||||
36D3F8432469B5C400CDEF9B /* MoonlightSession.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MoonlightSession.hpp; sourceTree = "<group>"; };
|
||||
36D3F8452469C6BC00CDEF9B /* Log.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Log.h; sourceTree = "<group>"; };
|
||||
|
@ -674,6 +678,8 @@
|
|||
3678EF722476D9DA0097345D /* DebugFileRecorderAudioRenderer.hpp */,
|
||||
36F16476247481F200D70AD9 /* AudrenAudioRenderer.cpp */,
|
||||
36F16477247481F200D70AD9 /* AudrenAudioRenderer.hpp */,
|
||||
36BFCCFA247AAF9B00245D40 /* AudoutAudioRenderer.cpp */,
|
||||
36BFCCFB247AAF9B00245D40 /* AudoutAudioRenderer.hpp */,
|
||||
36D3F8492469CC2600CDEF9B /* IAudioRenderer.hpp */,
|
||||
);
|
||||
path = audio;
|
||||
|
@ -873,6 +879,7 @@
|
|||
36A0C0372461DBA30083289C /* AddHostButton.cpp in Sources */,
|
||||
3652F06E245C292B001FABF3 /* rs.c in Sources */,
|
||||
3652EFD1245B3B00001FABF3 /* colorpicker.cpp in Sources */,
|
||||
36BFCCFC247AAF9B00245D40 /* AudoutAudioRenderer.cpp in Sources */,
|
||||
3652F066245C292B001FABF3 /* compress.c in Sources */,
|
||||
3652F07D245C292B001FABF3 /* Misc.c in Sources */,
|
||||
3652F070245C292B001FABF3 /* SimpleStun.c in Sources */,
|
||||
|
@ -936,6 +943,7 @@
|
|||
3652EFE5245B3B00001FABF3 /* theme.cpp in Sources */,
|
||||
367CD95A245DE25F00A95738 /* StreamWindow.cpp in Sources */,
|
||||
3652F07F245C292B001FABF3 /* LinkedBlockingQueue.c in Sources */,
|
||||
36BFCCFD247ABB6100245D40 /* AudrenAudioRenderer.cpp in Sources */,
|
||||
3652EFD2245B3B00001FABF3 /* textarea.cpp in Sources */,
|
||||
3652EFD5245B3B00001FABF3 /* canvas.cpp in Sources */,
|
||||
3652F078245C292B001FABF3 /* FakeCallbacks.c in Sources */,
|
||||
|
@ -1005,7 +1013,7 @@
|
|||
"\"$(SRCROOT)/third_party/moonlight-common-c/enet/include\"",
|
||||
"\"$(SRCROOT)/third_party/moonlight-common-c/src\"",
|
||||
"\"$(SRCROOT)/src/switch\"",
|
||||
/opt/devkitpro/libnx/include2,
|
||||
/opt/devkitpro/libnx/include,
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = /usr/local/lib;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
|
@ -1096,7 +1104,7 @@
|
|||
"\"$(SRCROOT)/third_party/moonlight-common-c/enet/include\"",
|
||||
"\"$(SRCROOT)/third_party/moonlight-common-c/src\"",
|
||||
"\"$(SRCROOT)/src/switch\"",
|
||||
/opt/devkitpro/libnx/include2,
|
||||
/opt/devkitpro/libnx/include,
|
||||
);
|
||||
LIBRARY_SEARCH_PATHS = /usr/local/lib;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.15;
|
||||
|
|
100
src/streaming/audio/AudoutAudioRenderer.cpp
Normal file
100
src/streaming/audio/AudoutAudioRenderer.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "AudoutAudioRenderer.hpp"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <inttypes.h>
|
||||
#include "Log.h"
|
||||
|
||||
AudoutAudioRenderer::AudoutAudioRenderer() {
|
||||
|
||||
}
|
||||
|
||||
AudoutAudioRenderer::~AudoutAudioRenderer() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
int AudoutAudioRenderer::init(int audio_configuration, const POPUS_MULTISTREAM_CONFIGURATION opus_config, void *context, int ar_flags) {
|
||||
m_channel_count = opus_config->channelCount;
|
||||
m_samples_datasize = m_channel_count * m_decoded_buffers_before_play * m_samples_per_frame * sizeof(s16);
|
||||
m_mempool_size = (m_samples_datasize + 0xFFF) &~ 0xFFF;
|
||||
|
||||
m_decoded_buffer = (s16 *)malloc(m_samples_datasize);
|
||||
mempool_ptr = memalign(0x1000, m_mempool_size);
|
||||
|
||||
if (m_decoded_buffer == NULL || mempool_ptr == NULL) {
|
||||
LOG_FMT("Failed to allocate buffers\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
Result rc = audoutInitialize();
|
||||
LOG_FMT("audoutInitialize() returned 0x%x\n", rc);
|
||||
|
||||
int error;
|
||||
m_decoder = opus_multistream_decoder_create(opus_config->sampleRate, opus_config->channelCount, opus_config->streams, opus_config->coupledStreams, opus_config->mapping, &error);
|
||||
|
||||
return DR_OK;
|
||||
}
|
||||
|
||||
void AudoutAudioRenderer::cleanup() {
|
||||
if (m_decoder) {
|
||||
opus_multistream_decoder_destroy(m_decoder);
|
||||
m_decoder = nullptr;
|
||||
}
|
||||
|
||||
if (m_decoded_buffer) {
|
||||
free(m_decoded_buffer);
|
||||
m_decoded_buffer = nullptr;
|
||||
}
|
||||
|
||||
if (mempool_ptr) {
|
||||
free(mempool_ptr);
|
||||
mempool_ptr = nullptr;
|
||||
}
|
||||
|
||||
audoutStopAudioOut();
|
||||
audoutExit();
|
||||
}
|
||||
|
||||
void AudoutAudioRenderer::decode_and_play_sample(char *data, int length) {
|
||||
s16* ptr = &m_decoded_buffer[m_current_frame * m_samples_per_frame * m_channel_count];
|
||||
int decoded_samples = opus_multistream_decode(m_decoder, (const unsigned char *)data, length, ptr, m_samples_per_frame, 0);
|
||||
|
||||
if (decoded_samples > 0) {
|
||||
m_current_frame++;
|
||||
m_total_decoded_samples += decoded_samples;
|
||||
|
||||
if (m_current_frame < m_decoded_buffers_before_play) {
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(mempool_ptr, m_decoded_buffer, m_samples_datasize);
|
||||
armDCacheFlush(mempool_ptr, (m_samples_datasize + 0xFFF) &~ 0xFFF);
|
||||
|
||||
audoutStopAudioOut();
|
||||
|
||||
// Prepare the audio data source buffer.
|
||||
audout_buf.next = NULL;
|
||||
audout_buf.buffer = mempool_ptr;
|
||||
audout_buf.buffer_size = m_mempool_size;
|
||||
audout_buf.data_size = m_samples_datasize;
|
||||
audout_buf.data_offset = 0;
|
||||
|
||||
// Prepare pointer for the released buffer.
|
||||
audout_released_buf = NULL;
|
||||
|
||||
// Play the buffer.
|
||||
audoutStartAudioOut();
|
||||
Result rc = audoutPlayBuffer(&audout_buf, &audout_released_buf);
|
||||
|
||||
if (R_FAILED(rc))
|
||||
LOG_FMT("audoutPlayBuffer() returned 0x%x\n", rc);
|
||||
|
||||
m_current_frame = 0;
|
||||
m_total_decoded_samples = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int AudoutAudioRenderer::capabilities() {
|
||||
return CAPABILITY_DIRECT_SUBMIT;
|
||||
}
|
31
src/streaming/audio/AudoutAudioRenderer.hpp
Normal file
31
src/streaming/audio/AudoutAudioRenderer.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
#include "IAudioRenderer.hpp"
|
||||
#include <opus/opus_multistream.h>
|
||||
#include <switch.h>
|
||||
#pragma once
|
||||
|
||||
class AudoutAudioRenderer: public IAudioRenderer {
|
||||
public:
|
||||
AudoutAudioRenderer();
|
||||
~AudoutAudioRenderer();
|
||||
|
||||
int init(int audio_configuration, const POPUS_MULTISTREAM_CONFIGURATION opus_config, void *context, int ar_flags) override;
|
||||
void cleanup() override;
|
||||
void decode_and_play_sample(char *sample_data, int sample_length) override;
|
||||
int capabilities() override;
|
||||
|
||||
private:
|
||||
OpusMSDecoder* m_decoder = nullptr;
|
||||
s16* m_decoded_buffer = nullptr;
|
||||
void* mempool_ptr = nullptr;
|
||||
|
||||
AudioOutBuffer audout_buf;
|
||||
AudioOutBuffer *audout_released_buf;
|
||||
|
||||
int m_channel_count = 0;
|
||||
int m_samples_per_frame = AUDREN_SAMPLES_PER_FRAME_48KHZ;
|
||||
const int m_decoded_buffers_before_play = 20; // Small value for lower delay...
|
||||
int m_mempool_size = 0, m_samples_datasize = 0;
|
||||
|
||||
int m_current_frame = 0;
|
||||
s32 m_total_decoded_samples = 0;
|
||||
};
|
|
@ -33,6 +33,11 @@ int AudrenAudioRenderer::init(int audio_configuration, const POPUS_MULTISTREAM_C
|
|||
m_decoded_buffer = (s16 *)malloc(m_samples_datasize);
|
||||
mempool_ptr = memalign(0x1000, mempool_size);
|
||||
|
||||
if (m_decoded_buffer == NULL || mempool_ptr == NULL) {
|
||||
LOG_FMT("Failed to allocate buffers\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int error;
|
||||
m_decoder = opus_multistream_decoder_create(opus_config->sampleRate, opus_config->channelCount, opus_config->streams, opus_config->coupledStreams, opus_config->mapping, &error);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "GLVideoRenderer.hpp"
|
||||
#ifdef __SWITCH__
|
||||
#include "AudrenAudioRenderer.hpp"
|
||||
#include "AudoutAudioRenderer.hpp"
|
||||
#endif
|
||||
#include "DebugFileRecorderAudioRenderer.hpp"
|
||||
#include "nanovg.h"
|
||||
|
@ -21,7 +22,7 @@ StreamWindow::StreamWindow(Widget *parent, const std::string &address, int app_i
|
|||
m_session->set_video_renderer(new GLVideoRenderer());
|
||||
|
||||
#ifdef __SWITCH__
|
||||
m_session->set_audio_renderer(new AudrenAudioRenderer());
|
||||
m_session->set_audio_renderer(new AudoutAudioRenderer());
|
||||
#else
|
||||
m_session->set_audio_renderer(new DebugFileRecorderAudioRenderer(false));
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue