Gallery and Press Folder
@@ -76,7 +76,7 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "IoT guitar effect for Raspberry Pi")
|
|||||||
set(CPACK_DEBIAN_PACKAGE_SECTION sound)
|
set(CPACK_DEBIAN_PACKAGE_SECTION sound)
|
||||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||||
set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
|
set(CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION TRUE)
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "jackd2")
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS "jackd2, hostapd, dnsmasq" )
|
||||||
#set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
|
#set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
|
||||||
set(CPACK_PACKAGING_INSTALL_PREFIX /usr)
|
set(CPACK_PACKAGING_INSTALL_PREFIX /usr)
|
||||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ PiPedal provides a pre-installed selection of LV2 plugins from the ToobAmp colle
|
|||||||
|
|
||||||
If your USB audio adapter has midi connectors, you can use midi devices (keyboards or midi floor boards) to control PiPedal while performing. A simple interface allows you to select how you would like to bind PiPedal controls to midi messages.
|
If your USB audio adapter has midi connectors, you can use midi devices (keyboards or midi floor boards) to control PiPedal while performing. A simple interface allows you to select how you would like to bind PiPedal controls to midi messages.
|
||||||
|
|
||||||
|
<img src="docs/gallery/jazz.png" width="92%">
|
||||||
<!-- {% include gallery.html %} -->
|
<!-- {% include gallery.html %} -->
|
||||||
<img src="docs/gallery/jazz.png" width="45%"></img> <img src="docs/gallery/thunder.png" width="45%"></img> <img src="docs/gallery/midi-bindings.png" width="45%"></img> <img src="docs/gallery/hotspot.png" width="45%"></img>
|
<img src="docs/gallery/jazz.png" width="45%"></img> <img src="docs/gallery/thunder.png" width="45%"></img> <img src="docs/gallery/midi-bindings.png" width="45%"></img> <img src="docs/gallery/hotspot.png" width="45%"></img>
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,14 @@
|
|||||||
|
|
||||||
{
|
{
|
||||||
let images = [
|
let images = [
|
||||||
|
"rig.jpg",
|
||||||
"jazz.png",
|
"jazz.png",
|
||||||
"thunder.png",
|
"thunder.png",
|
||||||
"midi-bindings.png",
|
"midi-bindings.png",
|
||||||
"hotspot.png"
|
"hotspot.png"
|
||||||
];
|
];
|
||||||
let captions = [
|
let captions = [
|
||||||
|
"\u00A0",
|
||||||
"PiPedal web interface.",
|
"PiPedal web interface.",
|
||||||
"Flexible effect routing.",
|
"Flexible effect routing.",
|
||||||
"Bind controls to midi messages.",
|
"Bind controls to midi messages.",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
height: 54px;
|
height: 54px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<header class="site-header sticky-header">
|
<header class="site-header sticky-header" style="background: url(banner-bg.jpg); background-size: cover">
|
||||||
|
|
||||||
<div class="wrapper ">
|
<div class="wrapper ">
|
||||||
{%- assign default_paths = site.pages | map: "path" -%}
|
{%- assign default_paths = site.pages | map: "path" -%}
|
||||||
|
|||||||
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 28 KiB |
@@ -5,15 +5,16 @@
|
|||||||
|
|
||||||
Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet.
|
Use your Raspberry Pi as a guitar effects pedal. Configure and control PiPedal with your phone or tablet.
|
||||||
|
|
||||||
PiPedal running on a Raspberry Pi 4 provides stable super-low-latency audio via external USB audio devices, or internal Raspberry Pi audio hats.
|
PiPedal running on a Raspberry Pi 4 provides stable low-latency audio via external USB audio devices, or internal Raspberry Pi audio hats; and the Raspberry Pi 4's
|
||||||
|
processor provides enough power to run even the most demanding pedal plugins.
|
||||||
|
|
||||||
PiPedal's user interface has been specifically designed to work well on small form-factor touch devices like phones or tablets. Clip a phone or tablet on your microphone stand on stage, and you're ready to play! Or connect via a desktop browser, for a slightly more luxurious experience. The PiPedal user-interface adapts to the screen size and orientation of your device, providing easy control of your guitar effects across a broad variety devices and screen sizes.
|
PiPedal's user interface has been specifically designed to work well on small form-factor touch devices like phones or tablets. Clip a phone or tablet on your microphone stand on stage, and you're ready to play! Or connect via a desktop browser, for a slightly more luxurious experience. The PiPedal user-interface adapts to the screen size and orientation of your device, providing easy control of your guitar effects across a broad variety devices and screen sizes.
|
||||||
|
|
||||||
PiPedal provides a simple configuration tool that allows you to easily set up a WiFi hotspot on your Raspberry Pi which can then be used to connect wirelessly.
|
Set up a Wi-Fi hotspot for your phone or table to connect to using a simple setup dialog.
|
||||||
|
|
||||||
PiPedal provides a pre-installed selection of LV2 plugins from the ToobAmp collection of plugins. But it works with most LV2 Audio plugins. There are literally hundreds of free high-quality LV2 audio plugins that will work with PiPedal.
|
PiPedal includes a small selection of LV2 plugins from the ToobAmp collection of plugins. But it works with most LV2 Audio plugins. There are literally hundreds of [free high-quality LV2 audio plugins](UsingLv2Plugins.md) that will work with PiPedal.
|
||||||
|
|
||||||
If your USB audio adapter has midi connectors, you can use midi devices (keyboards or midi floor boards) to control PiPedal while performing. A simple interface allows you to select how you would like to bind PiPedal controls to midi messages.
|
If your USB audio adapter has MIDI connectors, you can use MIDI controllers or keyboards to control PiPedal while performing. A simple interface allows you to select how you would like to bind MIDI messages to effect controls.
|
||||||
|
|
||||||
{% include gallery.html %}
|
{% include gallery.html %}
|
||||||
|
|
||||||
|
|||||||
|
After Width: | Height: | Size: 705 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 237 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 64 KiB |
@@ -563,7 +563,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
||||||
|
|
||||||
<ButtonBase className={classes.setting} disabled={!isConfigValid || disableShutdown}
|
<ButtonBase className={classes.setting} disabled={disableShutdown}
|
||||||
onClick={() => this.handleRestart()} >
|
onClick={() => this.handleRestart()} >
|
||||||
<SelectHoverBackground selected={false} showHover={true} />
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
<div style={{ width: "100%" }}>
|
<div style={{ width: "100%" }}>
|
||||||
@@ -577,7 +577,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
|||||||
</div>
|
</div>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
||||||
<ButtonBase className={classes.setting} disabled={!isConfigValid || disableShutdown}
|
<ButtonBase className={classes.setting} disabled={disableShutdown}
|
||||||
onClick={() => this.handleShutdown()} >
|
onClick={() => this.handleShutdown()} >
|
||||||
<SelectHoverBackground selected={false} showHover={true} />
|
<SelectHoverBackground selected={false} showHover={true} />
|
||||||
<div style={{ width: "100%" }}>
|
<div style={{ width: "100%" }}>
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ static std::string GetLinkLocalAddressForInterface(const std::string &name)
|
|||||||
struct ifaddrs *ifap = nullptr;
|
struct ifaddrs *ifap = nullptr;
|
||||||
if (getifaddrs(&ifap) != 0)
|
if (getifaddrs(&ifap) != 0)
|
||||||
return "";
|
return "";
|
||||||
std::string result;
|
std::string result = "notlinklocal.error";
|
||||||
for (ifaddrs *p = ifap; p != nullptr; p = p->ifa_next)
|
for (ifaddrs *p = ifap; p != nullptr; p = p->ifa_next)
|
||||||
{
|
{
|
||||||
if (p->ifa_addr->sa_family == AF_INET6 && p->ifa_addr != nullptr && p->ifa_netmask != nullptr)
|
if (p->ifa_addr->sa_family == AF_INET6 && p->ifa_addr != nullptr && p->ifa_netmask != nullptr)
|
||||||
@@ -322,7 +322,7 @@ static std::string GetLinkLocalAddressForInterface(const std::string &name)
|
|||||||
struct sockaddr_in6 *pAddr = (struct sockaddr_in6 *)(p->ifa_addr);
|
struct sockaddr_in6 *pAddr = (struct sockaddr_in6 *)(p->ifa_addr);
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&(pAddr->sin6_addr)))
|
if (IN6_IS_ADDR_LINKLOCAL(&(pAddr->sin6_addr)))
|
||||||
{
|
{
|
||||||
if (name.length() == 0 || name == p->ifa_name)
|
if (name == p->ifa_name)
|
||||||
{
|
{
|
||||||
const int BUFSIZE = 128;
|
const int BUFSIZE = 128;
|
||||||
char host[BUFSIZE];
|
char host[BUFSIZE];
|
||||||
@@ -349,6 +349,36 @@ static std::string GetLinkLocalAddressForInterface(const std::string &name)
|
|||||||
freeifaddrs(ifap);
|
freeifaddrs(ifap);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
static std::string GetLinkLocalAddressForIp4Interface(const std::string&name)
|
||||||
|
{
|
||||||
|
struct ifaddrs *ifap = nullptr;
|
||||||
|
if (getifaddrs(&ifap) != 0)
|
||||||
|
return "";
|
||||||
|
std::string result = "notlocalsubnet.error";
|
||||||
|
for (ifaddrs *p = ifap; p != nullptr; p = p->ifa_next)
|
||||||
|
{
|
||||||
|
if (p->ifa_addr->sa_family == AF_INET && p->ifa_addr != nullptr && p->ifa_netmask != nullptr)
|
||||||
|
{ // TODO: Add support for AF_INET6
|
||||||
|
struct sockaddr_in *pAddr = (struct sockaddr_in *)(p->ifa_addr);
|
||||||
|
{
|
||||||
|
if (name == p->ifa_name)
|
||||||
|
{
|
||||||
|
const int BUFSIZE = 128;
|
||||||
|
char host[BUFSIZE];
|
||||||
|
if (getnameinfo(p->ifa_addr, sizeof(struct sockaddr_in), host, BUFSIZE, NULL, 0, NI_NUMERICHOST) == 0)
|
||||||
|
{
|
||||||
|
host[BUFSIZE - 1] = '\0';
|
||||||
|
|
||||||
|
result = host;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
freeifaddrs(ifap);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::string pipedal::GetLinkLocalAddress(const std::string fromAddress)
|
std::string pipedal::GetLinkLocalAddress(const std::string fromAddress)
|
||||||
{
|
{
|
||||||
@@ -365,7 +395,7 @@ std::string pipedal::GetLinkLocalAddress(const std::string fromAddress)
|
|||||||
{
|
{
|
||||||
uint32_t remoteAddress = htonl(inetAddr.s_addr);
|
uint32_t remoteAddress = htonl(inetAddr.s_addr);
|
||||||
std::string interfaceName = GetInterfaceForIp4Address(remoteAddress);
|
std::string interfaceName = GetInterfaceForIp4Address(remoteAddress);
|
||||||
result = GetLinkLocalAddressForInterface(interfaceName);
|
result = GetLinkLocalAddressForIp4Interface(interfaceName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -391,26 +421,26 @@ std::string pipedal::GetLinkLocalAddress(const std::string fromAddress)
|
|||||||
// [FE80:: ] link local.
|
// [FE80:: ] link local.
|
||||||
// [FEC0:: ] site local.
|
// [FEC0:: ] site local.
|
||||||
// others?
|
// others?
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&inetAddr6))
|
if (IN6_IS_ADDR_V4MAPPED(&inetAddr6))
|
||||||
{
|
{
|
||||||
return address;
|
int8_t*pAddr = (int8_t*)&inetAddr6;
|
||||||
}
|
uint32_t remoteAddress = htonl(*(int32_t*)(pAddr+12));
|
||||||
if (IN6_IS_ADDR_SITELOCAL(&inetAddr6))
|
std::string interfaceName = GetInterfaceForIp4Address(remoteAddress);
|
||||||
{
|
result = GetLinkLocalAddressForIp4Interface(interfaceName);
|
||||||
return address;
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
std::string interfaceName;
|
std::string interfaceName;
|
||||||
if (IsIpv4MappedAddress(inetAddr6))
|
if (IsIpv4MappedAddress(inetAddr6))
|
||||||
{
|
{
|
||||||
uint32_t remoteAddress = GetIpv4MappedAddress(inetAddr6);
|
uint32_t remoteAddress = GetIpv4MappedAddress(inetAddr6);
|
||||||
interfaceName = GetInterfaceForIp4Address(remoteAddress);
|
interfaceName = GetInterfaceForIp4Address(remoteAddress);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
interfaceName = GetInterfaceForIp6Address(inetAddr6);
|
||||||
|
}
|
||||||
|
result = GetLinkLocalAddressForInterface(interfaceName);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
interfaceName = GetInterfaceForIp6Address(inetAddr6);
|
|
||||||
}
|
|
||||||
result = GetLinkLocalAddressForInterface(interfaceName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result == "")
|
if (result == "")
|
||||||
|
|||||||