Support all audio formats

This commit is contained in:
Robin Davies
2022-10-12 14:31:34 -04:00
parent 914b9c0f2c
commit 5fd84b9aa9
7 changed files with 366 additions and 15 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ project(pipedal
DESCRIPTION "PiPedal Guitar Effect Pedal For Raspberry Pi"
HOMEPAGE_URL "https://rerdavies.github.io/pipedal"
)
set (DISPLAY_VERSION "v1.0.16")
set (DISPLAY_VERSION "v1.0.17")
set (CMAKE_INSTALL_PREFIX "/usr/")
@@ -86,7 +86,7 @@ set(CPACK_DEBIAN_PACKAGE_SECTION sound)
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
#set(CPACK_DEBIAN_PACKAGE_DEPENDS "jackd2, hostapd, dnsmasq" )
set(CPACK_DEBIAN_PACKAGE_DEPENDS "hostapd, dnsmasq authbind" )
set(CPACK_DEBIAN_PACKAGE_DEPENDS "hostapd, dnsmasq, authbind" )
#set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
set(CPACK_PACKAGING_INSTALL_PREFIX /usr)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
+1 -1
View File
@@ -1,7 +1,7 @@
<img src='docs/GithubBanner.png' width="100%" /><br/>
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.0.16</a>
Download: <a href='https://rerdavies.github.io/pipedal/download.html'>v1.0.17</a>
Website: [https://rerdavies.github.io/pipedal](https://rerdavies.github.io/pipedal).
+2 -2
View File
@@ -1,5 +1,5 @@
Architecture: arm64
Depends: libstdc++6 (>= 9), libasound2 (>= 1.0.16), libc6 (>= 2.34), libgcc-s1 (>= 4.0), libjack-jackd2-0 (>= 1.9.10+20150825) | libjack-0.125, liblilv-0-0 (>= 0.22.0~dfsg0), libnl-3-200 (>= 3.2.7), libnl-genl-3-200 (>= 3.2.7), libstdc++6 (>= 11), libsystemd0
Depends: libstdc++6 (>= 9), libasound2 (>= 1.0.17), libc6 (>= 2.34), libgcc-s1 (>= 4.0), libjack-jackd2-0 (>= 1.9.10+20150825) | libjack-0.125, liblilv-0-0 (>= 0.22.0~dfsg0), libnl-3-200 (>= 3.2.7), libnl-genl-3-200 (>= 3.2.7), libstdc++6 (>= 11), libsystemd0
Description: IoT guitar effect for Raspberry Pi
IoT guitar effect pedal for Raspberry Pi, with phone-friendly web interface.
Homepage: https://github.com/rerdavies/pipedal
@@ -9,6 +9,6 @@ Package: pipedal
Pre-Depends: hostapd;authbind
Priority: optional
Section: sound
Version: 1.0.16
Version: 1.0.17
Installed-Size: 15147
+2 -2
View File
@@ -13,14 +13,14 @@ page_icon: img/Install4.jpg
Download the most recent Debian (.deb) package for your platform:
- [Ubuntu/Raspberry Pi OS (64-bit) v1.0.16](https://github.com/rerdavies/pipedal/releases/download/v1.0.16/pipedal_1.0.16_arm64.deb)
- [Ubuntu/Raspberry Pi OS (64-bit) v1.0.17](https://github.com/rerdavies/pipedal/releases/download/v1.0.17/pipedal_1.0.17_arm64.deb)
Install the package by running
```
sudo apt update
cd ~/Downloads
sudo dpkg --install pipedal_1.0.16_arm64.deb
sudo dpkg --install pipedal_1.0.17_arm64.deb
```
On Raspberry Pi OS, if you have a graphical desktop installed, you can also install the package by double-clicking on the downloaded package in the File Manager.
+2 -2
View File
@@ -4,14 +4,14 @@
Download the most recent Debian (.deb) package for your platform:
- [Ubuntu or Raspberry Pi OS (64-bit)](https://github.com/rerdavies/pipedal/releases/download/v1.0.16/pipedal_1.0.16_arm64.deb) v1.0.16
- [Ubuntu or Raspberry Pi OS (64-bit)](https://github.com/rerdavies/pipedal/releases/download/v1.0.17/pipedal_1.0.17_arm64.deb) v1.0.17
Install the package by running
```
sudo apt update
cd ~/Downloads
sudo apt-get install ./pipedal_1.0.16_arm64.deb
sudo apt-get install ./pipedal_1.0.17_arm64.deb
```
Follow the instructions in [_Configuring PiPedal After Installation_](https://rerdavies.github.io/pipedal/Configuring.html) to complete the installation.
+1 -1
View File
@@ -1,7 +1,7 @@
<img src="GithubBanner.png" width="100%"/>
<a href="Installing.html"><i>v1.0.16</i></a>
<a href="Installing.html"><i>v1.0.17</i></a>
&nbsp;
+356 -5
View File
@@ -88,17 +88,17 @@ namespace pipedal
static AudioFormat leFormats[]{
{"32-bit float little-endian", SND_PCM_FORMAT_FLOAT_LE},
{"24-bit little-endian in 3bytes format", SND_PCM_FORMAT_S24_3LE},
{"32-bit integer little-endian", SND_PCM_FORMAT_S32_LE},
{"24-bit little-endian", SND_PCM_FORMAT_S24_LE},
{"24-bit little-endian in 3bytes format", SND_PCM_FORMAT_S24_3LE},
{"16-bit little-endian", SND_PCM_FORMAT_S16_LE},
};
static AudioFormat beFormats[]{
{"32-bit float big-endian", SND_PCM_FORMAT_FLOAT_BE},
{"24-bit big-endian in 3bytes format", SND_PCM_FORMAT_S24_3BE},
{"32-bit integer big-endian", SND_PCM_FORMAT_S32_BE},
{"24-bit big-endian", SND_PCM_FORMAT_S24_BE},
{"24-bit big-endian in 3bytes format", SND_PCM_FORMAT_S24_3BE},
{"16-bit big-endian", SND_PCM_FORMAT_S16_BE},
};
@@ -491,6 +491,47 @@ namespace pipedal
snd_pcm_dump(playbackHandle, snd_output);
#endif
}
int32_t EndianSwap(int32_t v)
{
int32_t b0 = v & 0xFF;
int32_t b1 = (v >> 8) & 0xFF;
int32_t b2 = (v >> 16) & 0xFF;
int32_t b3 = (v >> 24) & 0xFF;
return (b0 << 24) | (b1 << 16) | (b2 << 8) | (b3);
}
int16_t EndianSwap(int16_t v)
{
int16_t b0 = v & 0xFF;
int16_t b1 = (v >> 8) & 0xFF;
return (b0 << 8) | (b1);
}
void EndianSwap(float*p,float v_)
{
int32_t v = EndianSwap(*(int32_t*)&v_);
*(int32_t*)p = v;
}
void CopyCaptureFloatBe(size_t frames)
{
int32_t *p = (int32_t *)rawCaptureBuffer;
std::vector<float *> &buffers = this->captureBuffers;
int channels = this->captureChannels;
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
int32_t v = EndianSwap(*p);
++p;
*(int32_t*)(buffers[channel]+frame) = v;
}
}
}
void CopyCaptureFloatLe(size_t frames)
{
float *p = (float *)rawCaptureBuffer;
@@ -507,6 +548,39 @@ namespace pipedal
}
}
void CopyCaptureS16Le(size_t frames)
{
int16_t *p = (int16_t *)rawCaptureBuffer;
std::vector<float *> &buffers = this->captureBuffers;
int channels = this->captureChannels;
constexpr float scale = 1.0f / (std::numeric_limits<int16_t>::max() + 1L);
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
int16_t v = *p++;
buffers[channel][frame] = scale * v;
}
}
}
void CopyCaptureS16Be(size_t frames)
{
int16_t *p = (int16_t *)rawCaptureBuffer;
std::vector<float *> &buffers = this->captureBuffers;
int channels = this->captureChannels;
constexpr float scale = 1.0f / (std::numeric_limits<int16_t>::max() + 1L);
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
int16_t v = EndianSwap(*p++);
buffers[channel][frame] = scale * v;
}
}
}
void CopyCaptureS32Le(size_t frames)
{
int32_t *p = (int32_t *)rawCaptureBuffer;
@@ -523,6 +597,128 @@ namespace pipedal
}
}
}
void CopyCaptureS24_3Le(size_t frames)
{
uint8_t *p = (uint8_t*)rawCaptureBuffer;
std::vector<float *> &buffers = this->captureBuffers;
int channels = this->captureChannels;
constexpr float scale = 1.0f / (std::numeric_limits<int32_t>::max() + 1L);
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
int32_t v = (p[0] << 8)+(p[1] << 16) | (p[2] << 24);
p += 3;
buffers[channel][frame] = scale * v;
}
}
}
void CopyCaptureS24_3Be(size_t frames)
{
uint8_t *p = (uint8_t*)rawCaptureBuffer;
std::vector<float *> &buffers = this->captureBuffers;
int channels = this->captureChannels;
constexpr float scale = 1.0f / (std::numeric_limits<int32_t>::max() + 1L);
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
int32_t v = (p[2] << 8)+(p[1] << 16) | (p[0] << 24);
p += 3;
buffers[channel][frame] = scale * v;
}
}
}
void CopyCaptureS24Le(size_t frames)
{
int32_t *p = (int32_t *)rawCaptureBuffer;
std::vector<float *> &buffers = this->captureBuffers;
int channels = this->captureChannels;
constexpr float scale = 1.0f / (0x00FFFFFFL + 1L);
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
int32_t v = *p++;
buffers[channel][frame] = scale * v;
}
}
}
void CopyCaptureS24Be(size_t frames)
{
int32_t *p = (int32_t *)rawCaptureBuffer;
std::vector<float *> &buffers = this->captureBuffers;
int channels = this->captureChannels;
constexpr float scale = 1.0f / (0x00FFFFFFL + 1L);
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
int32_t v = EndianSwap(*p++);
buffers[channel][frame] = scale * v;
}
}
}
void CopyCaptureS32Be(size_t frames)
{
int32_t *p = (int32_t *)rawCaptureBuffer;
std::vector<float *> &buffers = this->captureBuffers;
int channels = this->captureChannels;
constexpr float scale = 1.0f / (std::numeric_limits<int32_t>::max() + 1L);
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
int32_t v = EndianSwap(*p++);
buffers[channel][frame] = scale * v;
}
}
}
void CopyPlaybackS16Le(size_t frames)
{
int16_t *p = (int16_t *)rawPlaybackBuffer;
std::vector<float *> &buffers = this->playbackBuffers;
int channels = this->playbackChannels;
constexpr float scale = std::numeric_limits<int16_t>::max();
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
float v = buffers[channel][frame];
if (v > 1.0f)
v = 1.0f;
else if (v < -1.0f)
v = -1.0f;
*p++ = (int16_t)(scale * v);
}
}
}
void CopyPlaybackS16Be(size_t frames)
{
int16_t *p = (int16_t *)rawPlaybackBuffer;
std::vector<float *> &buffers = this->playbackBuffers;
int channels = this->playbackChannels;
constexpr float scale = std::numeric_limits<int16_t>::max();
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
float v = buffers[channel][frame];
if (v > 1.0f)
v = 1.0f;
else if (v < -1.0f)
v = -1.0f;
*p++ = EndianSwap((int16_t)(scale * v));
}
}
}
void CopyPlaybackS32Le(size_t frames)
{
int32_t *p = (int32_t *)rawPlaybackBuffer;
@@ -537,12 +733,123 @@ namespace pipedal
float v = buffers[channel][frame];
if (v > 1.0f)
v = 1.0f;
if (v < -1.0f)
else if (v < -1.0f)
v = -1.0f;
*p++ = (int32_t)(scale * v);
}
}
}
void CopyPlaybackS24Le(size_t frames)
{
// 24 bits in low bits of an int32_t.
int32_t *p = (int32_t *)rawPlaybackBuffer;
std::vector<float *> &buffers = this->playbackBuffers;
int channels = this->playbackChannels;
constexpr float scale = 0x00FFFFFF;
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
float v = buffers[channel][frame];
if (v > 1.0f)
v = 1.0f;
else if (v < -1.0f)
v = -1.0f;
*p++ = (int32_t)(scale * v);
}
}
}
void CopyPlaybackS24Be(size_t frames)
{
// 24 bits in low bits of an int32_t.
int32_t *p = (int32_t *)rawPlaybackBuffer;
std::vector<float *> &buffers = this->playbackBuffers;
int channels = this->playbackChannels;
constexpr float scale = 0x00FFFFFF;
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
float v = buffers[channel][frame];
if (v > 1.0f)
v = 1.0f;
else if (v < -1.0f)
v = -1.0f;
*p++ = EndianSwap((int32_t)(scale * v));
}
}
}
void CopyPlaybackS32Be(size_t frames)
{
int32_t *p = (int32_t *)rawPlaybackBuffer;
std::vector<float *> &buffers = this->playbackBuffers;
int channels = this->playbackChannels;
constexpr float scale = std::numeric_limits<int32_t>::max();
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
float v = buffers[channel][frame];
if (v > 1.0f)
v = 1.0f;
else if (v < -1.0f)
v = -1.0f;
*p++ = EndianSwap((int32_t)(scale * v));
}
}
}
void CopyPlaybackS24_3Be(size_t frames)
{
uint8_t *p = (uint8_t *)rawPlaybackBuffer;
std::vector<float *> &buffers = this->playbackBuffers;
int channels = this->playbackChannels;
constexpr float scale = std::numeric_limits<int32_t>::max();
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
float v = buffers[channel][frame];
if (v > 1.0f)
v = 1.0f;
else if (v < -1.0f)
v = -1.0f;
int32_t iValue = (int32_t)(scale * v);
p[0] = (uint8_t)(iValue >> 24);
p[1] = (uint8_t)(iValue >> 16);
p[2] = (uint8_t)(iValue >> 8);
}
}
}
void CopyPlaybackS24_3Le(size_t frames)
{
uint8_t *p = (uint8_t *)rawPlaybackBuffer;
std::vector<float *> &buffers = this->playbackBuffers;
int channels = this->playbackChannels;
constexpr float scale = std::numeric_limits<int32_t>::max();
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
float v = buffers[channel][frame];
if (v > 1.0f)
v = 1.0f;
else if (v < -1.0f)
v = -1.0f;
int32_t iValue = (int32_t)(scale * v);
p[0] = (uint8_t)(iValue >> 8);
p[1] = (uint8_t)(iValue >> 16);
p[2] = (uint8_t)(iValue >> 24);
}
}
}
void CopyPlaybackFloatLe(size_t frames)
{
float *p = (float *)rawPlaybackBuffer;
@@ -558,6 +865,22 @@ namespace pipedal
}
}
}
void CopyPlaybackFloatBe(size_t frames)
{
float *p = (float *)rawPlaybackBuffer;
std::vector<float *> &buffers = this->playbackBuffers;
int channels = this->captureChannels;
for (size_t frame = 0; frame < frames; ++frame)
{
for (int channel = 0; channel < channels; ++channel)
{
float v = buffers[channel][frame];
EndianSwap(p,v);
p++;
}
}
}
void AllocateBuffers(std::vector<float *> &buffers, size_t n)
{
buffers.resize(n);
@@ -709,6 +1032,7 @@ namespace pipedal
snd_pcm_format_t captureFormat;
snd_pcm_hw_params_get_format(captureHwParams, &captureFormat);
copyInputFn = nullptr;
switch (captureFormat)
{
@@ -717,6 +1041,7 @@ namespace pipedal
copyInputFn = &AlsaDriverImpl::CopyCaptureFloatLe;
break;
case SND_PCM_FORMAT_S24_3LE:
copyInputFn = &AlsaDriverImpl::CopyCaptureS24_3Le;
captureSampleSize = 3;
break;
case SND_PCM_FORMAT_S32_LE:
@@ -725,27 +1050,39 @@ namespace pipedal
break;
case SND_PCM_FORMAT_S24_LE:
captureSampleSize = 4;
copyInputFn = &AlsaDriverImpl::CopyCaptureS24Le;
break;
case SND_PCM_FORMAT_S16_LE:
captureSampleSize = 2;
copyInputFn = &AlsaDriverImpl::CopyCaptureS16Le;
break;
case SND_PCM_FORMAT_FLOAT_BE:
captureSampleSize = 4;
copyInputFn = &AlsaDriverImpl::CopyCaptureFloatBe;
captureSampleSize = 4;
break;
case SND_PCM_FORMAT_S24_3BE:
captureSampleSize = 3;
copyInputFn = &AlsaDriverImpl::CopyCaptureS24_3Be;
break;
case SND_PCM_FORMAT_S32_BE:
copyInputFn = &AlsaDriverImpl::CopyCaptureS32Be;
captureSampleSize = 4;
break;
case SND_PCM_FORMAT_S24_BE:
copyInputFn = &AlsaDriverImpl::CopyCaptureS24Be;
captureSampleSize = 4;
break;
case SND_PCM_FORMAT_S16_BE:
copyInputFn = &AlsaDriverImpl::CopyCaptureS16Be;
captureSampleSize = 2;
break;
default:
throw PiPedalStateException("Invalid format.");
break;
}
if (copyInputFn == nullptr)
{
throw PiPedalStateException(SS("Audio input format not supported. (" << captureFormat << ")"));
}
captureFrameSize = captureSampleSize * captureChannels;
rawCaptureBuffer = new uint8_t[captureFrameSize * bufferSize];
@@ -756,6 +1093,7 @@ namespace pipedal
snd_pcm_format_t playbackFormat;
snd_pcm_hw_params_get_format(playbackHwParams, &playbackFormat);
copyOutputFn = nullptr;
switch (playbackFormat)
{
case SND_PCM_FORMAT_FLOAT_LE:
@@ -763,6 +1101,7 @@ namespace pipedal
copyOutputFn = &AlsaDriverImpl::CopyPlaybackFloatLe;
break;
case SND_PCM_FORMAT_S24_3LE:
copyOutputFn = &AlsaDriverImpl::CopyPlaybackS24_3Le;
playbackSampleSize = 3;
break;
case SND_PCM_FORMAT_S32_LE:
@@ -770,29 +1109,41 @@ namespace pipedal
playbackSampleSize = 4;
break;
case SND_PCM_FORMAT_S24_LE:
copyOutputFn = &AlsaDriverImpl::CopyPlaybackS24Le;
playbackSampleSize = 4;
break;
case SND_PCM_FORMAT_S16_LE:
copyOutputFn = &AlsaDriverImpl::CopyPlaybackS16Le;
playbackSampleSize = 2;
break;
case SND_PCM_FORMAT_FLOAT_BE:
copyOutputFn = &AlsaDriverImpl::CopyPlaybackFloatBe;
playbackSampleSize = 4;
break;
case SND_PCM_FORMAT_S24_3BE:
copyOutputFn = &AlsaDriverImpl::CopyPlaybackS24_3Be;
playbackSampleSize = 3;
break;
case SND_PCM_FORMAT_S32_BE:
copyOutputFn = &AlsaDriverImpl::CopyPlaybackS32Be;
playbackSampleSize = 4;
break;
case SND_PCM_FORMAT_S24_BE:
copyOutputFn = &AlsaDriverImpl::CopyPlaybackS24Be;
playbackSampleSize = 4;
break;
case SND_PCM_FORMAT_S16_BE:
copyOutputFn = &AlsaDriverImpl::CopyPlaybackS16Be;
playbackSampleSize = 2;
break;
default:
throw PiPedalStateException("Invalid format.");
break;
}
if (copyOutputFn == nullptr)
{
throw PiPedalStateException(SS("Unsupported audio output format. (" << playbackFormat << ")"));
}
playbackFrameSize = playbackSampleSize * playbackChannels;
rawPlaybackBuffer = new uint8_t[playbackFrameSize * bufferSize];
memset(rawPlaybackBuffer, 0, playbackFrameSize * bufferSize);