Commit Graph
28 Commits
Author SHA1 Message Date
Henrik RydgårdandClaude Opus 5 000af25d81 sceAudio: split the SRC channel out, and stop rescheduling mid-syscall
The nine channels were one array of one struct, but only index 8 ever used the
two DMA descriptors, the played/fraction position and the waiting-thread vector,
and only 0-7 ever used the buffer slot - so eight copies of a std::vector sat
there dead. They are two different pieces of hardware and now they are two
structs: AudioChannel for the eight the mixer walks, and a single AudioSRCChannel
for the one the codec reads directly.

Found while rereading it:

- __AudioUpdate can now run from inside an output call, and it reschedules when
  it wakes a thread. A context switch there lands before the syscall writes its
  return value, so the caller loses it and the woken thread gets it instead.
  Deferred with hleReSchedule when a syscall is in flight. The same fix applies
  to the release path, which had the problem before this branch existed.
- A finished SRC buffer whose waiting thread had given up dropped the completion
  entirely, so the next caller waited a buffer too long. Now it walks past dead
  waiters and banks the completion if nobody is left.
- An output with a null pointer changed the channel volume, where the hardware
  returns before touching it.
- A busy channel came back as an error from the Output2 path and as debug from
  the mixer path. It is an ordinary answer a game polls on, so both are debug
  now; the old behavior filled the log with 18k error lines in a minute of F1
  2009.
- AudioChannel::reset had no callers left: releasing a channel with a thread
  parked on it is refused, so there is nobody to wake.
- The two routing modes are globals and were written once per channel. They get
  their own small savestate block.

Savestate: the sceAudio section goes to 3, and the SRC channel gets a section of
its own. States from released builds carry it as a ninth channel record, which is
read and discarded.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 17:03:07 -06:00
Henrik RydgårdandClaude Opus 5 ac50cd5759 sceAudio: model the real buffering, so contending threads get told "busy"
I deduced that this was the case, and attempted implementing this path long ago,
but I could never quite get it to work in all games. Set Claude on a quest to
research and implement it, and lo and behold, it works. A bit sobering.

Fixes #12888 and likely more. Additionally, audio latency is likely slightly
improved overall, and memory usage is down by 4.6MB.

Claude says:

The blocking output calls are not a queue that callers line up behind. Each
mixer channel holds exactly one buffer and at most one parked thread; a second
thread arriving while the first is waiting is told the channel is busy and is
expected to skip its turn. The Output2/SRC channel holds two DMA descriptors and
refuses a third caller outright, without waiting at all.

We blocked everyone instead, so a game running a movie thread and a sound-effect
thread over one output made the two alternate - a frame of movie audio, a frame
of effects silence - and the movie played at half rate. That is #12888, seen in
F1 2009 and Colin McRae: DiRT 2. With this, the movie thread keeps the channel
for the whole cutscene and the effects thread is refused, which is what the
hardware trace shows.

The driver also never copies a buffer on the way in: it stores the pointer and
its mixer walks it forward 64 samples at a time out of the game's own memory.
Modelling that fixes #20095 as a side effect, and drops the 4.6MB of per-channel
sample rings we were carrying. The mix event is re-phased to the moment a DMA
starts, since the mixer thread outranks its caller and gets a block in before the
output call returns.

Along the way: the two rest-length calls differ after a null-pointer output,
sceAudioChRelease reports not-reserved rather than not-init,
sceAudioChangeChannelConfig validates the format,
sceAudioChangeChannelVolume validates nothing, and sceAudioOutput2ChangeLength
takes a range of 17..4111. Details in docs/sceAudio.md.

Savestates: AudioChannel goes to version 4. Older ones stored mixed samples that
can't become a pointer and a position again, so they load with the pending audio
dropped and any parked threads released.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-10 17:03:07 -06:00
Henrik RydgårdandClaude Opus 5 fd72f308af sceAudio: fix a crash when reserving a channel with none free
GetFreeChannel counted down with an unsigned loop variable, so i >= 0
was always true. With every channel already reserved it wrapped past
zero and kept indexing g_audioChans until it walked off the end -
sceAudioChReserve(-1, ...) segfaulted the emulator instead of returning
"no channels available". Reproduces on audio/sceaudio/reserve, which
crashed before printing anything.

Also gives sceVaudioChReserve the parameter checks it never had. It
took any sample count, channel count and frequency; the hardware allows
256, 1024 or 2048 samples, stereo only, and the same sample rates the
SRC channel accepts. Every value in the test now matches - what's left
there is only reschedule markers.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JvJR8oJNSCimCM9KXVLjfq
2026-09-04 18:12:31 -06:00
Henrik Rydgård d9eab4e4a2 sceAudio: Add per-channel mute checkboxes in the debugger 2025-04-15 11:44:28 +02:00
Henrik Rydgård af30c04711 Rename 'chans' to g_audioChans 2025-04-15 11:18:53 +02:00
Henrik Rydgård b2b0ff1753 Consolidate error codes in ErrorCodes.h 2025-02-04 11:53:00 -06:00
Henrik Rydgård 27c059bf9e Really no need to call clear() in the constructor for AudioChannel.
However if this helps #13271, something is very wrong...
2020-08-12 00:22:54 +02:00
Unknown W. Brackets 4c46867230 Audio: Avoid exposing fixed size queue in header. 2020-08-10 08:03:44 +00:00
kaienfr e25bc6908a Fix nonsmooth sound issue and incomplete frame at the end of source and pcm buffers.
using a std::string to save the source buffer, and changing the loading strategy so as we will not get any incomplete frame.
2014-04-12 23:16:38 +02:00
kaienfr 3a12cf2ad7 Universal Audio Class
Based on my implementation in sceAac https://github.com/hrydgard/ppsspp/pull/5836
I've created a class AuCtx included in My SimpleAudioDec.cpp/.h which aims at providing a standard easy implementation to support all codecs in ffmpeg.
Here, I also completely re-code sceMp3 file with this class to give an example how to use this class, and it has solved all mp3 issues I've observed in the current master.
Tests on different freq and channels mp3 audios as:
Miku custom BGM (48kHz, stereo), Hanayaka Nari Wa ga Ichizoku(32kHz, mono, a little fast but better than before now), downstreet panic (44.1kHz, stereo), and learn jp09(44.1kHz, stero) are just all right.
Especially, I am very glad to see that Miku's Custom BGMs have no repetition issues in first tone any more and no longer stopped in the first second neither. :)
We will come into a new age to fast support new audio formats from now on I hope :P
2014-04-11 22:56:59 +02:00
lioncash b9886942a7 Fix some vertical alignments in misc Core source files. 2014-03-03 11:16:53 -05:00
Unknown W. Brackets 06c19622d5 Fix some init/type warnings. 2013-05-31 23:14:29 -07:00
Unknown W. Brackets 839ff0a795 Correctly reset audio channels on shutdown.
Fixes #1876.
2013-05-21 00:59:05 -07:00
Unknown W. Brackets d4f3137a2c Don't overlay Vaudio with multichannel.
It seems to share living space with Output2/SRC.
2013-05-19 15:46:24 -07:00
Unknown W. Brackets 2bab76a940 Block audio output more correctly.
Still with the same thresholds, so hopefully it won't hurt sync.
2013-05-19 12:31:47 -07:00
Unknown W. Brackets 0ab30ecb07 Use a separate channel for SRC/Output2.
Tests on the PSP show that all 8 channels can be reserved/used at the
same time as *either* Output2 or SRC (but SRC and Output2 cannot be used
at the same time.)
2013-05-16 01:12:39 -07:00
raven02 d07bd499a7 Add SCE_ERROR_AUDIO_INVALID_VOLUME 2013-04-16 15:48:17 +08:00
raven02 c0a49c1603 Add ERROR_AUDIO_INVALID_FREQUENCY/CHANNEL_ALREADY_RESERVED 2013-03-30 23:55:49 +08:00
Unknown W. Brackets 2a6457b6ab Cut down on h files including PointerWrap.
This makes changes to it a bit faster to build.
2013-02-04 08:26:59 -08:00
Henrik Rydgard d1b3fd0e49 Better window resize handling 2013-01-27 00:15:39 +01:00
raven02 faaa837ca2 Use u32 for leftVolume/rightVolume/format 2013-01-24 23:31:30 +08:00
Unknown W. Brackets 19aaca2705 Start save stating audio, plus minor fixes. 2012-12-28 13:55:29 -08:00
raven02 2bdaaba2ab Change MAX_CHANNEL to PSP_AUDIO_CHANNEL_MAX 2012-12-24 01:00:43 +08:00
Henrik Rydgard 9acfd50139 Fix one cause of audio choppiness - we were dropping samples when audio functions blocked. Also some cleanup. 2012-12-17 20:15:23 +01:00
Henrik Rydgard 7720dc3f60 Various warning, logging, jit fixes 2012-11-17 19:56:28 +01:00
Henrik Rydgard 5a48578a12 Rewrite audio line output. Now deterministic (from the game's POV) and smoother. 2012-11-17 14:20:59 +01:00
Henrik Rydgard 64cc573703 Switch to "GPL 2.0 or later" for various reasons. I wrote most of the code I imported from Dolphin (which is GPL2-but-not-later), so it should be OK. 2012-11-04 23:24:00 +01:00
Henrik Rydgard 4f7ad15758 Add snapshot of the whole source code. 2012-11-01 16:19:01 +01:00