From 5c13eca700df1c0ecb2c666ed0f5e7ce9526671b Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Thu, 6 Dec 2018 07:49:07 -0500 Subject: [PATCH] audio_core/lle: implement PipeRead/GetPipeReadableSize --- src/audio_core/lle/lle.cpp | 55 ++++++++++++++++++++++++++++++++++++++ src/audio_core/lle/lle.h | 2 ++ 2 files changed, 57 insertions(+) diff --git a/src/audio_core/lle/lle.cpp b/src/audio_core/lle/lle.cpp index 0f6c7a8bbe..7ead44e823 100644 --- a/src/audio_core/lle/lle.cpp +++ b/src/audio_core/lle/lle.cpp @@ -102,6 +102,53 @@ struct DspLle::Impl final { teakra.SendData(2, pipe_status.slot_index); } } + + std::vector ReadPipe(u8 pipe_index, u16 bsize) { + PipeStatus pipe_status = GetPipeStatus(pipe_index, PipeDirection::DSPtoCPU); + bool need_update = false; + std::vector data(bsize); + u8* buffer_ptr = data.data(); + while (bsize != 0) { + u16 x = pipe_status.read_bptr ^ pipe_status.write_bptr; + ASSERT_MSG(x != 0, "Pipe is empty"); + u16 read_bend; + if (x >= 0x8000) { + read_bend = pipe_status.bsize; + } else { + read_bend = pipe_status.write_bptr & 0x7FFF; + } + u16 read_bbegin = pipe_status.read_bptr & 0x7FFF; + ASSERT(read_bend > read_bbegin); + u16 read_bsize = std::min(bsize, read_bend - read_bbegin); + std::memcpy(buffer_ptr, GetDspDataPointer(pipe_status.waddress * 2 + read_bbegin), + read_bsize); + buffer_ptr += read_bsize; + pipe_status.read_bptr += read_bsize; + bsize -= read_bsize; + ASSERT_MSG((pipe_status.read_bptr & 0x7FFF) <= pipe_status.bsize, + "Pipe is in inconsistent state: read > size"); + if ((pipe_status.read_bptr & 0x7FFF) == pipe_status.bsize) { + pipe_status.read_bptr &= 0x8000; + pipe_status.read_bptr ^= 0x8000; + } + need_update = true; + } + if (need_update) { + UpdatePipeStatus(pipe_status); + while (!teakra.SendDataIsEmpty(2)) + RunTeakraSlice(); + teakra.SendData(2, pipe_status.slot_index); + } + return data; + } + u16 GetPipeReadableSize(u8 pipe_index) { + PipeStatus pipe_status = GetPipeStatus(pipe_index, PipeDirection::DSPtoCPU); + u16 size = pipe_status.write_bptr - pipe_status.read_bptr; + if ((pipe_status.read_bptr ^ pipe_status.write_bptr) >= 0x8000) { + size += pipe_status.bsize; + } + return size & 0x7FFF; + } }; u16 DspLle::RecvData(u32 register_number) { @@ -119,6 +166,14 @@ void DspLle::SetSemaphore(u16 semaphore_value) { impl->teakra.SetSemaphore(semaphore_value); } +std::vector DspLle::PipeRead(DspPipe pipe_number, u32 length) { + return impl->ReadPipe(static_cast(pipe_number), static_cast(length)); +} + +std::size_t DspLle::GetPipeReadableSize(DspPipe pipe_number) const { + return impl->GetPipeReadableSize(static_cast(pipe_number)); +} + void DspLle::PipeWrite(DspPipe pipe_number, const std::vector& buffer) { impl->WritePipe(static_cast(pipe_number), buffer); } diff --git a/src/audio_core/lle/lle.h b/src/audio_core/lle/lle.h index 9b282dcb68..5a343d4963 100644 --- a/src/audio_core/lle/lle.h +++ b/src/audio_core/lle/lle.h @@ -16,6 +16,8 @@ public: u16 RecvData(u32 register_number) override; bool RecvDataIsReady(u32 register_number) const override; void SetSemaphore(u16 semaphore_value) override; + std::vector PipeRead(DspPipe pipe_number, u32 length) override; + std::size_t GetPipeReadableSize(DspPipe pipe_number) const override; void PipeWrite(DspPipe pipe_number, const std::vector& buffer) override; private: