Skip to content

Commit

Permalink
wii u: static stereo audio works now
Browse files Browse the repository at this point in the history
  • Loading branch information
TurtleP committed Apr 15, 2024
1 parent 482158d commit 827e047
Show file tree
Hide file tree
Showing 20 changed files with 210 additions and 102 deletions.
1 change: 0 additions & 1 deletion include/modules/audio/Source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ namespace love
AudioBuffer buffer;
AudioBuffer _clone;

int16_t* data;
size_t size;
int nsamples;
};
Expand Down
3 changes: 2 additions & 1 deletion include/modules/filesystem/File.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include "common/Map.hpp"

#include <cstring>
#include <string_view>

namespace love
Expand Down Expand Up @@ -112,7 +113,7 @@ namespace love
{
// clang-format off
StrongRef<FileData> temp(new FileData(bytesRead, this->getFilename()), Acquire::NO_RETAIN);
std::copy_n((const uint8_t*)data->getData(), (size_t)bytesRead, (uint8_t*)temp->getData());
std::memcpy(temp->getData(), data->getData(), bytesRead);
// clang-format on

data = temp;
Expand Down
33 changes: 24 additions & 9 deletions platform/cafe/include/driver/audio/AudioBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#include <sndcore2/voice.h>

#include <algorithm>

#include <array>
#include <vector>

namespace love
{
Expand All @@ -19,15 +21,17 @@ namespace love

AudioBuffer(const AudioBuffer&) = delete;

AudioBuffer(AudioBuffer&& other) noexcept
AudioBuffer(AudioBuffer&& other)
{
this->voices = std::move(other.voices);
this->channels = other.channels;
this->ready = other.ready;
this->data = other.data;
this->nsamples = other.nsamples;

other.ready = false;
this->data_pcm16 = std::move(other.data_pcm16);
this->nsamples = other.nsamples;
this->voices = std::move(other.voices);
this->channels = other.channels;
this->ready = other.ready;
this->playing = other.playing;

other.ready = false;
other.playing = false;
}

~AudioBuffer();
Expand Down Expand Up @@ -64,8 +68,18 @@ namespace love

bool isLooping() const;

int getChannelCount() const
{
return this->channels;
}

void setChannelCount(int channels)
{
this->channels = channels;
}

public:
int16_t* data;
std::array<int16_t*, 2> data_pcm16;
size_t nsamples;

private:
Expand All @@ -78,5 +92,6 @@ namespace love
int channels;

bool ready;
bool playing;
};
} // namespace love
20 changes: 13 additions & 7 deletions platform/cafe/include/driver/audio/DigitalSound.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ namespace love
class DigitalSound : public DigitalSoundBase<DigitalSound>
{
public:
enum InterpType
{
CHANNEL_MONO,
CHANNEL_STEREO
};

~DigitalSound();

virtual void initialize() override;
Expand All @@ -33,7 +27,7 @@ namespace love

float getMasterVolume() const;

AudioBuffer createBuffer(int channels);
AudioBuffer createBuffer(int size, int channels);

void freeBuffer(const AudioBuffer& buffer);

Expand Down Expand Up @@ -65,6 +59,17 @@ namespace love

static int32_t getFormat(int channels, int bitDepth);

OSEvent& getEvent()
{
return this->event;
}

void updateChannels()
{
for (auto& channel : this->channels)
channel.update();
}

// clang-format off
ENUMMAP_DECLARE(AudioFormats, EncodingFormat, AX_VOICE_FORMAT,
{ ENCODING_PCM8, AX_VOICE_FORMAT_LPCM8 },
Expand All @@ -74,5 +79,6 @@ namespace love

private:
std::array<SoundChannel, 24> channels;
OSEvent event;
};
} // namespace love
11 changes: 8 additions & 3 deletions platform/cafe/include/driver/audio/SoundChannel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ namespace love
void reset();

/**
** @brief Sets the interpolation type of the channel.
** @param channels The interpolation type to set.
** @brief Sets the interpolation type (stereo or mono) of the channel.
** @param channels The number of channels for the interpolation type.
*/
void setInterpType(int channels);

/*
** @brief Gets the interpolation type of the channel.
** @return The interpolation type of the channel.
** @return The interpolation channel count of the channel.
*/
int getInterpType() const;

Expand Down Expand Up @@ -100,6 +100,11 @@ namespace love
*/
bool isPlaying() const;

/*
** @brief Plays the buffer at the front of the queue.
*/
void play();

