7 |
8 | the same approach is possible for other editors like Visual Studio Code and Eclipse for nodejs
9 |
10 | ### Debugging with system journal
11 |
12 | You can see all logs, generated both by the system and Volumio with
13 |
14 | ```shell
15 | sudo journalctl -f
16 | ```
17 |
18 | This includes outputs to the console too:
19 |
20 | ```javascript
21 | console.log('my output')
22 | ```
23 |
24 | So, ideally, you'll want to:
25 |
26 | * Edit the files from your editor of choice
27 | * Upload changes to the Volumio device
28 | * Restart NODE Services
29 | * See the effects via an SSH connection, with sudo journalctl -f
30 |
--------------------------------------------------------------------------------
/docs/01_Development_How_To/img/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/01_Development_How_To/img/architecture.png
--------------------------------------------------------------------------------
/docs/02_API/01_API_Overview.md:
--------------------------------------------------------------------------------
1 | ## Introduction
2 |
3 | ### Volumio's main API: websocket
4 |
5 | The most used API transport in Volumio2 is its Websockets API as it allows almost real time communication with multiple clients. Volumio's WebUI gets and sends data (almost) exclusively via WS. Volumio's WS layer is powered by [Socket.io](http://socket.io/).
6 | The WebSocket API interface is located at: [WebSocket](https://github.com/volumio/Volumio2/tree/master/app/plugins/user_interface/websocket)
7 |
8 | Full documentation about Volumio Websocket protocol is provided in the next section
9 |
10 | ### Volumio's REST API
11 |
12 | Alternatively, a small subset of system calls are available trough RESTful APIs, in json format. They are available in the REST API section
13 |
--------------------------------------------------------------------------------
/docs/03_Plugin_System/05_Toast_Messages.md:
--------------------------------------------------------------------------------
1 | ## Toast Messages
2 |
3 | ### Enable Toast Messages
4 |
5 | For easier usage make sure you assign the coreCommand instance in the consturctor of your plugin:
6 |
7 | ```javascript
8 | module.exports = ExamplePlugin;
9 | function ExamplePlugin(context) {
10 | var self = this;
11 | self.context = context;
12 | self.commandRouter = this.context.coreCommand;
13 | }
14 | ```
15 |
16 | ### Create Toast Message
17 |
18 | At any place in your code you can then call the `commandRouter.pushToastMessage` method to show a toast messages to the user:
19 |
20 | ```javascript
21 | self.commandRouter.pushToastMessage('success', "Account Login", "Login was successful");
22 | ```
23 |
24 | There are four kinds of toast messages: `info`, `success`, `warning` and `error`:
25 |
26 | ```javascript
27 | self.commandRouter.pushToastMessage('info', "Account Login", "Login pending....");
28 | self.commandRouter.pushToastMessage('success', "Account Login", "Login was successful");
29 | self.commandRouter.pushToastMessage('warning', "Account Login", "Login not possible");
30 | self.commandRouter.pushToastMessage('error', "Account Login", "Login failed - invalid credentials");
31 | ```
32 |
--------------------------------------------------------------------------------
/docs/03_Plugin_System/06_Logging.md:
--------------------------------------------------------------------------------
1 | ## Logging
2 |
3 | ### Enable Logging
4 |
5 | For easier usage make sure you assign the `context.logger` instance in the consturctor of your plugin:
6 |
7 | ```javascript
8 | module.exports = ControllerSpop;
9 | function ControllerSpop(context) {
10 | var self = this;
11 | self.logger = this.context.logger;
12 | }
13 | ```
14 |
15 | ### Create Log Message
16 |
17 | At any place in your code you can then call the methods of the logger instance:
18 |
19 | ```javascript
20 | self.logger.info("Youtube::onStart Adding to browse sources");
21 | ```
22 |
23 | The logger instance has the following methods to create log messages: `info`, `warn`, `error` and `debug`.
24 |
25 | Volumio is using [winston](https://github.com/winstonjs/winston) for logging.
--------------------------------------------------------------------------------
/docs/03_Plugin_System/07_User_Modal.md:
--------------------------------------------------------------------------------
1 | ## User Modal
2 |
3 | It is possible to interact with your plugin's user in real time using modals.
4 |
5 | Here's an example:
6 |
7 | ```javascript
8 | var modalData = {
9 | title: 'Modal',
10 | message: 'Something occured, you may react, or close this window',
11 | size: 'lg',
12 | buttons: [
13 | {
14 | name: 'Close',
15 | class: 'btn btn-warning'
16 | },
17 | {
18 | name: 'React',
19 | class: 'btn btn-info',
20 | emit:'react',
21 | payload:''
22 | }
23 | ]
24 | }
25 |
26 | self.commandRouter.broadcastMessage("openModal", modalData);
27 | ```
28 |
29 | In the previous example, a modal is created by the plugin at runtime.
30 | Whatever button the user presses, the modal will close.
31 |
32 | The "React" button however will also emit a "react" socketIO event, which can be handled directly by the plugin.
33 |
34 | This section is potentially incomplete and needs revisiting, but it should work.
35 |
--------------------------------------------------------------------------------
/docs/03_Plugin_System/img/plugin_enable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/03_Plugin_System/img/plugin_enable.png
--------------------------------------------------------------------------------
/docs/03_Plugin_System/img/plugin_list.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/03_Plugin_System/img/plugin_list.png
--------------------------------------------------------------------------------
/docs/03_Plugin_System/img/plugin_menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/03_Plugin_System/img/plugin_menu.png
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/01_Introduction.md:
--------------------------------------------------------------------------------
1 | ## Introduction ##
2 |
3 | ### Note ###
4 | This is work in progress and will be updated the coming couple of days
5 | Last change: 18.06.2017/ gkkpch
6 |
7 | ### What does it cover ###
8 | This is a __guideline__ for porting Volumio to new ARM platforms, not a step-by-step instruction or cookbook.
9 | It covers most of the steps needed:
10 | * Creating/ compiling u-boot to make the new board image bootable
11 | * Compiling a suitable kernel, the device tree, modules and firmware
12 | * Creating a platform repo to support the build process
13 | * Creating the board-specific image.sh script
14 | * Creating the board-specific config.sh script
15 |
16 | As arm devices can differ regarding kernel version, supported u-boot version, boot parameters, and partition layout, board-specific properties have to be taken into account.
17 | Example: some board images use uEnv.txt or boot.ini to describe the boot parameters, others use a compiled boot.scr.
18 | Or, as we will see in our build example, a combination of a compiled boot.scr and a text file to override certain defined parameters.
19 | As for u-boot, some can be compiled directly from ____ (mostly newer boards with a mainline kernel), some need additional blobs.
20 | For some boards, blobs, SPL and u-boot are written to a device in separate steps, for others an image from u-boot and spl binary must be prepared and written to the device.
21 | The purpose of this guide is to offer help in finding the information you need to cover all these different issues.
22 | Again, the guide is not a cookbook, but it will use the Asus Tinkerboard as an example from chapter 4 onwards, describing in detail how it was done for that particular device.
23 |
24 | ### Advice ###
25 | Try to find an example build procedure for another OS, a good source of information is usually the suppliers own BSP (Board Support Package) repo or forums and wiki's (e.g. the excellent Hardkernel wiki).
26 | Also our friends at ____ are doing an awesome job supporting relevant devices, not only do the offer their own ARMBIAN distribution, they are excellent at supporting their kernels up-to-date by patching whenever relevant.
27 | In case the Armbian Team does not support your device, you are probably going to have a hard time finding a better source for info.
28 | Another good source of information (also with lots of contributions from the Armbian Team), but dedicated to Allwinner SoC based devices, is ____
29 |
30 | Look for things like “How to build an SD card for .....”, it makes the porting a lot easier.
31 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/03_Preparing_The_Build_Environment.md:
--------------------------------------------------------------------------------
1 | ## Preparing the Build Process ##
2 |
3 | ### Necessary packages ###
4 | The following packages need to be installed on your build machine, you will need them sooner or later in the build process.
5 |
6 | git squashfs-tools kpartx multistrap qemu-user-static samba debootstrap parted dosfstools qemu binfmt-support lzop chrpath gawk texinfo libsdl1.2-dev whiptail diffstat cpio libssl-dev
7 |
8 | ### Optional ###
9 |
10 | qemu-utils (only needed if x86 will be built with the machine too )
11 |
12 | ### Special Requirement for Rockchip on Debian jessie ###
13 |
14 | Jessie's u-boot tool 'mkimage' is too old to support a "rksd"-type image, needed for u-boot creation with Rockchip SoC's (see "Compiling U-Boot").
15 | In case you build for Rockchip, you need to download a newer version, at least __2016.11+dfsg1-4__, and install it over jessie's 2014.10+dfsg1-5:
16 |
17 | wget http://ftp.debian.org/debian/pool/main/u/u-boot/u-boot-tools_2016.11+dfsg1-4_amd64.deb
18 | dpkg -i u-boot-tools_2016.11+dfsg1-4_amd64.deb
19 | rm u-boot-tools_2016.11+dfsg1-4_amd64.deb
20 |
21 | ### Toolchain ###
22 | You need to crosscompile for arm, this means you need the proper toolchain and also take care to use the correct version.
23 | For older kernels and u-boot we used GCC-4.9.3 (Odroids, arm and aarch64), some require GCC-5, newer ones (like our build example with the Asus Tinkerboard) now require gcc-6.1
24 | You can download the toolchain from the Linaro organisation: ____
25 |
26 | Create a folder /opt/toolchains and extract the tarball in it (example with gcc-4.9.3)
27 |
28 | sudo mkdir -p /opt/toolchains
29 | sudo tar xvf gcc-linaro-arm-linux-gnueabihf-4.9-2014.11_linux.tar.xz -C /opt/toolchains/
30 |
31 | Add the path to PATH and set environment variables, best to add them to $HOME/.bashrc, just add the following lines:
32 |
33 | export ARCH=arm
34 | export CROSS_COMPILE=arm-linux-gnueabihf-
35 | export PATH=/opt/toolchains/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/:$PATH
36 |
37 | You can apply the change by logging out and in again or evaluate $HOME/.bashrc with source command.
38 |
39 | source ~/.bashrc
40 |
41 | Check if the toolchain works properly by checking its version, if you can find gcc version string at the end of the output, you’re OK.
42 |
43 | arm-linux-gnueabihf-gcc -v
44 | Using built-in specs
45 | …
46 | …
47 | …
48 | …
49 | gcc version 4.9.3 20141031 (prerelease) (Linaro GCC 2014.11)
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/04_Example:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/05_Porting_Guide/04_Example
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/05_The_Process.md:
--------------------------------------------------------------------------------
1 | ## The Process ##
2 |
3 | When Volumio was ported to odroid c1, c2, xu4, cubox-i and pine64, we did things more or less in the same order, let's do this for the Tinkerboard too:
4 | * Make a platform home folder
5 | * Get u-boot and related info (defconfig, offsets for placing the u-boot on disk)
6 | * Get the kernel sources and corresponding config file
7 | * Compile u-boot and assemble u-boot.bin
8 | * Compile the kernel, this should give you the kernel (zImage or uImage), the binary device tree (dtb), modules and firmware.
9 |
10 | You do not need to set all the kernel options right yet.
11 | At this stage in the process it is more important that the first resulting image will boot.
12 | All other options can be added after the basics have been done.
13 | Make sure that you have at least __overlayfs__ (File Systems) and __squashfs__ (Miscellaneous Filesystems ) enabled as modules and also the kernel has __support for initramfs__.
14 |
15 | There is more information on how u-boot must be built in ____
16 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/06_The_Platform_Folder.md:
--------------------------------------------------------------------------------
1 | ## The Platform Folder ##
2 |
3 | Create the platform folder. This will be used to store all device-specific files, like kernel, boot configuration, u-boot and SPL files and anything we find during the build which is board specific goes here.
4 | This folder gets tarred in the end and moved into a separate volumio repo, described in __Saving Files to the Platform Folder__.
5 |
6 | We presumed the board is called tinkerboard and we have the location of the kernel and u-boot, including the config files which we will use.
7 | Assuming, Asus will released further sbc's in the future, we will name the platform folder "platform_asus" and create a subfolder "tinkerboard" which will hold the platform files for that board.
8 |
9 | Then start preparing, assuming the root of the platform files is in $HOME/asus-build
10 |
11 | mkdir $HOME/asus-build/platform-asus
12 | mkdir $HOME/asus-build/platform-asus/tinkerboard/boot
13 | mkdir $HOME/asus-build/platform-asus/tinkerboard/etc
14 | mkdir $HOME/asus-build/platform-asus/tinkerboard/u-boot
15 | mkdir $HOME/asus-build/platform-asus/tinkerboard/usr
16 |
17 | Note: eventually you need to add the platform folder to the Volumio repo.
18 | This does not need to be done immediately.
19 | Chapter "Creating the image" shows a way to build an image before integrating the new scripts and platform files into the repo.
20 | The same method can be used to test new platform files before they are pushed.
21 | When integration is due, get in touch with @volumio (Micelangelo) to have him create the platform-file repo, in our case "platform-asus".
22 | Fork this one and clone it to your host PC, add (or edit) the README.md file.
23 | This file should at least contain a reference the used kernel source location, u-boot and other relevant device-specific info.
24 | Best practise also means you keep a changelog in README.md.
25 | Examples of README.md in are in the Volumio Platform repos.
26 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/07_Compiling_U-Boot.md:
--------------------------------------------------------------------------------
1 | ## Compiling U-Boot ##
2 |
3 | ### Clone u-boot ###
4 |
5 | git clone git://git.denx.de/u-boot.git u-boot -b master --depth 1
6 |
7 | ### Patches ###
8 | At the time of writing, there is a correction/ change for u-boot, which has not been committed to the official U-Boot repository yet.
9 | It deals with fixing an eth mac address.
10 | When volumio is configured to use dhcp for eth (which is default), the device should not get a new IP address every time the device is booted.
11 | With this patch, a fixed eth mac address is generated, using device-specific info from an EEPROM.
12 | The patch file is in folder "platform-files", under "patches".
13 | Copy the patch to the root of the u-boot folder and apply it like this:
14 |
15 | patch -p1 < tinker_set_ethaddr_in_late_init.patch
16 |
17 | ### Compile ###
18 | There is a u-boot configuration for the Tinkerboard in the master branch, we will compile u-boot using it:
19 |
20 | cd u-boot
21 | make clean (does not do anything here as we just cloned)
22 | make tinker-rk3288_defconfig
23 | touch .scmversion (to get a clean u-boot version number)
24 | make -j8
25 |
26 | #### assumption ####
27 | DEST=$HOME/platform-asus/tinkerboard
28 |
29 | ### Create the u-boot.img ###
30 | For a correct boot process, the u-boot spl and u-boot dtb are combined into a single u-boot.bin file, to be used for the Tinkerboard image build script.
31 |
32 | mkimage -n rk3288 -T rksd -d spl/u-boot-spl-dtb.bin ../platform-asus/tinkerboard/u-boot/u-boot.img
33 | mkdir $DEST/u-boot (in case not yet existing)
34 | cat u-boot-dtb.bin >> $DEST/u-boot/u-boot.img
35 |
36 | The u-boot image must be copied to the beginning of the device, skip 64 blocks for the location of the loader.
37 | This should be done in the tinkerimage.sh script, to be explained later.
38 |
39 | dd if=platform-asus/tinkerboard/u-boot/u-boot.img of=${LOOP_DEV} seek=64 conv=notrunc
40 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/08_Get_The_Kernel_Source.md:
--------------------------------------------------------------------------------
1 | ## Getting the kernel Source ##
2 | ### Use the Armbian Tool to get a patched kernel 4.4.xx ###
3 |
4 | We will use the armbian toolset to download and compile the kernel only.
5 | Go to ____
6 | Make sure you meet the requiremens in “What do I need”
7 |
8 | Follow the guide to run the script
9 |
10 | ./compile.sh KERNEL_ONLY=yes KERNEL_KEEP_CONFIG=yes
11 |
12 | From the menu, select “Kernel and u-boot packages”.
13 | Then select “Tinkerboard” from the supported boards menu.
14 | You will then have to select the kernel version & branch.
15 | Pick the default “Vendor Provided / legacy (3.4.x – 4.4.x)” from the presented list.
16 | This is not really “Vendor provided” in the true sense, as Armbian then clones from the mqmaker repo as explained above.
17 | You can forget about u-boot and sunxi-tools, we do not need them for our purpose.
18 |
19 | When you're building on a Ubuntu machine, you can continue with kernel compilation in
20 |
21 | $HOME/sources/linux-rockchip/miqi/release-4.4
22 |
23 | Otherwise
24 |
25 | cd $HOME/sources/linux-rockchip/miqi/release-4.4
26 | sudo make clean
27 | cd ..
28 | sudo tar cvfJ release-4.4.tar.xz ./release-4.4
29 |
30 | ...then transfer the tarball, create $HOME/sources/linux-rockchip/miqi on your target system and unpack it in the miqi folder
31 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/09_Configure_Kernel_Options.md:
--------------------------------------------------------------------------------
1 | ## Changing Kernel Options, Volumio requirements ##
2 | ### Basics ###
3 | support for initramfs
4 | overlayfs
5 | squashfs
6 | nfs server
7 |
8 | ### Volumio 2 reqs ###
9 | usb audio
10 | board's soc sound options and codes
11 | iptables
12 | all built-in wireless options (wifi/bluetooth) and possible wifi dongles
13 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/09_Get_The_Kernel_Source.md:
--------------------------------------------------------------------------------
1 | ## Getting the kernel Source ##
2 | ### Use the Asus Tinkerboard Repo to get the kernel source (4.4.xx) ###
3 |
4 | Luckily, Asus now supplyies their own kernel repo
5 | Start with downoading onto your Home folder
6 |
7 | git clone http://github.com/tinkerboard/debian_kernel linux-asus
8 |
9 | ### Patches ###
10 |
11 | Sometimes, especially with brand new boards, changes are made by others, which would suit Volumio but haven't found their way into the (vendor's) kernel repo.
12 | A way to get these into our kernel is applying these changes aspatches.
13 | At the time of writing, 3 patches are know, which I will apply from one single patch file.
14 | It deals with:
15 |
16 | - Change in the kernel compile 'makefile' in order to eliminate two very strict syntax checks, which causes the compile to fail with gcc version 6. The best way would have been to fix the sources, but I consider that a task for the maintainers.
17 | - Change to the behavior of two board leds, allowing one blinking as a heartbeat and the other one blinking for disk activity
18 | - an entry in the usb quirks table, to show the internal usb audio device to show a friendly name (Tinkerboard)
19 |
20 | The patch is in the plaform-asus folder, under "patches": Volumio-Kernel.patches.
21 | Copy it to the kernel root folder and apply as follows:
22 |
23 | patch -p1 < Volumio-Kernel.patches
24 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/10_Compiling_The_Kernel.md:
--------------------------------------------------------------------------------
1 | ## Compiling the Kernel ##
2 |
3 | Armbian was using a default config linux-rockchip-default.config, to be found in $HOME/lib/config/kernel, which should be copied to ................. arch/arm/configs
4 | DEFCONFIG=linux-rockchip-default.config
5 | DTB=rk3288-miniarm.dtb
6 |
7 |
8 | make clean does nothing on first compile, as there is nothing to clean.
9 | Otherwise it is a good idea to start with this when options are going to be changed.
10 |
11 | cd $HOME/sources/linux-rockchip/miqi/release-4.4
12 | make clean
13 | make linux-rockchip-default_defconfig
14 | make menuconfig
15 |
16 | At this stage go to section File Systems and make sure overlayfs has been enabled as a module.
17 | Then go to Miscellaneous Filesystems and check if squashfs has been enabled as a module (including the various compression options).
18 | Then save and exit menuconfig.
19 |
20 | When you want to keep the changes permanent:
21 |
22 | cp .config arch/arm/configs/my_tinker-default_defconfig
23 |
24 | Or easier if you keep the same name:
25 |
26 | make savedefconfig
27 |
28 | Continue compiling the kernel
29 |
30 | make -jx (For x take 1.5 times the number of cpus you have available)
31 |
32 | Save the kernel and dtb's
33 |
34 | cp arch/arm/boot/zImage your-platform-file-folder/boot
35 | cp arch/arm/boot/dts/*.dtb your-platform-file-folder/boot/dtb
36 |
37 | Save the modules and firmware
38 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/10_Configure_Kernel_Options.md:
--------------------------------------------------------------------------------
1 | ## Changing Kernel Options, Volumio requirements ##
2 | ### Basics ###
3 | support for initramfs
4 | overlayfs
5 | squashfs
6 | nls437
7 | nfs server
8 |
9 | ### Volumio 2 reqs ###
10 | usb audio
11 | board's soc sound options and codes
12 | iptables
13 | all built-in wireless options (wifi/bluetooth) and possible wifi dongles
14 |
15 | Wherever possible, configure the options as a module (no need to blow up the kernel for things we not always use)
16 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/11_Compiling_The_Kernel.md:
--------------------------------------------------------------------------------
1 | ## Compiling the Kernel ##
2 |
3 | First we will rename the kernel config to something more logical.
4 | This is normally not necessary, but in this case we started when the original miniarm-rk3288 was not renamed to Tinker Board yet.
5 |
6 | cd linux-asus/arch/arm/configs
7 | cp miniarm-rk3288_defconfig tinker-rockchip_defconfig
8 |
9 | We will use this renamed default kernel config
10 |
11 | Let us build the kernel step by step.
12 | Of course 'make clean' does nothing on first compile, as there is nothing to clean.
13 | Otherwise it is a good idea to start with this when options are going to be changed.
14 | After that we select the kernel config tu use and in this case we also start kernel configuration.
15 |
16 | cd $HOME/linux-asus
17 | make clean
18 | make tinker-rockchip_defconfig
19 | make menuconfig
20 |
21 | At this stage ensure all minimum options from the previous chapter have been selected.
22 | To get a bootable, first volumio image, we need at least overlayfs, squashfs and nls437 as a module.
23 | Then save and exit menuconfig.
24 |
25 | When you want to keep the changes permanent:
26 |
27 | cp .config arch/arm/configs/my_tinker-default_defconfig
28 |
29 | Or easier if you keep the same name:
30 |
31 | make savedefconfig
32 |
33 | Continue compiling the kernel
34 |
35 | make -jx (For x take 1.5 times the number of cpus you have available)
36 |
37 | This does all the work defined in the makefile, including dts compilation
38 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/12_Boot_Parameters.md:
--------------------------------------------------------------------------------
1 |
2 | ## Boot Parameters #
3 | Boot configuration depends on the u-boot version in use for the particular platform.
4 | Always look for prebuilt vendor images, they are a good source of the option(s) you have.
5 |
6 | With the u-boot version we use, there are several options to achieve boot configuration with our requirements.
7 | Below is a script we would have used with an armbian based kernel/ u-boot, it is based on a compiled boot.scr (from boot.cmd) and an optional text file to override predefined variables. Very flexible and works with many platforms.
8 |
9 | ### boot.scr ###
10 | setenv volumioenv "/dev/mmcblk0p1"
11 | setenv fdt_file "rk3288-miqi.dtb"
12 | setenv ramdisk_addr_r "0x21000000"
13 | setenv console "ttyS2,115200n8"
14 | setenv verbosity "1"
15 |
16 | itest.b ${devnum} == 0 && echo "U-boot loaded from SD"
17 | itest.b ${devnum} == 1 && echo "U-boot loaded from eMMC"
18 |
19 | if load ${devtype} ${devnum}:1 ${ramdisk_addr_r} /boot/volumio-env.txt || load ${devtype} ${devnum}:1 ${ramdisk_addr_r} volumio-env.txt; then
20 | env import -t ${ramdisk_addr_r} ${filesize}
21 | fi
22 |
23 | setenv bootargs "consoleblank=0 scandelay ${volumioenv} rw console=${console} rootfstype=ext4 loglevel=${verbosity} rootwait ${extraargs} "
24 | ext4load ${devtype} ${devnum}:1 ${fdt_addr_r} /boot/dtb/${fdt_file} || fatload ${devtype} ${devnum}:1 ${fdt_addr_r} dtb/${fdt_file} || ext4load ${devtype} ${devnum}:1 ${fdt_addr_r} dtb/${fdt_file}
25 | ext4load ${devtype} ${devnum}:1 ${ramdisk_addr_r} /boot/uInitrd || fatload ${devtype} ${devnum}:1 ${ramdisk_addr_r} uInitrd || ext4load ${devtype} ${devnum}:1 ${ramdisk_addr_r} uInitrd
26 | ext4load ${devtype} ${devnum}:1 ${kernel_addr_r} /boot/zImage || fatload ${devtype} ${devnum}:1 ${kernel_addr_r} zImage || ext4load ${devtype} ${devnum}:1 ${kernel_addr_r} zImage
27 | bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}
28 |
29 | # Recompile this script with
30 | # mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr
31 | # or
32 | # Edit volumio-env.txt to override defined setenv parameters
33 |
34 | This would be the corresponding volumio-env.txt file
35 |
36 | verbosity=1
37 | volumio=imgpart=/dev/mmcblk0p2 imgfile=/volumio_current.sqsh
38 | console=tty2,ttyS2,115200n8
39 |
40 | ### extlinux/extlinux.conf ###
41 |
42 | As there is no requirement for flexibility and hardly anything we need to configure for Volumio, the extlinux.conf option in the boot partition is all we need.
43 | The file is located in boot/extlinux and has the following content, adapted from one of the Asus prebuilt images:
44 |
45 | label kernel-4.4
46 | kernel /zImage
47 | fdt /dtb/rk3288-miniarm.dtb
48 | initrd /uInitrd
49 | append earlyprintk console=tty1 console=ttyS1,115200n8 imgpart=/dev/mmcblk0p2 imgfile=/volumio_current.sqsh
50 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/14_Saving_Files_To_The_Platform_Folder.md:
--------------------------------------------------------------------------------
1 | ## Saving the files to the Platform Folder ##
2 |
3 | We are now ready to save all he files to the platform-asus folder, where they can be picked up to be used from the volumio tinker board build script.
4 |
5 | ### Assumptions ###
6 |
7 | DESTDIR=$HOME/asus-build/platform-asus/tinkerboard
8 | KERNELDIR=$HOME/linux-asus
9 | UBOOTDIR=$HOME/u-boot
10 |
11 | ### u-boot ###
12 | Assuming you compiled u-boot from the guideline above, you already saw how the u-boot image landet in the latform folder.
13 | For the kernel we want to do a little more. It is always handy to the last few kernel configurations.
14 | It is good practise, to copy the current kernel config to the boot folder. In the boot folder should only hold the current one.
15 | Chapter 2 also showed how to save the config to the kernel.
16 | To help identify the con fig file, I like adding the kernel version to the filename, including a timestamp.
17 |
18 | kver=`make kernelrelease`-`date +%Y.%d.%m-%H.%M`
19 | rm $DESTDIR/boot/config*
20 | cp .config $DESTDIR/boot/config-${kver}
21 | cp .config $DESTDIR/config-${kver}
22 |
23 | ### Kernel ###
24 | Next step is to save the kernel, in this case a zImage, and the dts
25 |
26 | cp arch/arm/boot/zImage $DESTDIR/boot
27 | cp arch/arm/boot/dts/*.dtb $DESTDIR/boot/dtb
28 |
29 | ### Modules and firmware ###
30 | For building an image, the only thing missing are the modules and firmware.
31 | Best is to delete the previous lib folder, avoiding the risk to save the ones from an older kernel version
32 |
33 | rm -r $DESTDIR/lib
34 | make modules_install ARCH=arm INSTALL_MOD_PATH=$DESTDIR
35 | make firmware_install ARCH=arm INSTALL_FW_PATH=$DESTDIR/lib/firmware
36 |
37 | ### Patches and other files ###
38 | As we do not want to loose the patches, we save these as well (though we only need these once after cloning the repos.
39 |
40 | git diff > $DESTDIR/tinkerboard/patches/Volumio-Kernel.patches
41 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/15_A_Complete_Script.md:
--------------------------------------------------------------------------------
1 | ## Creating a complete Script for compiling U-Boot and Kernel ##
2 |
3 |
4 | #!/bin/sh
5 | DESTDIR=$HOME/asus-build/platform-asus/tinkerboard
6 | KERNELDIR=$HOME/linux-asus
7 | UBOOTDIR=$HOME/u-boot
8 | TARDIR=/media/nas/asus
9 |
10 | echo "Compiling u-boot..."
11 | cd $UBOOTDIR
12 | touch .scmversion
13 | make clean
14 | make tinker-rk3288_defconfig
15 | make -j8
16 |
17 | echo "Create u-boot image..."
18 | mkimage -n rk3288 -T rksd -d spl/u-boot-spl-dtb.bin $DESTDIR/u-boot/u-boot.img
19 | cat u-boot-dtb.bin >> $DESTDIR/u-boot/u-boot.img
20 |
21 | cd $KERNELDIR
22 | echo "Cleaning kernel folder..."
23 | touch .scmversion
24 | make clean
25 |
26 | echo "Configuring options..."
27 | make tinker-rockchip_defconfig
28 | make menuconfig
29 | cp .config.old arch/arm/configs/tinker-rockchip_defconfig.old
30 | cp .config arch/arm/configs/tinker-rockchip_defconfig
31 |
32 | echo "Compiling the kernel..."
33 | make -j12
34 |
35 | echo "Saving configuration..."
36 | kver=`make kernelrelease`-`date +%Y.%d.%m-%H.%M`
37 | rm $DESTDIR/boot/config*
38 | cp .config $DESTDIR/boot/config-${kver}
39 | cp .config $DESTDIR/config-${kver}
40 |
41 | echo "Saving kernel and dtb's..."
42 | cp arch/arm/boot/zImage $DESTDIR/boot
43 | cp arch/arm/boot/dts/*.dtb $DESTDIR/boot/dtb
44 |
45 | echo "Saving modules and firmware..."
46 | rm -r $DESTDIR/lib
47 | make modules_install ARCH=arm INSTALL_MOD_PATH=$DESTDIR
48 | make firmware_install ARCH=arm INSTALL_FW_PATH=$DESTDIR/lib/firmware
49 |
50 | echo "Saving Volumio kernel patches"
51 | git diff > $DESTDIR/tinkerboard/patches/Volumio-Kernel.patches
52 |
53 | echo "Backup platform files..."
54 | cd $TARDIR
55 | tar cfvJ tinkerboard.tar.xz ./tinkerboard
56 | echo "Creating platform files completed"
57 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/17_1_How_To_Build_A_Sparky.md:
--------------------------------------------------------------------------------
1 | ## Allo Sparky-build
2 | Scripts to help build an Allo Sparky image
3 |
4 | #### Prerequisites
5 |
6 | ```
7 | git squashfs-tools kpartx multistrap qemu-user-static samba debootstrap parted dosfstools qemu binfmt-support qemu-utils
8 | ```
9 |
10 | It is recommended, not a necessity, to use Debian Jessie 8 (as that's what we are building for).
11 | If on Ubuntu, you may need to remove `$forceyes` from line 989 of /usr/sbin/multistrap
12 |
13 | ### How to
14 | #### Prepare
15 | - clone the help scripts repo to $HOME :
16 | git clone http://github.com/gkkpch/sparky-build $HOME/sparky-build
17 | - go to $HOME/sparky-build, type
18 | ```
19 | ./infrainit.sh
20 | ```
21 | This will
22 | - clone the sparky kernel repo to $HOME/sparky-linux
23 | - clone the official Volumio 2 build repo to $HOME/volumio-build
24 | - place the default platform-sparky files into the volumio-build folder
25 |
26 | #### Build the platform files
27 | - go to $HOME/sparky-build to start the kernel build, type:
28 |
29 | ```
30 | ./build-kernel.sh
31 | ```
32 | In case you don't need kernel config changes, just exit menuconfig.
33 | Otherwise do not forget to save the config (via menu or when prompted).
34 |
35 | #### Build Sparky Image
36 | - goto $HOME/volumio-build and type:
37 |
38 | ```
39 | sudo ./build.sh -b arm -d sparky -v -
40 | ```
41 |
42 | You can do it separate, rootfs first and then the image:
43 |
44 | ```
45 | sudo ./build.sh -b arm
46 | sudo ./build.sh -d sparky -v -
47 | ```
48 |
49 | Once you built the arm rootfs, there is no need to repeat this (unless volumio has changed).
50 | For subsequent image builds, just do:
51 |
52 | ```
53 | sudo ./build.sh -d sparky -v -
54 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/19_Creating_the_image_build_scripts (Part 2).md:
--------------------------------------------------------------------------------
1 | ## Creating the Image Build Script (Part 2)
2 | For the config script we use the corresponding __odroidc1config.sh__ as a template.
3 | This chapter will describe which parts need to be adjusted and for what reason.
4 | For the complete template script see ____
5 | The resulting tinkerimage.sh can be found [__here__](http://github.com/volumio/Build/scripts/tinkerconfig.sh)
6 | The parts of the C1 template which are not mentioned here are considered generic and unlikely candidates for changes.
7 | ### Creating fstab
8 | Just change the description in line 1.
9 | This part is standard in most implementations we encountered as most devices boot from mmcblk0, independent of SD or eMMC.
10 | That said, this may call for a future change.
11 | Newer devices using mainline u-boot and offering boot from emmc and sd are now using different devices.
12 | This may require the UUID for locating the correct boot device as we do not want to produce separate images for booting from SD or eMMC.
13 | An example implementation "by_UUID" you will find in the x86 build scripts.
14 | ### Adding default sound modules ###
15 | Tinkerboard does not (yet) support i2s devices, so no need to load sound modules.
16 | This may chnage in future releases.
17 | ### init script ###
18 | Tinkerboard is still headless, C1 uses a script to initialise the framebuffer at an early stage (C1-init.sh).
19 | In case Tinkerboard needs this, add it to the tinker init script, which was implemented like this:
20 |
21 | echo "#!/bin/sh
22 | echo 2 > /proc/irq/45/smp_affinity
23 | " > /usr/local/bin/tinker-init.sh
24 | chmod +x /usr/local/bin/tinker-init.sh
25 |
26 | echo "#!/bin/sh -e
27 | /usr/local/bin/tinker-init.sh
28 | exit 0" > /etc/rc.local
29 | Currently, the init script changes the usb interrupt CPU affinity (from CPU0 to CPU1).
30 | This was done to avoid possible crackling and dropouts on usb audio.
31 | The script runs when rc.local is called at boot time.
32 | ### Additional packages ###
33 | lirc is installed, but no specific configuration for a remote is present yet.
34 | It defaults to a small remote Hardkernel offers for the C1/C2.
35 | As no framebuffer initialisation is done, package "fbset" is not needed and removed.
36 |
--------------------------------------------------------------------------------
/docs/05_Porting_Guide/img/uart-intfc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/05_Porting_Guide/img/uart-intfc.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/01_Preparing_your_system.md:
--------------------------------------------------------------------------------
1 | ## Preparing Your system
2 |
3 | To start install the plugin following the instructions on the [ : Brutefir Git-hub](https://github.com/balbuze/volumio-plugins/tree/master/plugins/audio_interface/brutefir3) page. Then follow the following instructions:
4 |
5 | 1. Once the plugin is installed, enabled it wait about 20 sec. Don't try to make any change in Volumio playback.
6 | 2. The plugin will prompt you to reboot in order to perform hardware detection. Most of the time, a __reboot__ is required to get good values.
7 | 3. After a reboot try to play a track, if the music is playing, go to the next step.
8 | - If an error occurs go in plugin settings and try to change __Output Format__ and __Sample Rate__. These are DAC dependant parameters.
9 | 4. You can now test with a filter, just select __demo-left.pcm__ and __demo-right.pcm__ in plugin settings: (a few filters to test are installed by the plugin, they are placed in `/data/INTERNAL/Dsp/filters`) and press `Apply`. This can be done while playing. You should hear the difference.
10 | - __Important:__ Applying filters will display a prompt to Test Clipping and set Attenuation. This is done by playing full volume pink noise. If your DAC support a volume mixer, it should be mute. In other case __Turn down your volume before pressing `Test`__
11 |
12 | ### Now, let's see how to create your own filter, just designed for your hardware and room!
13 | Go to [next page](02_Making_Measurment.md).
14 |
15 | ---
16 | ## Interface screenshots
17 |
18 | __Main Interface of the plugin__
19 |
20 |
21 |
22 |
23 | __Filter Advanced Settings__
24 |
25 |
26 |
27 |
28 | __VoBAF settings (optional)__
29 |
30 |
31 |
32 |
33 | __Filter Creation (described in the following pages)__
34 |
35 |
36 |
37 |
38 | __Tools (described in the following pages)__
39 |
40 |
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/VoBAF-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/VoBAF-settings.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/export_impulse.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/export_impulse.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/filter-creation-menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/filter-creation-menu.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/first_filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/first_filter.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/general_plugin_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/general_plugin_settings.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/install_tools.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/install_tools.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/list_sweep_files.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/list_sweep_files.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/make_a_measurment.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/make_a_measurment.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/preferences_micmeter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/preferences_micmeter.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/rePhase_import.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/rePhase_import.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/rephase_import_REW_filter_settings.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/rephase_import_REW_filter_settings.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/rew1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/rew1.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/rew_EQ_window.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/rew_EQ_window.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/rew_preferences.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/rew_preferences.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/rew_rta_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/rew_rta_settings.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/room-settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/room-settings.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/room_settings_values.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/room_settings_values.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/select_filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/select_filter.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/sofa_front.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/sofa_front.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/sofa_iso.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/sofa_iso.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/sofa_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/sofa_top.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/00_brutefir/img/using_filter_in_volumio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/00_brutefir/img/using_filter_in_volumio.png
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/02_Device_Tree_Overlays.md:
--------------------------------------------------------------------------------
1 | ## Linux Device Tree Overlay: Rotary Encoder
2 | Even with a perfect signal from RC-filter and Schmitt-trigger, there were still missed ticks sometimes. I could solve that by moving to the DT overlay driver for rotary encoders.
3 |
4 | Raspbian (and Volumio) support it out of the box. If you load the device-tree overlay for a rotary, you no longer need to take care of the Gray-Code and just hook up to a device that will nicely send you information about turns of the rotary encoder (relative or absolute, the plugin only supports relative so far).
5 |
6 | The advantages of the dtoverlay solution:
7 | - Very fast response, due to Kernel level implementation
8 | - Versatile driver for use with all kinds of encoder types
9 | - The dtoverlays can dynamically be loaded and unloaded, so integration was quite straightforward.
10 |
11 | The plugin basically executes calls to dtoverlay for adding and removing overlays:
12 | To add a rotary:
13 | ```
14 | sudo dtoverlay rotary-encoder pin_a=17 pin_b=27 relative_axis=1 steps-per-period=2
15 | ```
16 | To remove a rotary:
17 | ```
18 | sudo dtoverlay -r
19 | ```
20 |
21 | The plugin is doing this when you change and save settings. You do not need to go to the command line.
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/03_Compatible_Encoders.md:
--------------------------------------------------------------------------------
1 | ## List of compatible Rotary Encoders
2 | The list currently lists only the ALPS Encoder I used for my project. I am convinced, that it works with others as well. I found some other projects using dtoverlay that use KY040 for example or other ALPS types.
3 | **_Please add yours to the list to help others. If you do not know how to edit this file in Github, create an issue with the information and I will integrate it someday._**
4 |
5 | |Manufacturer|Model |Periods/Position|HW-Debounce used |Tested by |
6 | |------------|------------|----------------|---------------------|-------------------|
7 | |ALPS |STEC11B03 | 1/2 |RC + Schmitt-Trigger |[7h0mas-R](https://github.com/7h0mas-R) |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/04_Appendix.md:
--------------------------------------------------------------------------------
1 | ## Potential future extensions
2 | - add the other parameters offered by the dtoverlay (e.g. absolute positioning, binary instead of Gray-code etc.)
3 | - Add support for more than 3 encoders
4 | - Add support for dtoverlays loaded at boot (similar to overlays for I2S DACs)
5 |
6 | ## Known issues and limitations
7 | ### Kernel warning when last overlay is removed
8 | When the plugin is disabled, a kernel warning message about a potential memory leak is displayed when the last overlay is removed. I tried several things to prevent it and posted to several forums looking for help, but could not get rid of it.
9 | I consider it as not nice, but I could also not observe any issue after multiple disable/enable loops - so I decided to keep it as is for the time being.
10 | During normal use, the plugin will be configured once only and then loaded at boot and unloaded at shutdown - so you should never experience an issue. I use it for several months already without issues.
11 |
12 |
13 | ## References
14 | ### Device Tree Documentation
15 | - [Kernel Documentation: rotary-encoder](https://www.kernel.org/doc/Documentation/input/rotary-encoder.txt)
16 | Explains more about how a rotary works and how the DTOverlay is implemented
17 | - [Documentation of the `dtoverlay` command](https://github.com/raspberrypi/firmware/blob/master/boot/overlays/README)
18 | Search for 'rotary-encoder'. Alternatively, you can call
19 | ```
20 | dtoverlay -h rotary-encoder
21 | ```
22 | from the command line.
23 | - [Documentation of the Raspberry Device Tree](https://www.raspberrypi.org/documentation/configuration/device-tree.md)
24 | If you would like to learn more about the details of the dtoverlay function.
25 |
26 | ### NPM modules used
27 | - [onoff](https://www.npmjs.com/search?q=onoff)
28 | Since it was easier to implement and does not have any issues, I still use _onoff_ for the push button. This could also be done with _dtoverlay_, but seems too much effort since it does not provide additional performance.
29 |
30 | ### Hardware Resources
31 | - [RPi GPIOs](https://www.raspberrypi.org/documentation/hardware/raspberrypi/gpio/README.md)
32 |
33 |
34 |
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/RC-Schmitt.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/RC-Schmitt.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/RC-debounced.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/RC-debounced.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/RC-debounced2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/RC-debounced2.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/RC-filter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/RC-filter.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/Schmitt-Trigger.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/Schmitt-Trigger.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/Schmitt-Trigger2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/Schmitt-Trigger2.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/bouncy_rotary.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/bouncy_rotary.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/rotary_types.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/rotary_types.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/settings_en.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/settings_en.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/settings_en.pxm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/settings_en.pxm
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/tau_charge.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/tau_charge.jpg
--------------------------------------------------------------------------------
/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/tau_discharge.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/06_Plugins_User_Manuals/01_rotaryencoder2/img/tau_discharge.jpg
--------------------------------------------------------------------------------
/docs/07_Good_to_Knows/02_Mounting_an_NFS_Share.md:
--------------------------------------------------------------------------------
1 | ## Adding Music from a shared folder on a Synology
2 |
3 | The following has been tested on a Synology DS412 in combination with Volumio 0.978 for Raspberry Pi 3.
4 |
5 | Since both Synology and Volumio for Raspberry Pi are Unix based the preference is to use NFS (Network File System) type file sharing. More information about NFS is available [on Wikipedia](https://en.wikipedia.org/wiki/Network_File_System).
6 |
7 | #### Synology preparation
8 |
9 | To enable NFS on Synology follow the [detailed guide from Synology](https://www.synology.com/en-global/knowledgebase/DSM/tutorial/File_Sharing/How_to_access_files_on_Synology_NAS_within_the_local_network_NFS). This guide explains in great detail the steps required.
10 |
11 | The final NFS rule configuration is shown in the following screenshot. The most important part is the `Squash` setting. The required access is `RW` and since it's wise to disable the Guest account on your Synology, the `Squash` setting must be set to `Map all users to admin`.
12 |
13 |
14 |
15 | #### Volumio preparation
16 |
17 | - Go to `Settings > My Music`
18 | - Press `+ Add New Drive`
19 | - Make sure you configure the share as shown in the screenshot below. `volume1` is normally the first part of the path, followed by the name of your share (in this case, `Music`)
20 |
21 | Since we are using an NFS share, no username nor password are required.
22 |
23 |
24 |
--------------------------------------------------------------------------------
/docs/07_Good_to_Knows/03_Contribute_to_this_Doc.md:
--------------------------------------------------------------------------------
1 | ## Contribute to this Documentation
2 |
3 | Everyone knows how tedious it is to write documentation. But it is extremely important for every project, especially for Volumio. So if you find something incomplete, missing or
4 | wrong feel free to edit this doc and improve it.
5 |
6 | If you don't feel like editing this doc yourself, you can at least tell us what you would change [here](https://volumio.org/forum/documentation-feedback-t6425.html)!
7 |
8 | #### How this doc works
9 |
10 | This DOC is powered by [DAUX.IO](http://daux.io/) and the source is hosted on the [Github Volumio docs repository](https://github.com/volumio/docs). To edit it, simply clone it, edit the
11 | pages located under /docs and issue a pull request. You can do so either via command line or with a graphical tool, I personally suggest [GitKraken](https://www.gitkraken.com/).
12 |
13 |
14 | #### Cloning and issuing a Pull request
15 |
16 | 1. Clone it
17 | ```bash
18 | https://github.com/volumio/docs.git
19 | ```
20 |
21 | 2. Edit it
22 | * I suggest [Atom.io IDE](https://atom.io/) together with [Markdown Preview](https://atom.io/packages/markdown-preview) but any text editor will do
23 | * Make sure you comply with [DAUX rules](http://daux.io/Getting_Started) (if you create a new page, don't use spaces but _ and make sure the name ends with .md)
24 | * This doc is written in Markdown language, and automatically converted to html. See the [Markdown Cheatsheet](../Good_to_Knows/Markdown_Cheatsheet) to get used to it
25 |
26 | 3. Commit it
27 |
28 | ```bash
29 | git commit -m "Hey I changed this and that"
30 | ```
31 |
32 | 4. Issue a pull request
33 |
34 | 5. Once your PR gets accepted, in 2 minutes your contribution will be available to the whole community.
35 |
36 |
37 | #### See changes live
38 |
39 | To see your changes live, just download and launch any [XAMMP environment](https://www.apachefriends.org/en/index.html) to expose a php-capable local web server, and clone the docs
40 | under your htdocs folder. Docs will update in realtime and will be available under `http://localhost/docs`
41 |
42 | You don't even need XAMMP.
43 | * make your modifications
44 | * in the top level of the project run:
45 | ```bash
46 | $ php generate
47 | ```
48 | This will generate the documentation in the ```static/``` folder
49 | * in your browser, navigate to ```file:///path/to/doc-clone/static```
50 | * when you are satisfied, commit the changes
51 |
--------------------------------------------------------------------------------
/docs/07_Good_to_Knows/04_Connection_Outside_LAN.md:
--------------------------------------------------------------------------------
1 | ## Connecting from Outside the LAN
2 |
3 | Sometimes it might be useful to connect to Volumio from outside the LAN, via services like NO-IP. Volumio UI uses socket.io to communicate with the backend, so we must tell the UI to connect
4 | to the external IP rather than the LAN's IP.
5 |
6 | #### Tell the UI to bind to new IP
7 |
8 | If you want to achieve this, hardcode your public IP in [https://github.com/volumio/Volumio2/blob/master/http/restapi.js](https://github.com/volumio/Volumio2/blob/master/http/restapi.js) line 49
9 |
10 | ```
11 | res.json({ host: 'http://'+self.host});
12 | ```
13 |
14 | your public ip instead of self.host
15 |
--------------------------------------------------------------------------------
/docs/08_FAQs/02_Updating_and_Maintenance.md:
--------------------------------------------------------------------------------
1 | ## Updating & Maintenance
2 |
3 | #### How do I update Volumio?
4 |
5 | Volumio features an OTA (Over The Air) updater, meant to allow a seamless and reliable way to update to new system versions. Please note that if you enable updating to intermediate beta/test versions, you risk making your system unreliable, and may need to carry out a 'factory reset' to the last stable version that you installed.
6 |
7 |
8 | Caution: do not try to update your system by using 'sudo apt-get upgrade' ... this is likely to result in a non-functional system.
9 |
10 |
11 | #### How do I do a 'factory reset?'
12 |
13 | System settings may be returned to the first version that you installed by carrying out a 'factory reset' under 'System Settings.' Note that you will lose all of your settings by applying this option.
14 |
15 | #### How can I backup my settings?
16 |
17 | It is a good idea to have a backup of your settings (NAS, playlists, webradios etc.) and this is easily achieved by use of the 'Backup and Restore' plugin.
18 |
--------------------------------------------------------------------------------
/docs/08_FAQs/04_Audio_Output.md:
--------------------------------------------------------------------------------
1 | ## Audio Output
2 |
3 | #### How do I set the audio output from Volumio?
4 |
5 | Select 'Settings', 'Playback Options', and choose your 'Output Device' from the drop down menu. If you are are NOT using an i2s device (for example a USB DAC), then ensure that the 'i2s' switch is in the 'Off' position. Choose the correct DAC model (note that some DAC models use a common driver), and save your settings. Reboot & check that the settings are retained.
6 |
7 |
8 |
9 | #### Why can't I control the volume from the Volumio UI?
10 |
11 | Not all DACs include a hardware volume control (check with your device manufacturer) which allows the changing of volume from the UI. This behaviour can be achieved in such devices by selecting the Mixer Type as 'Software', rather than 'Hardware', BUT please note that this results in a degradation of the sound quality. If this is a problem then select Mixer Type as 'None', and adjust the volume on your amplifier.
12 |
13 | #### Does Volumio support multiroom play?
14 |
15 | Volumio does allow the control of devices in different rooms from a single Volumio UI (if you have more than one device, then they will be visible in the UI).
16 |
17 |
18 |
19 |
20 | Multiroom synchronised play is also possible through the use of a 'Snapcast' plugin.
21 |
--------------------------------------------------------------------------------
/docs/08_FAQs/img/audio-output.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/08_FAQs/img/audio-output.jpg
--------------------------------------------------------------------------------
/docs/08_FAQs/img/cifs_options.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/08_FAQs/img/cifs_options.jpg
--------------------------------------------------------------------------------
/docs/08_FAQs/img/multiroom.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/docs/08_FAQs/img/multiroom.png
--------------------------------------------------------------------------------
/docs/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "title": "Volumio Documentation",
3 | "tagline": "The Audiophile Music Player",
4 | "author": "Michelangelo Guarise",
5 | "image": "images/Volumio_logo.jpg",
6 | "ignore": {
7 | "files": ["Work_In_Progress.md"],
8 | "folders": ["99_Not_Ready"]
9 | },
10 | "live": {
11 | "inherit_index": true,
12 | "clean_urls": true
13 | },
14 | "html": {
15 | "theme": "daux-blue",
16 | "template":"default",
17 | "breadcrumbs": false,
18 | "breadcrumb_separator": "Chevrons",
19 | "toggle_code": true,
20 | "date_modified": false,
21 | "float": false,
22 | "auto_landing": false,
23 |
24 |
25 | "twitter": ["volumio"],
26 | "google_analytics": "UA-46374275-1",
27 | "links": {
28 | "Home": "https://volumio.org",
29 | "Download": "https://volumio.org/get-started",
30 | "Forum": "https://volumio.org/forum",
31 | "GitHub Repo": "https://github.com/volumio",
32 | "Improve this documentation": "https://volumio.github.io/docs/Good_to_Knows/Contribute_to_this_Doc.html"
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/generate:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | run();
78 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "docs_directory": "docs",
3 | "themes_directory": "themes",
4 | "title": "My Project",
5 | "tagline": "My Stylish Documentation",
6 | "author": "I, Me & Myself",
7 | "image": "",
8 | "languages": {},
9 |
10 | "format": "html",
11 | "processor": "",
12 |
13 | "ignore": {
14 | "files": [],
15 | "folders": []
16 | },
17 |
18 | "timezone": "America/Los_Angeles",
19 |
20 | "live": {
21 | "inherit_index": false,
22 | "clean_urls": false
23 | },
24 |
25 | "html": {
26 | "theme": "daux-blue",
27 | "breadcrumbs": false,
28 | "toggle_code": false,
29 | "date_modified": false,
30 | "float": false,
31 | "auto_landing": false,
32 | "search": true,
33 | "auto_toc": false,
34 |
35 | "repo": "",
36 | "twitter": [],
37 | "links": {
38 | },
39 |
40 | "google_analytics": false,
41 | "piwik_analytics": false,
42 | "piwik_analytics_id": "0"
43 | },
44 |
45 | "confluence": {
46 | "prefix": "",
47 | "delete": false
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/libs/Config.php:
--------------------------------------------------------------------------------
1 | $value) {
16 | // If the key doesn't exist yet,
17 | // we can simply set it.
18 | if (!array_key_exists($key, $this)) {
19 | $this[$key] = $value;
20 | continue;
21 | }
22 |
23 | // We already know this value exists
24 | // so if we're in conservative mode
25 | // we can skip this key
26 | if ($override === false) {
27 | continue;
28 | }
29 |
30 | // Merge the values only if
31 | // both values are arrays
32 | if (is_array($this[$key]) && is_array($value)) {
33 | $this[$key] = array_replace_recursive($this[$key], $value);
34 | } else {
35 | $this[$key] = $value;
36 | }
37 | }
38 | }
39 |
40 | /**
41 | * Merge an array into the object, ignore already added keys.
42 | *
43 | * @param $newValues
44 | */
45 | public function conservativeMerge($newValues)
46 | {
47 | $this->merge($newValues, false);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/libs/Console/Application.php:
--------------------------------------------------------------------------------
1 | setArguments();
46 |
47 | return $inputDefinition;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/libs/Console/RunAction.php:
--------------------------------------------------------------------------------
1 | write($title);
10 |
11 | $length = function_exists("mb_strlen")? mb_strlen($title) : strlen($title);
12 |
13 | // 8 is the length of the label + 2 let it breathe
14 | $padding = $width - $length - 10;
15 | try {
16 | $response = $closure();
17 | } catch (\Exception $e) {
18 | $output->writeln(str_pad(" ", $padding) . "[ FAIL ]");
19 | throw $e;
20 | }
21 | $output->writeln(str_pad(" ", $padding) . "[ OK ]");
22 |
23 | return $response;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/libs/ContentTypes/ContentType.php:
--------------------------------------------------------------------------------
1 | types = array_reverse($types);
18 | }
19 |
20 | /**
21 | * Get all valid content file extensions
22 | *
23 | * @return string[]
24 | */
25 | public function getContentExtensions()
26 | {
27 | $extensions = [];
28 | foreach ($this->types as $type) {
29 | $extensions = array_merge($extensions, $type->getExtensions());
30 | }
31 |
32 | return array_unique($extensions);
33 | }
34 |
35 | /**
36 | * Get the ContentType able to handle this node
37 | *
38 | * @param Content $node
39 | * @return ContentType
40 | */
41 | public function getType(Content $node)
42 | {
43 | $path = $node->getPath() ?: $node->getName();
44 | $extension = pathinfo($path, PATHINFO_EXTENSION);
45 |
46 | foreach ($this->types as $type) {
47 | if (in_array($extension, $type->getExtensions())) {
48 | return $type;
49 | }
50 | }
51 |
52 | throw new \RuntimeException("no contentType found for $path");
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/libs/ContentTypes/Markdown/CommonMarkConverter.php:
--------------------------------------------------------------------------------
1 | mergeConfig($config);
23 | $environment->addExtension(new TableExtension());
24 |
25 | // Table of Contents
26 | $environment->addBlockParser(new TableOfContentsParser());
27 |
28 | $this->extendEnvironment($environment, $config['daux']);
29 |
30 | if (array_key_exists('processor_instance', $config['daux'])) {
31 | $config['daux']['processor_instance']->extendCommonMarkEnvironment($environment);
32 | }
33 |
34 | $this->docParser = new DocParser($environment);
35 | $this->htmlRenderer = new HtmlRenderer($environment);
36 | }
37 |
38 | protected function getLinkRenderer(Environment $environment)
39 | {
40 | return new LinkRenderer($environment->getConfig('daux'));
41 | }
42 |
43 | protected function extendEnvironment(Environment $environment, Config $config)
44 | {
45 | $environment->addInlineRenderer('Link', $this->getLinkRenderer($environment));
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/libs/ContentTypes/Markdown/ContentType.php:
--------------------------------------------------------------------------------
1 | config = $config;
17 | $this->converter = new CommonMarkConverter(['daux' => $config]);
18 | }
19 |
20 | /**
21 | * @return array
22 | */
23 | public function getExtensions()
24 | {
25 | return ['md', 'markdown'];
26 | }
27 |
28 | public function convert($raw, Content $node)
29 | {
30 | return $this->converter->convertToHtml($raw);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/libs/ContentTypes/Markdown/LinkRenderer.php:
--------------------------------------------------------------------------------
1 | daux = $daux;
22 | }
23 |
24 | /**
25 | * @param string $url
26 | * @return Entry
27 | * @throws Exception
28 | */
29 | protected function resolveInternalFile($url)
30 | {
31 | $file = DauxHelper::getFile($this->daux['tree'], $url);
32 | if ($file) {
33 | return $file;
34 | }
35 |
36 | $file = DauxHelper::getFile($this->daux['tree'], $url . '.html');
37 | if ($file) {
38 | return $file;
39 | }
40 |
41 | throw new Exception("Could not locate file '$url'");
42 | }
43 |
44 | /**
45 | * @param Link $inline
46 | * @param ElementRendererInterface $htmlRenderer
47 | *
48 | * @return HtmlElement
49 | */
50 | public function render(AbstractInline $inline, ElementRendererInterface $htmlRenderer)
51 | {
52 | // This can't be in the method type as
53 | // the method is an abstract and should
54 | // have the same interface
55 | if (!$inline instanceof Link) {
56 | throw new \RuntimeException(
57 | "Wrong type passed to " . __CLASS__ . "::" . __METHOD__ .
58 | " the expected type was 'League\\CommonMark\\Inline\\Element\\Link' but '" .
59 | get_class($inline) . "' was provided"
60 | );
61 | }
62 |
63 | $element = parent::render($inline, $htmlRenderer);
64 |
65 | $url = $inline->getUrl();
66 | if (!empty($url) && $url[0] == '!') {
67 | $file = $this->resolveInternalFile(ltrim($url, "!"));
68 |
69 | $element->setAttribute('href', $this->daux['base_url'] . $file->getUrl());
70 | }
71 |
72 | return $element;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/libs/ContentTypes/Markdown/TableOfContents.php:
--------------------------------------------------------------------------------
1 | isIndented()) {
19 | return false;
20 | }
21 |
22 | $previousState = $cursor->saveState();
23 | $cursor->advanceToFirstNonSpace();
24 | $fence = $cursor->match('/^\[TOC\]/');
25 | if (is_null($fence)) {
26 | $cursor->restoreState($previousState);
27 |
28 | return false;
29 | }
30 |
31 | $context->addBlock(new TableOfContents());
32 |
33 | return true;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/libs/Exception.php:
--------------------------------------------------------------------------------
1 | raw = $content;
12 | }
13 |
14 | public function getContent()
15 | {
16 | return $this->raw->getContent();
17 | }
18 |
19 | public function getPureContent()
20 | {
21 | return $this->raw->getContent();
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/libs/Format/Base/ContentPage.php:
--------------------------------------------------------------------------------
1 | initializePage($title, $content);
29 | }
30 |
31 | public function setFile(Content $file)
32 | {
33 | $this->file = $file;
34 | }
35 |
36 | public function getFile()
37 | {
38 | return $this->file;
39 | }
40 |
41 | public function setParams(Config $params)
42 | {
43 | $this->params = $params;
44 | }
45 |
46 | /**
47 | * @param ContentType $contentType
48 | */
49 | public function setContentType($contentType)
50 | {
51 | $this->contentType = $contentType;
52 | }
53 |
54 | public function getPureContent()
55 | {
56 | if (!$this->generatedContent) {
57 | $this->generatedContent = $this->contentType->convert($this->content, $this->getFile());
58 | }
59 |
60 | return $this->generatedContent;
61 | }
62 |
63 | protected function generatePage()
64 | {
65 | return $this->getPureContent();
66 | }
67 |
68 | public static function fromFile(Content $file, $params, ContentType $contentType)
69 | {
70 | $page = new static($file->getTitle(), $file->getContent());
71 | $page->setFile($file);
72 | $page->setParams($params);
73 | $page->setContentType($contentType);
74 |
75 | return $page;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/libs/Format/Base/EmbedImages.php:
--------------------------------------------------------------------------------
1 | tree = $tree;
24 | }
25 |
26 | public function embed($page, Content $file, $callback)
27 | {
28 | return preg_replace_callback(
29 | "/]*src=['\"]([^\"]*)['\"][^>]*>/",
30 | function ($matches) use ($file, $callback) {
31 |
32 | if ($result = $this->findImage($matches[1], $matches[0], $file, $callback)) {
33 | return $result;
34 | }
35 |
36 | return $matches[0];
37 | },
38 | $page
39 | );
40 | }
41 |
42 | private function getAttributes($tag)
43 | {
44 | $dom = new DOMDocument();
45 | $dom->loadHTML($tag);
46 |
47 | $img = $dom->getElementsByTagName('img')->item(0);
48 |
49 | $attributes = ['align', 'class', 'title', 'style', 'alt', 'height', 'width'];
50 | $used = [];
51 | foreach ($attributes as $attr) {
52 | if ($img->attributes->getNamedItem($attr)) {
53 | $used[$attr] = $img->attributes->getNamedItem($attr)->value;
54 | }
55 | }
56 |
57 | return $used;
58 | }
59 |
60 | private function findImage($src, $tag, Content $file, $callback)
61 | {
62 | //for protocol relative or http requests : keep the original one
63 | if (substr($src, 0, strlen("http")) === "http" || substr($src, 0, strlen("//")) === "//") {
64 | return $src;
65 | }
66 |
67 | //Get the path to the file, relative to the root of the documentation
68 | $url = DauxHelper::getCleanPath(dirname($file->getUrl()) . '/' . $src);
69 |
70 | //Get any file corresponding to the right one
71 | $file = DauxHelper::getFile($this->tree, $url);
72 |
73 |
74 | if ($file === false) {
75 | return false;
76 | }
77 |
78 | $result = $callback($src, $this->getAttributes($tag), $file);
79 |
80 | return $result ?: $src;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/libs/Format/Base/Generator.php:
--------------------------------------------------------------------------------
1 | file = $filename;
12 | }
13 |
14 | public function getFile()
15 | {
16 | return $this->file;
17 | }
18 |
19 | public function getPureContent()
20 | {
21 | throw new Exception("you should not use this method to show a raw content");
22 | }
23 |
24 | public function getContent()
25 | {
26 | throw new Exception("you should not use this method to show a raw content");
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/libs/Format/Base/SimplePage.php:
--------------------------------------------------------------------------------
1 | initializePage($title, $content);
12 | }
13 |
14 | public function getPureContent()
15 | {
16 | return $this->content;
17 | }
18 |
19 | public function getContent()
20 | {
21 | if (is_null($this->generated)) {
22 | $this->generated = $this->generatePage();
23 | }
24 |
25 | return $this->generated;
26 | }
27 |
28 | protected function initializePage($title, $content)
29 | {
30 | $this->title = $title;
31 | $this->content = $content;
32 | }
33 |
34 | protected function generatePage()
35 | {
36 | return $this->content;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/libs/Format/Confluence/ContentPage.php:
--------------------------------------------------------------------------------
1 | params['tree']))
17 | ->embed(
18 | $content,
19 | $this->file,
20 | function ($src, array $attributes, Raw $file) {
21 | $filename = basename($file->getPath());
22 |
23 | //Add the attachment for later upload
24 | $this->attachments[$filename] = ['filename' => $filename, 'file' => $file];
25 |
26 | return $this->createImageTag($filename, $attributes);
27 | }
28 | );
29 |
30 |
31 | $intro = '';
32 | if (array_key_exists('confluence', $this->params) && array_key_exists('header', $this->params['confluence']) && !empty($this->params['confluence']['header'])) {
33 | $intro = '' . $this->params['confluence']['header'] . '';
34 | }
35 |
36 | return $intro . $content;
37 | }
38 |
39 | private function createImageTag($filename, $attributes)
40 | {
41 | $img = " $value) {
44 | $img .= ' ac:' . $name . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"';
45 | }
46 |
47 | $img .= ">";
48 |
49 | return $img;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/libs/Format/Confluence/ContentTypes/Markdown/CommonMarkConverter.php:
--------------------------------------------------------------------------------
1 | getConfig('daux'));
11 | }
12 |
13 | protected function extendEnvironment(Environment $environment, Config $config)
14 | {
15 | parent::extendEnvironment($environment, $config);
16 |
17 | $environment->addBlockRenderer('Todaymade\Daux\ContentTypes\Markdown\TableOfContents', new TOCRenderer());
18 |
19 | //Add code renderer
20 | $environment->addBlockRenderer('FencedCode', new FencedCodeRenderer());
21 | $environment->addBlockRenderer('IndentedCode', new IndentedCodeRenderer());
22 |
23 | $environment->addInlineRenderer('Image', new ImageRenderer());
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/libs/Format/Confluence/ContentTypes/Markdown/ContentType.php:
--------------------------------------------------------------------------------
1 | config = $config;
10 | $this->converter = new CommonMarkConverter(['daux' => $config]);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/libs/Format/Confluence/ContentTypes/Markdown/FencedCodeRenderer.php:
--------------------------------------------------------------------------------
1 | 'html/xml', 'xml' => 'html/xml', 'js' => 'javascript'];
38 |
39 | /**
40 | * @param AbstractBlock $block
41 | * @param HtmlRendererInterface $htmlRenderer
42 | * @param bool $inTightList
43 | *
44 | * @return HtmlElement|string
45 | */
46 | public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, $inTightList = false)
47 | {
48 | if (!($block instanceof FencedCode)) {
49 | throw new \InvalidArgumentException('Incompatible block type: ' . get_class($block));
50 | }
51 |
52 | $content = [];
53 |
54 | if ($language = $this->getLanguage($block->getInfoWords(), $htmlRenderer)) {
55 | $content[] = new HtmlElement('ac:parameter', ['ac:name' => 'language'], $language);
56 | }
57 |
58 | $content[] = new HtmlElement('ac:plain-text-body', [], 'getStringContent() . ']]>');
59 |
60 | return new HtmlElement(
61 | 'ac:structured-macro',
62 | ['ac:name' => 'code'],
63 | $content
64 | );
65 | }
66 |
67 | public function getLanguage($infoWords, ElementRendererInterface $htmlRenderer)
68 | {
69 | if (count($infoWords) === 0 || strlen($infoWords[0]) === 0) {
70 | return false;
71 | }
72 |
73 | $language = $htmlRenderer->escape($infoWords[0], true);
74 |
75 | if (array_key_exists($language, $this->known_conversions)) {
76 | $language = $this->known_conversions[$language];
77 | }
78 |
79 | if (in_array($language, $this->supported_languages)) {
80 | return $language;
81 | }
82 |
83 | return false;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/libs/Format/Confluence/ContentTypes/Markdown/ImageRenderer.php:
--------------------------------------------------------------------------------
1 | getUrl(), 'http') === 0) {
20 | return new HtmlElement(
21 | 'ac:image',
22 | [],
23 | new HtmlElement('ri:url', ['ri:value' => $inline->getUrl()])
24 | );
25 | }
26 |
27 | return parent::render($inline, $htmlRenderer);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/libs/Format/Confluence/ContentTypes/Markdown/IndentedCodeRenderer.php:
--------------------------------------------------------------------------------
1 | 'code'],
27 | new HtmlElement('ac:plain-text-body', [], 'getStringContent() . ']]>')
28 | );
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/libs/Format/Confluence/ContentTypes/Markdown/LinkRenderer.php:
--------------------------------------------------------------------------------
1 | getUrl();
32 | if (empty($url) || $url[0] != '!') {
33 | return $element;
34 | }
35 |
36 | //Internal links
37 | $file = $this->resolveInternalFile(ltrim($url, "!"));
38 |
39 | $link_props = [
40 | 'ri:content-title' => trim($this->daux['confluence']['prefix']) . " " . $file->getTitle(),
41 | 'ri:space-key' => $this->daux['confluence']['space_id']
42 | ];
43 |
44 | $page = strval(new HtmlElement('ri:page', $link_props, '', true));
45 | $children = $htmlRenderer->renderInlines($inline->children());
46 | if (strpos($children, "<") !== false) {
47 | $children = '' . $children . '';
48 | } else {
49 | $children = '';
50 | }
51 |
52 | return new HtmlElement('ac:link', [], $page . $children);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/libs/Format/Confluence/ContentTypes/Markdown/TOCRenderer.php:
--------------------------------------------------------------------------------
1 | ';
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/libs/Format/Confluence/DuplicateTitleException.php:
--------------------------------------------------------------------------------
1 | addDocumentProcessor(new TOC\Processor($config));
13 | $environment->addBlockRenderer('Todaymade\Daux\ContentTypes\Markdown\TableOfContents', new TOC\Renderer());
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/libs/Format/HTML/ContentTypes/Markdown/ContentType.php:
--------------------------------------------------------------------------------
1 | config = $config;
10 | $this->converter = new CommonMarkConverter(['daux' => $config]);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/libs/Format/HTML/ContentTypes/Markdown/TOC/Entry.php:
--------------------------------------------------------------------------------
1 | content = $content;
15 | $this->level = $content->getLevel();
16 | }
17 |
18 | /**
19 | * @return string
20 | */
21 | public function getId()
22 | {
23 | return $this->content->data['attributes']['id'];
24 | }
25 |
26 | /**
27 | * @return int
28 | */
29 | public function getLevel()
30 | {
31 | return $this->level;
32 | }
33 |
34 | /**
35 | * @return Entry
36 | */
37 | public function getParent()
38 | {
39 | return $this->parent;
40 | }
41 |
42 | /**
43 | * @return Heading
44 | */
45 | public function getContent()
46 | {
47 | return $this->content;
48 | }
49 |
50 | /**
51 | * @return Entry[]
52 | */
53 | public function getChildren()
54 | {
55 | return $this->children;
56 | }
57 |
58 | /**
59 | * @param Entry $parent
60 | * @param bool $addChild
61 | */
62 | public function setParent(Entry $parent, $addChild = true)
63 | {
64 | $this->parent = $parent;
65 | if ($addChild) {
66 | $parent->addChild($this);
67 | }
68 | }
69 |
70 | /**
71 | * @param Entry $child
72 | */
73 | public function addChild(Entry $child)
74 | {
75 | $child->setParent($this, false);
76 | $this->children[] = $child;
77 | }
78 |
79 | public function toString()
80 | {
81 | return $this->getLevel() . " - " . $this->getId();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/libs/Format/HTML/ContentTypes/Markdown/TOC/Renderer.php:
--------------------------------------------------------------------------------
1 | renderBlocks($block->children());
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/libs/Format/HTML/ContentTypes/Markdown/TOC/RootEntry.php:
--------------------------------------------------------------------------------
1 | content = null;
8 | $this->level = 0;
9 | }
10 |
11 | /**
12 | * @return Entry
13 | */
14 | public function getParent()
15 | {
16 | throw new \RuntimeException("No Parent Exception");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/libs/Format/HTML/RawPage.php:
--------------------------------------------------------------------------------
1 | params['tree']))
17 | ->embed(
18 | $content,
19 | $this->file,
20 | function ($src, array $attributes, Raw $file) {
21 |
22 | $content = base64_encode(file_get_contents($file->getPath()));
23 | $attr = '';
24 | foreach ($attributes as $name => $value) {
25 | $attr .= ' ' .$name . '="' . htmlentities($value, ENT_QUOTES, 'UTF-8', false) . '"';
26 | }
27 |
28 | return "";
29 | }
30 | );
31 |
32 | return $content;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/libs/GeneratorHelper.php:
--------------------------------------------------------------------------------
1 | getFilename() === '.' || $file->getFilename() === '..') {
37 | continue;
38 | }
39 | if ($file->isDir()) {
40 | rmdir($file->getRealPath());
41 | } else {
42 | unlink($file->getRealPath());
43 | }
44 | }
45 | }
46 |
47 | /**
48 | * Copy files recursively
49 | *
50 | * @param string $source
51 | * @param string $destination
52 | */
53 | public static function copyRecursive($source, $destination)
54 | {
55 | if (!is_dir($destination)) {
56 | mkdir($destination);
57 | }
58 |
59 | $dir = opendir($source);
60 | while (false !== ($file = readdir($dir))) {
61 | if ($file != '.' && $file != '..') {
62 | if (is_dir($source . DIRECTORY_SEPARATOR . $file)) {
63 | static::copyRecursive(
64 | $source . DIRECTORY_SEPARATOR . $file,
65 | $destination . DIRECTORY_SEPARATOR . $file
66 | );
67 | } else {
68 | copy($source . DIRECTORY_SEPARATOR . $file, $destination . DIRECTORY_SEPARATOR . $file);
69 | }
70 | }
71 | }
72 | closedir($dir);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/libs/Processor.php:
--------------------------------------------------------------------------------
1 | daux = $daux;
32 | $this->output = $output;
33 | $this->width = $width;
34 | }
35 |
36 | /**
37 | * With this connection point, you can transform
38 | * the tree as you want, move pages, modify
39 | * pages and even add new ones.
40 | *
41 | * @param Root $root
42 | */
43 | public function manipulateTree(Root $root)
44 | {
45 | }
46 |
47 | /**
48 | * This connection point provides
49 | * a way to extend the Markdown
50 | * parser and renderer.
51 | *
52 | * @param Environment $environment
53 | */
54 | public function extendCommonMarkEnvironment(Environment $environment)
55 | {
56 | }
57 |
58 | /**
59 | * Provide new generators with this extension point. You
60 | * can simply return an array, the key is the format's
61 | * name, the value is a class name implementing the
62 | * `Todaymade\Daux\Format\Base\Generator` contract.
63 | * You can also replace base generators.
64 | *
65 | * @return string[]
66 | */
67 | public function addGenerators()
68 | {
69 | return [];
70 | }
71 |
72 | /**
73 | * Provide new content Types to be used during the generation
74 | * phase, with this you can change the markdown parser or add
75 | * a completely different file type.
76 | *
77 | * @return \Todaymade\Daux\ContentTypes\ContentType[]
78 | */
79 | public function addContentType()
80 | {
81 | return [];
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/libs/Server/ErrorPage.php:
--------------------------------------------------------------------------------
1 | params = $params;
26 | }
27 |
28 | /**
29 | * @return string
30 | */
31 | protected function generatePage()
32 | {
33 | $params = $this->params;
34 | $page = [
35 | 'title' => $this->title,
36 | 'content' => $this->getPureContent(),
37 | 'language' => '',
38 | ];
39 |
40 | $template = new Template($params['templates'], $params['theme']['templates']);
41 | return $template->render('error', ['page' => $page, 'params' => $params]);
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/libs/Server/NotFoundException.php:
--------------------------------------------------------------------------------
1 | content;
14 | }
15 |
16 | /**
17 | * @param string $content
18 | */
19 | public function setContent($content)
20 | {
21 | $this->content = $content;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/libs/Tree/Raw.php:
--------------------------------------------------------------------------------
1 | setConfig($config);
18 |
19 | $this->setUri($uri);
20 | $this->path = $uri;
21 | }
22 |
23 | /**
24 | * @return Config
25 | */
26 | public function getConfig()
27 | {
28 | return $this->config;
29 | }
30 |
31 | /**
32 | * @param Config $config
33 | */
34 | public function setConfig($config)
35 | {
36 | $this->config = $config;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/logb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/volumio/docs/3232d19b70c6c0f3dd8b65bc3f5b03b659d9c633/logb
--------------------------------------------------------------------------------
/logu:
--------------------------------------------------------------------------------
1 | balbuze balbuze@gmail.com
2 | balbuze balbuze@users.noreply.github.com
3 | biva biva@users.noreply.github.com
4 | crisp00 cristian@pintea.net
5 | Cris Pintea cristian@pintea.net
6 | Gé Koerkamp ge.koerkamp@gmail.com
7 | ghembs ggambacorta88@gmail.com
8 | Ghembs ggambacorta88@gmail.com
9 | Gianpaolo Macario gmacario@gmail.com
10 | GitHub noreply@github.com
11 | Ian Sutherland i.m.sutherland@softhome.net
12 | Joel Takvorian joel.takvorian@qaraywa.net
13 | luckynrslevin luckynrslevin@users.noreply.github.com
14 | macmpi spam@ipik.org
15 | Marcus Götling marcus@gotling.se
16 | Michelangelo Guarise job@Mac-mini-di-Michelangelo.local
17 | Michiel Fokke michiel@fokke.org
18 | Rachid Groeneveld Saiyato@users.noreply.github.com
19 | Rob Campbell 27976+robcee@users.noreply.github.com
20 | sla89 skullsplitter@die-optimisten.net
21 | Vincent McIntyre vincent.mcintyre@gmail.com
22 | volumio info@volumio.org
23 | Volumio info@volumio.org
24 | Xipmix xipmix@users.noreply.github.com
25 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "daux.io",
3 | "version": "0.1.1",
4 | "private": true,
5 | "devDependencies": {
6 | "cssnano": "^3.5.2",
7 | "grunt": "^1.0.3",
8 | "grunt-php": "^1.0.0",
9 | "gulp": "^4.0.0",
10 | "gulp-connect-php": "^0.0.7",
11 | "gulp-less": "^4.0.1",
12 | "gulp-plumber": "^1.1.0",
13 | "gulp-postcss": "^6.1.0",
14 | "gulp-rename": "^1.2.2",
15 | "gulp-sourcemaps": "^2.0.0-alpha",
16 | "gulp-stylelint": "^8.0.0",
17 | "stylelint-config-standard": "^6.0.0"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 | ./tests/
16 |
17 |
18 |
19 |
20 |
21 | libs
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/serve:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | php -S 0.0.0.0:8085 index.php
4 |
--------------------------------------------------------------------------------
/templates/content.php:
--------------------------------------------------------------------------------
1 | layout('theme::layout/05_page') ?>
2 |
3 |
4 |