# Embedded Lab5 Project
## Cross-compile
There are (or may have) dependencies between packages. Follow the steps to config the executables and dynamic libraries.
Before we start we have to create a new folder as the `prefix`, and this is the place we store the binaries and DLLs. Replace `/path/to/your/prefix` to your path.
And the cross-compile toolchain is presumed to installed in `/opt/EmbedSky/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/bin/`
### alsa-lib
On the board, there is already a soundcard driver (ALSA), but the essential API library required by the ALSA architecture is absent. Therefore, it is necessary to transfer the ALSA library to the target board.
The reason we start by compiling `alsa-lib`. Please see this [reference](https://groups.google.com/g/linux.debian.bugs.dist/c/d1lBFkrKfRM).
And here are the steps:
1. Download the ALSA library source code from https://www.alsa-project.org/files/pub/lib/
We download **alsa-lib-1.0.26.tar.bz2** and unzip it.
2. Cross-compile the ALSA library
`--with-configdir` : The directory containing the ALSA configuration files, this location should remain consistent between the PC and the target board after cross-compilation.
```shell=!
$ ./configure --host=arm-linux-gnueabihf --prefix=/path/to/your/prefix \
--enable-shared --disable-python \
--with-configdir=/usr/local/share/alsa \
--with-plugindir=/usr/local/lib/alsa_lib \
CC=/opt/EmbedSky/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc \
CXX=/opt/EmbedSky/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ \
LD=/opt/EmbedSky/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ld
$ make
$ make install
```
### alsa-utils
Cross-compile the ALSA utilities to get command-line sound player **aplay** for ALSA
1. Download the [ALSA utilities source code](https://www.alsa-project.org/files/pub/utils/)
We download **alsa-utils-1.0.26.tar.bz2** and unzip it.
2. Cross-compile the ALSA utilities
```shell!
$ ./configure --host=arm-linux \
--prefix=/usr/local/share/arm-alsa \
CFLAGS="-I/path/to/your/prefix/include" \
LDFLAGS="-L/path/to/your/prefix/lib -lasound" \
--disable-alsamixer --disable-xmlto \
--with-alsa-inc-prefix=/usr/local/share/arm-alsa/include \
--with-alsa-prefix=/usr/local/share/arm-alsa/lib \
CC=/opt/EmbedSky/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc \
CXX=/opt/EmbedSky/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ \
LD=/opt/EmbedSky/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-ld
$ make -j{nproc}
$ sudo make install
```
---
**Madplay** is an open-source command-line audio player specifically designed for playing MPEG audio files. It relies on the following libraries: **zlib**, **libid3tag**, **libmad**. We download the source code from the following repositories: [madplay, libid3tag, libmad](https://sourceforge.net/projects/mad/files/), and [zlib](https://www.zlib.net/fossils/)
Below are the steps to cross-compile these libraries into the system for use by the madplay program. Please see this [reference](https://blog.csdn.net/weixin_44175439/article/details/120186387?fbclid=IwAR34-SnjFaHaVFdHjSWiMFZ3N06Zi).
### zlib
First we have to build zlib for `libid3tag` dependencies.
```shell=!
$ wget https://www.zlib.net/fossils/zlib-1.2.3.tar.gz
$ tar xvfz zlib-1.2.3.tar.gz
$ cd zlib-1.2.3
$ ./configure --prefix=/path/to/your/prefix
$ sed -i 's/CC=gcc/CC=arm-linux-gnueabihf-gcc/g; \
s/LDSHARED=gcc -shared -Wl,-soname,libz.so.1/LDSHARED=arm-linux-gnueabihf-gcc -shared -Wl,-soname,libz.so.1/g; \
s/CPP=gcc -E/CPP=arm-linux-gnueabihf-gcc -E/g; \
s/AR=ar rc/AR=arm-linux-gnueabihf-ar rc/g; \
s/RNALIB=ranlib/RANLIB=arm-linux-gnueabihf-ranlib/g' Makefile
$ make -j{nproc}
$ sudo make install
```
Here in line 5 we modified our compile toolchain to cross-compiled version. If the the compilation using non-cross-compile tolchain, please replace it with absolute path of the cross-compile toolchain.
### libid3tag
Then this `libid3tag` is a dependency of `libmad`. Since we cannot use `apt`, we have to compile all libraries and dependencies from source.
```shell=!
$ tar zxvf libid3tag-0.15.1b.tar.gz
$ cd libid3tag-0.15.1b
$ ./configure --host=arm-linux-gnueabihf \
--prefix=/path/to your/prefix \
CPPFLAGS=-I/path/to your/prefix/include \
LDFLAGS=-L/path/to your/prefixlib \
$ make -j$(nproc)\n
$ make install
```
### libmad
When we execute `madplay`, we need the DLL `libmad`, so we also need to compile it.
```shell=!
$ tar zxvf libid3tag-0.15.1b.tar.gz
$ cd libid3tag-0.15.1b
$ ./configure --host=arm-linux-gnueabihf \
--prefix=/path/to your/prefix \
CPPFLAGS=-I/path/to your/prefix/include \
LDFLAGS=-L/path/to your/prefixlib \
$ sed -i 's/--fforce-mem//g' Makefile
```
But there are still some mistakes in the source. Open `fixed.h`. Replace
```C=!
# define MAD_F_MLN(hi, lo) \
asm ("rsbs %0, %2, #0\n\t" \
"rsc %1, %3, #0" \
: "=r" (lo), "=r" (hi) \
: "0" (lo), "1" (hi) \
: "cc")
```
with
```C=!
#ifdef __thumb__
/* In Thumb-2, the RSB-immediate instruction is only allowed with a zero
operand. If needed this code can also support Thumb-1
(simply append "s" to the end of the second two instructions). */
# define MAD_F_MLN(hi, lo) \
asm ("rsbs %0, %0, #0\n\t" \
" sbc %1, %1, %1\n\t" \
"sub %1, %1, %2" \
: "+&r" (lo), "=&r" (hi) \
: "r" (hi) \
: "cc")
#else /* ! __thumb__ */
# define MAD_F_MLN(hi, lo) \
asm ("rsbs %0, %2, #0\n\t" \
"rsc %1, %3, #0" \
: "=r" (lo), "=r" (hi) \
: "=&r" (lo), "=r" (hi) \
: "0" (lo), "1" (hi) \
: "cc")
#endif /* __thumb__ */
```
and then you can execute
```shell=!
$ make -j$(nproc)\n
$ make install
```
Here is the [Reference](https://www.twblogs.net/a/5e6b933dbd9eee211685f17d?fbclid=IwAR1a9ZtyoccMP_94uWYMhFH4Pfvj0bOtHSotsoilit7iI1MNKFyuqptcjms)
### madplay
Madplay is a tool to convert the music file format. Like in this lab, we can use this `madplay` to convert `music.mp3` into an `wav` file.
Here's the instruction to compile the `madplay`:
```shell=!
$ tar zxvf madplay-0.15.2b.tar.gz
$ cd madplay-0.15.2b
$ ./configure --host=arm-linux-gnueabihf \
CC=arm-linux-gnueabihf-gcc \
CPPFLAGS=-I/path/to/your/prefix/include \
LDFLAGS=-L/path/to/your/prefix/lib
$ make -j$(nproc)\n
$ make install
```
Then we finish all compilation steps.
## On board
Copy all the files we need to the SD card, or you could use minicom instead. We prefer using SD card
Here's the steps:
1. Copy `aplay` and `madplay` to `/usr/bin` on the board. They are in `/path/to/your/prefix/bin`
2. Copy all DLLs from `/path/to/your/prefix/lib` to `/usr/lib`. Don't copy the symbolic link! (You can't, either.)
3. Copy `/usr/local/share/alsa` to your SD card and place it on the board right at the same path `/usr/local/share/alsa`. This is important! Make sure you put this directory `alsa` the same path of `--with-configdir`. `libasound.so.2` need the `a.conf` at the right path.
4. Some configurations. Make a symbolic link in case the executable can find the right DLL on the target board in `/usr/lib`. What is the exact name the executable is looking for? Let us took madplay for example:
```shell=!
(On the host machine)
$ arm-linux-gnueabihf-readelf -d madplay | grep Shared
#
0x00000001 (NEEDED) Shared library: [libmad.so.0]
0x00000001 (NEEDED) Shared library: [libid3tag.so.0]
0x00000001 (NEEDED) Shared library: [libm.so.6]
0x00000001 (NEEDED) Shared library: [libc.so.6]
0x00000001 (NEEDED) Shared library: [ld-linux-armhf.so.3]
```
Config DLLs in this way:
```shell=!
$ ln -s libid3tag.so.0.3.0 libid3tag.so.0
$ ln -s libmad.so.0.2.1 libmad.so.0
$ ln -s libasound.so.2.0.0 libasound.so.2
```
Apparently, line 3 is for `aplay`
5. Go to the place where you put your mp3 file and:
```shell=!
$ madplay -o wav:- a.mp3 | aplay
```
It is very important that there is a blank space after `wav:-`. The arg after `wav:` is the output target, here choose `-` means the output target is `stdout`.
Here the output of comverted wav is **piped** to `aplay` as input. `aplay` will play the music.
Finished!
## References
https://blog.csdn.net/weixin_44175439/article/details/120186387?fbclid=IwAR34-SnjFaHaVFdHjSWiMFZ3N06Zi
https://www.twblogs.net/a/5e6b933dbd9eee211685f17d?fbclid=IwAR1a9ZtyoccMP_94uWYMhFH4Pfvj0bOtHSotsoilit7iI1MNKFyuqptcjms
https://www.cnblogs.com/chd-zhangbo/p/5270290.html?fbclid=IwAR0eMqh-pnridDSzIegmg2gbSVgybbrkLRBnIScBpkuRnJVj3CUPzff4Arc
https://groups.google.com/g/linux.debian.bugs.dist/c/d1lBFkrKfRM
## Source Code
alsa-lib: https://www.alsa-project.org/files/pub/lib/
alsa-utils: https://www.alsa-project.org/files/pub/utils/
zlib: https://www.zlib.net/fossils/
madplay, libid3tag, libmad: https://sourceforge.net/projects/mad/files/