/*
** @brief Stops the buffer at the front of the queue.
** This also pops the buffers from the queue.
Expand Down
60 changes: 38 additions & 22 deletions platform/cafe/source/driver/audio/AudioBuffer.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
#include "driver/audio/AudioBuffer.hpp"
#include "driver/audio/DigitalSoundMix.hpp"

#include <cstring>

namespace love
{
AudioBuffer::AudioBuffer() : data(nullptr), nsamples(0), voices {}, ready(false)
AudioBuffer::AudioBuffer() :
data_pcm16 { nullptr, nullptr },
nsamples(0),
voices {},
ready(false)
{}

AudioBuffer::~AudioBuffer()
Expand All @@ -21,14 +27,14 @@ namespace love
{
this->voices[index] = AXAcquireVoice(0x1F, nullptr, nullptr);

if (!this->voices[index])
throw love::Exception("Failed to acquire Voice.");

AXVoiceBegin(this->voices[index]);
AXSetVoiceType(this->voices[index], AX_VOICE_TYPE_UNKNOWN);
AXVoiceEnd(this->voices[index]);
}

if (channels == 2 && !this->voices.back())
throw love::Exception("Stereo voices require 2 voices to be available.");

this->channels = channels;
this->ready = true;
}
Expand All @@ -38,25 +44,25 @@ namespace love
if (!this->ready)
return false;

if (!this->data || !this->nsamples)
if (!this->data_pcm16[0])
return false;

if (!this->data_pcm16[1] && this->channels == 2)
return false;

for (int index = 0; index < this->channels; index++)
{
AXVoiceBegin(this->voices[index]);

AXSetVoiceState(this->voices[index], AX_VOICE_STATE_STOPPED);

AXVoiceOffsets offsets {};
AXGetVoiceOffsets(this->voices[index], &offsets);

offsets.currentOffset = 0;
offsets.endOffset = this->nsamples;
offsets.loopOffset = 0;
offsets.data = this->data;
offsets.data = this->data_pcm16[index];

AXSetVoiceOffsets(this->voices[index], &offsets);
AXSetVoiceCurrentOffset(this->voices[index], 0);

AXVoiceEnd(this->voices[index]);
}
Expand Down Expand Up @@ -101,11 +107,12 @@ namespace love
for (int index = 0; index < this->channels; index++)
{
AXVoiceBegin(this->voices[index]);

AXSetVoiceState(this->voices[index], state);

AXVoiceEnd(this->voices[index]);
}

this->playing = (state == AX_VOICE_STATE_PLAYING);
}

bool AudioBuffer::setFormat(AXVoiceFormat format)
Expand Down Expand Up @@ -137,23 +144,26 @@ namespace love
if (!this->ready)
return false;

AXVoiceBegin(this->voices[0]);
if (!this->playing)
return true;

bool done = this->voices[0]->state == AX_VOICE_STATE_STOPPED;
AXVoiceOffsets offsets {};

AXVoiceEnd(this->voices[0]);
bool running = false;

return done == true;
AXGetVoiceOffsets(this->voices[0], &offsets);
running = AXIsVoiceRunning(this->voices[0]);

return (offsets.currentOffset == offsets.endOffset) ||
(!running && offsets.currentOffset == 0);
}

void AudioBuffer::setVolume(float volume)
{
volume = std::clamp(volume, 0.0f, 1.0f);

AXVoiceVeData ve {
.volume = 0x8000,
.delta = 0,
};
AXVoiceVeData ve {};
ve.volume = volume * 0x8000;

for (int index = 0; index < this->channels; index++)
{
Expand All @@ -172,7 +182,7 @@ namespace love
{
AXVoiceBegin(this->voices[index]);

auto result = AXSetVoiceSrcRatio(this->voices[index], ratio);
AXSetVoiceSrcRatio(this->voices[index], ratio);
AXSetVoiceSrcType(this->voices[index], AX_VOICE_SRC_TYPE_LINEAR);

AXVoiceEnd(this->voices[index]);
Expand All @@ -183,17 +193,20 @@ namespace love

size_t AudioBuffer::getSampleOffset() const
{
AXVoiceOffsets offsets {};
if (!this->ready || !this->playing)
return 0;

AXVoiceBegin(this->voices[0]);
AXVoiceOffsets offsets {};
AXGetVoiceOffsets(this->voices[0], &offsets);
AXVoiceEnd(this->voices[0]);

return offsets.currentOffset;
}

void AudioBuffer::setLooping(bool looping)
{
if (!this->ready)
return;

for (int index = 0; index < this->channels; index++)
{
AXVoiceBegin(this->voices[index]);
Expand All @@ -211,6 +224,9 @@ namespace love

bool AudioBuffer::isLooping() const
{
if (!this->ready)
return false;

AXVoiceOffsets offsets {};

AXVoiceBegin(this->voices[0]);
Expand Down
Loading

0 comments on commit 827e047

Please sign in to comment.