From 421811ae9431ca2c1bc1a5fd6ee072a40a1f1074 Mon Sep 17 00:00:00 2001 From: ABelliqueux Date: Wed, 4 Aug 2021 11:24:42 +0200 Subject: [PATCH] Duplicate README files --- BS.md | 91 ++++++++++++++++++++++++++ CD.md | 56 ++++++++++++++++ CDDA.md | 56 ++++++++++++++++ STP.md | 66 +++++++++++++++++++ STR.md | 98 ++++++++++++++++++++++++++++ TIM.md | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VAG.md | 48 ++++++++++++++ XA.md | 135 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 743 insertions(+) create mode 100644 BS.md create mode 100644 CD.md create mode 100644 CDDA.md create mode 100644 STP.md create mode 100644 STR.md create mode 100644 TIM.md create mode 100644 VAG.md create mode 100644 XA.md diff --git a/BS.md b/BS.md new file mode 100644 index 0000000..d09a908 --- /dev/null +++ b/BS.md @@ -0,0 +1,91 @@ +# Loading a BS still image + +You need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image. + +## Compile + +```bash +make all +``` + +## Clean directory + +```bash +make cleansub +``` + +## Converting a still image to BS + +`MC32` can convert these formats to BS : TIM, RGB, YUV. + +### Image > TIM with img2tim + +Convert your image to a 24bpp TIM with [`img2tim`](https://github.com/Lameguy64/img2tim): + +```bash +img2tim -bpp 24 -o output.tim input.png +``` + +Then use `MC32` as instructed below. + +Result : + +```bash +identify bace.tim +bace.tim TIM 320x240 320x240+0+0 8-bit sRGB 230420B 0.000u 0:00.000 +``` + +### Image > RGB with imagemagick + +You can convert your image to RGB with: + +```bash +convert input.png RGB:output.rgb +``` +Result : +```bash +identify -size 320x240 -depth 8 RGB:bace.rgb +RGB:bace.rgb=>bace.rgb RGB 320x240 320x240+0+0 8-bit sRGB 230400B 0.000u 0:00.003 +``` + + +### Image > YUV422 UYVY with imagemagick + +You can convert your image to YUV with: + +```bash +convert input.png UYVY:output.yuv +``` +Result : +```bash +dentify -size 320x240 UYVY:bace.yuv +UYVY:bace.yuv=>bace.yuv UYVY 320x240 320x240+0+0 8-bit YCbCr 153600B 0.000u 0:00.005 +``` + + +### TIM/RGB/UYVY > BS conversion + +Use the [`MC32` tool](http://psx.arthus.net/tools/pimp-psx.zip) conversion tool to import the image, specifying the right dimensions, and convert to `bs` with those settings : + +**Note that a BS image must have a width and height that is a multiple of 16** + +``` +Input: RGB, Output: bs +MDEC version : 2 +Custom: Size in sectors or (2048 * sector number) bytes, Variable frame size +``` + +![MC32 bs conversion](https://wiki.arthus.net/assets/mc32-bs-conv.png) + +## Sources & Refs + +img2tim : https://github.com/Lameguy64/img2tim +MC32 : http://psx.arthus.net/tools/pimp-psx.zip + +mdecnote : http://psx.arthus.net/sdk/Psy-Q/DOCS/TECHNOTE/mdecnote.pdf +PSX RGB and YUV format : http://psx.arthus.net/sdk/Psy-Q/DOCS/Devrefs/Dataconv.pdf , p.68 + +YUV pixel format : https://www.fourcc.org/pixel-format/yuv-uyvy/ +RGB pixelformat : https://www.fourcc.org/pixel-format/rgb-bi_rgb/ + +RGB<>YUV conversion formulas : https://www.fourcc.org/fccyvrgb.php diff --git a/CD.md b/CD.md new file mode 100644 index 0000000..34ca6b0 --- /dev/null +++ b/CD.md @@ -0,0 +1,56 @@ +## Compiling + +You need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image. +Typing +```bash +make +``` +in a terminal will compile and generate the bin/cue files. + +Typing +```bash +make cleansub +``` +will clean the current directory + +## Creating the disk image + +```bash +mkpsxiso -y isoconfig.xml +``` + +## Using ffmpeg to generate a CDDA compliant Wav file + +Needed Specification : `RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz` + +### Conversion + +```bash +ffmpeg -i input.mp3 -acodec pcm_s16le -ac 2 -ar 44100 output.wav +``` + +### Merging two mono audio channels into one stereo channel + +```bash +ffmpeg -i herb.wav.new -filter_complex "[0:a][0:a]amerge=inputs=2[a]" -map "[a]" herbi.wav +``` + +### Adding the audio track to the CD + +Add a track section **after** your data track in `isoconfig.xml` : + +```xml + +``` + +## Music credits + +Track 1 : +Beach Party by Kevin MacLeod +Link: https://incompetech.filmmusic.io/song/3429-beach-party +License: https://filmmusic.io/standard-license + +Track 2: +Funk Game Loop by Kevin MacLeod +Link: https://incompetech.filmmusic.io/song/3787-funk-game-loop +License: https://filmmusic.io/standard-license diff --git a/CDDA.md b/CDDA.md new file mode 100644 index 0000000..34ca6b0 --- /dev/null +++ b/CDDA.md @@ -0,0 +1,56 @@ +## Compiling + +You need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image. +Typing +```bash +make +``` +in a terminal will compile and generate the bin/cue files. + +Typing +```bash +make cleansub +``` +will clean the current directory + +## Creating the disk image + +```bash +mkpsxiso -y isoconfig.xml +``` + +## Using ffmpeg to generate a CDDA compliant Wav file + +Needed Specification : `RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz` + +### Conversion + +```bash +ffmpeg -i input.mp3 -acodec pcm_s16le -ac 2 -ar 44100 output.wav +``` + +### Merging two mono audio channels into one stereo channel + +```bash +ffmpeg -i herb.wav.new -filter_complex "[0:a][0:a]amerge=inputs=2[a]" -map "[a]" herbi.wav +``` + +### Adding the audio track to the CD + +Add a track section **after** your data track in `isoconfig.xml` : + +```xml + +``` + +## Music credits + +Track 1 : +Beach Party by Kevin MacLeod +Link: https://incompetech.filmmusic.io/song/3429-beach-party +License: https://filmmusic.io/standard-license + +Track 2: +Funk Game Loop by Kevin MacLeod +Link: https://incompetech.filmmusic.io/song/3787-funk-game-loop +License: https://filmmusic.io/standard-license diff --git a/STP.md b/STP.md new file mode 100644 index 0000000..89777ef --- /dev/null +++ b/STP.md @@ -0,0 +1,66 @@ +![Hello_stp](https://wiki.arthus.net/assets/hello-stp.png) + +# STP : Semi-Transparency usage + +This example shows the various way of converting an image with transparency to a TIM and use it in code. +It also shows the effect of activating Semi-Transparency on a primitive textured with those images. + +Use the `SELECT` button to switch primitive semi-transparency on and off. + +It also features a few C struct to facilitate access to the TIM file / pixel data. + +You can use Lameguy64's [img2tim](https://github.com/Lameguy64/img2tim) tool to convert most of image formats to the psx [TIM format.](https://github.com/ABelliqueux/nolibgs_hello_worlds/tree/main/TIM). + +## Semi-transparency rates + +You can find another example with the various transparency rates demoed here : https://github.com/ABelliqueux/nolibgs_hello_worlds/tree/main/hello_cubetex_stp + +## Important + +**By default, the PSX will consider black pixels (0,0,0,0) as transparent**. +In order to display those black pixels as black, you have to set the STP on black (1,0,0,0). +Black pixels and non-black pixels with the STP bit will display as semi-transparent when using `SetSemiTrans()`. + +## STP on black + +Use this to display black pixels as black, not transparent. +The **inverted** alpha mask of the TIM corresponds to the position of black (0,0,0) pixels in the image. + +```bash +img2tim -b -org 640 0 -o stpOnBlack.tim av.png +``` + +## STP on non-black + +Black pixels will be considered as transparent, and non-black pixels will receive semi-transparency with `SetSemiTrans()`. + +The alpha mask of the TIM corresponds to the position of non-black (n,n,n) pixels in the image. +Additionally, a setting allows you to define the RGB value to be considered transparent ; `-tcol` . This does not set any STP flag. + +```bash +img2tim -t -org 320 0 -o stpOnNonBlack.tim av.png +``` + +## Use alpha channel + +The alpha mask of the TIM corresponds to the existing alpha channel of the image (PNG, GIF, TGA, TIFF). +Additionally, a setting allows you to define the threshold for the alpha value to be considered transparent ; `-alpt` . This does not set any STP flag. + +```bash +img2tim -usealpha -org 640 256 -o stpOnNonBlack.tim av.png +``` + +## Use color index + +When using 8/4bpp palettized images, you can specify the index number of the color to be considered transparent. This does not set any STP flag. + +You can set the STP bit by CLUT color with PsyQ's `TIMTOOL.EXE`. This allows you do do cool stuff like oly having specific colors being rendered as semi-transparent by `SetSemiTrans()`. + +```bash +img2tim -b -bpp 8 -tindex 0 -org 640 256 -plt 0 481 -o stpOnColIndex.tim av8.png +``` + +## Black transparency work-around + +Using a pseudo-black color with one of the channels value to 10, i.e : `255,255,10` can be done so you dont have to set the STP bit on full black. +This allows you to keep the pseudo-black opaque when using `SetSemiTrans()`. diff --git a/STR.md b/STR.md new file mode 100644 index 0000000..4e690dc --- /dev/null +++ b/STR.md @@ -0,0 +1,98 @@ +This example will play a fullscreen STR file and is as straightforward as possible. If you need more advanced control other the display size and position, see the [STR playback library](https://github.com/ABelliqueux/nolibgs_hello_worlds/tree/main/hello_str#str-playback-library) section. + +## Compiling + +You need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image. +Typing +```bash +make +``` +in a terminal will compile and generate the bin/cue files. + +Typing +```bash +make cleansub +``` +will clean the current directory. + +## STR playback library + +@Lameguy64 has spent some time making a STR playback library that's easily included in a project : + +> One thing that I find somewhat missing here is a decent piece of code for playing STR video files easily. So, what I did was take the old and messy PsyQ STR player example, clean it up entirely, and finally make it into a cute little c library for easy implementation. + +Original post : http://www.psxdev.net/forum/viewtopic.php?t=507 +Original download link : https://www.mediafire.com/download/s61u86sxd1djncy/strplay.7z +Mirror : http://psx.arthus.net/code/strplay.7z + +## Converting to AVI + +You need `AVI file 320x240, 15 fps, 24-bit color, Stereo 16-bit sound @ 44100 Hz`. + +``` +Stream #0:0: Video: rawvideo, bgr24, 320x240, 27763 kb/s, 15 fps, 15 tbr, 15 tbn, 15 tbc +Stream #0:1: Audio: pcm_u8 ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels, u8, 705 kb/s +``` + +### Video to AVI + +Use Virtualdub or ffmpeg : + +```bash +ffmpeg -i $INPUT.MKV -vcodec rawvideo -pix_fmt bgr24 -vf scale=320:240,setsar=1:1 -acodec pcm_u8 -ar 44100 -r 15 $OUTPUT.avi +``` + +### AVI to STR + +Use [`MC32.EXE`](http://psx.arthus.net/tools/pimp-psx.zip) to convert the AVI file to STR using these settings : + +``` +Format : Input : Avi (Uncompressed), Output : str (MDEC) +Sound: 37.8 KHz, Stereo; +Easy: Double Speed, 15 fps, 1ch, Leap Sector; +MDEC: version 2 +``` + +![MC32-avi-str](https://wiki.arthus.net/assets/MC32-avi-str.png) + +**If `MC32.exe` crashes when hitting the 'Go' button, you have to open the ffmpeg AVI file in virtualdub, then save it again ; `File > Save as AVI...` or `F7` key, then retry.** + +You should now have a STR file and a XA file that you have to interleave in `MC32`: + +``` +Format : Input : str (MDEC), Output: str (MDEC) +Sound: Input: XA , 37.8 KHz, Stereo; +Frame rate: 15 fps, # Channels : 1(150sectors/s), Leap Sector; +CD-ROM speed : Double Speed; +``` + +![MC32-avi-str-interleave](https://wiki.arthus.net/assets/MC32-avi-str-interleaved.png) + +### Finding a video's frame count + +With `ffmpeg` : + +```bash +ffprobe -v error -select_streams v:0 -count_packets -show_entries stream=nb_read_packets -of csv=p=0 VIDEOFILE.AVI +``` + +Alternatively, open the STR file in `MC32.exe` and look at the bottom left of the window. + +### Tools & Refs + +MC32 : http://psx.arthus.net/tools/pimp-psx.zip +STR converter : http://psx.arthus.net/tools/str_converter.rar + +Original PsyQ sample code : +``` +/psyq/psx/sample/scee/CD/MOVIE2 +/psyq/addons/cd/MOVIE (same as /psx/sample/cd/MOVIE ) +/addons/sound/STREAM/TUTO2.C +``` +Original post : http://www.psxdev.net/forum/viewtopic.php?t=507 +Video to STR conversion tutorial : http://www.psxdev.net/forum/viewtopic.php?f=51&t=277 +MDEC notes : http://psx.arthus.net/sdk/Psy-Q/DOCS/TECHNOTE/mdecnote.pdf + +## Video credits + +The video and song used in this example are by Nina Paley : https://archive.org/details/CopyingIsNotTheft-ScratchTrack1280X720Hdv diff --git a/TIM.md b/TIM.md new file mode 100644 index 0000000..d96716e --- /dev/null +++ b/TIM.md @@ -0,0 +1,193 @@ +# TIM files + +Standard bitmap images that can be transferred directly to the PSX VRAM. + +Can be 4bit or 8bit with a [CLUT (Colour Look Up Table)](https://en.wikipedia.org/wiki/Palette_(computing)), 16bit or 24 bit in direct color. + +See [this page](https://www.fourcc.org/pixel-format/rgb-bi_rgb/) for further information on how information is stored in the 16/24bpp modes. + +You can access the TIM mode through TIM_IMAGE->mode. +Mode can be : + + * 0: 4bits b0 + * 1: 8 bits b1 + * 2: 16 bits b10 + * 3: 24bits b11 + * 4: mixed b100 + +See [FileFormat47.pdf](http://psx.arthus.net/sdk/Psy-Q/DOCS/FileFormat47.pdf), p.179 + +# Transparency + +In 16bpp mode, only 15b are used for colors (R 5, G 5, B 5). The 15th bit is defined as the STP or Semi-Transparency flag. + +A primitive transparency is set with `SetSemiTrans()`. + +The only case where a primitive with unset (=0) STP is transparent is when all values are 0. i.e ; using STP 0, B 0, G 0, R 0 +will result in a transparent pixel wether the primitive is set to semi-tranparent or not. + +Here are the transparency modes for various values on semi-transparent and opaque primitives : + + | STP, B, G, R | (0, 0, 0, 0) | (1, 0, 0, 0) | (0, n, n, n) | (1, n, n, n) | + | :-: | :-: | :-: | :-: | :-: | + | Non-transparent primitive | Transparent | Black | Non-transparent | Non-transparent | + | Semi-transparent primitive | Transparent | Semi-transparent | Non-transparent black | Semi-transparent | + +See [FileFormat47.pdf](http://psx.arthus.net/sdk/Psy-Q/DOCS/FileFormat47.pdf), p.56, p.192, +[LibOver47.pdf](http://psx.arthus.net/sdk/Psy-Q/DOCS/LibOver47.pdf), p.107, Table 8-12: + +Here is an overview of the various STP modes : + +![STP](https://wiki.arthus.net/assets/psx-stp-modes-1.jpg) + +In the following picture, STP refers to the transparency rate mode as seen in [LibRef47.pdf](http://psx.arthus.net/sdk/Psy-Q/DOCS/LibRef47.pdf), p.306 : + +![STP rate](https://wiki.arthus.net/assets/psx-stp-modes.jpg) + + +## img2tim semi-transparency options + +`img2tim` has several options related to pixel transparency : + + * `-t` : Set semi-transparent bit (STP) on non fully black pixels. This will set the STP to 1 on pixels with RGB values different from B0,G0,R0. + * `-usealpha` : Use alpha channel (if available) as transparency mask. This will use the converted image's alpha channel (PNG, TGA, TIFF, GIF) + * `-alpt ` : Threshold value when alpha channel is used as transparency mask (Default: 127). Transparency values above this wil be treated as opaque. + * `-tindex ` : Specify color index to be treated as transparent (ignored on non palletized images). When using 4bpp/8bpp, specified color to be used as transparent. + * `-tcol ` : Specify RGB color value to be treated as transparent. Same as above for 16bpp. + +# Tools + +You can use open source tools : Gimp, Aseprite + +To convert your image files to TIM, use [IMG2TIM](https://github.com/Lameguy64/img2tim) : + +## 4bpp and 8bpp specificities + +If you want to generate 4bpp and 8bpp TIMs, your original image must be in indexed mode with a palette. + + * For 8bpp, < 256 colors , and dimensions must be a multiple of 2 + + * For 4bpp, < 16 colors, and dimensions must be a multiple of 4 + +See [FileFormat47.pdf](http://psx.arthus.net/sdk/Psy-Q/DOCS/FileFormat47.pdf), p.182 + +You can use TIMTOOL.EXE from legacy PsyQ to check your TIM files, or use Lameguy64's [TIMedit](https://github.com/Lameguy64/TIMedit) + +# Reproducing the TIM in this example + +## Image > 4bpp, 8bpp + +To convert your images to palettized 4bpp and 8bpp pngs, you can use [pngquant](https://pngquant.org/) : + +4bpp (16 colors) image : + +```bash +pngquant 16 input.png -o output.png --force +``` +8bpp (256 colors) image : + +```bash +pngquant 256 input.png -o output.png --force +``` + +Alternatively, you can use imagemagick : + +4bpp (16 colors) image : + +```bash +convert input.png -colors 16 output.png +``` +8bpp (256 colors) image : + +```bash +convert input.png -colors 256 output.png +``` + +## PNG > Tim + +```bash +img2tim -bpp 4 -org 512 0 -plt 0 481 -usealpha -o TIM4.tim TIM4.png +img2tim -bpp 8 -org 512 256 -plt 0 480 -usealpha -o TIM8.tim TIM8.png +img2tim -bpp 16 -org 768 0 -usealpha -o TIM16.tim TIM16.png +``` +## Content of Makefile : + +```mk +SRCS = hello_sprt.c \ +../common/crt0/crt0.s \ +TIM/TIM16.tim \ +TIM/TIM8.tim \ +TIM/TIM4.tim \ +``` +## Using the TIM file in code + +TODO : Make this presentable + +```c +// Some structures to handle TIM files + +// Access Pixels STP, R, G, B +typedef struct RGB_PIX { + u_int R:5, G:5, B:5, STP:1; +} RGB_PIX; + + +typedef struct PIXEL { + u_long bnum; + u_short DX, DY; + u_short W, H; + RGB_PIX data[]; +} PIXEL; + +typedef struct CLUT { + u_long bnum; + u_short DX, DY; + u_short W, H; + u_short clut[]; +} CLUT; + +typedef struct TIM_FILE_CLUT{ + u_long ID; + u_long flag; + u_long clut; + PIXEL pixel[]; +} TIM_FILE_CLUT; + +typedef struct TIM_FILE{ + u_long ID; + u_long flag; + PIXEL pixel[]; +} TIM_FILE; + +// If we were using C++, we could use templates +//~ struct EmbeddedClut { u_long clut; }; +//~ struct NoEmbeddedClut { }; +//~ template +//~ struct TIM_FILE { + //~ u_long ID; + //~ u_long flag; + //~ std::conditional clut; + //~ PIXEL pixel[]; +//~ }; + +// 16bpp TIM +// STP set on black pixels ( STP, B, R, G == 1, 0, 0 ,0) +extern TIM_FILE _binary_TIM_transBlack_tim_start; +// STP set on image's alpha ( STP, B, R, G == 1, n, n ,n) +extern TIM_FILE _binary_TIM_transAlpha_tim_start; +// STP set on image's alpha ( STP, B, R, G == 1, n, n ,n) with threshold (img2tim -alpt option) +extern TIM_FILE _binary_TIM_transAlphaS_tim_start; +// STP set on 8bpp TIM's CLUT index +extern TIM_FILE _binary_TIM_trans8bpp_tim_start; +// Store in an array so we can iterate over it +TIM_FILE * timFiles[4]; +TIM_IMAGE timImages[4]; + +FntPrint("RGB: %d\n", _binary_TIM_transBlack_tim_start.pixel->data[0].R ); +FntPrint("RGB: %d %d %d %d", timFiles[0]->pixel->data[8192].STP, timFiles[0]->pixel->data[8192].R, timFiles[0]->pixel->data[8192].G, timFiles[0]->pixel->data[8192].B ); +``` + +# Links + + * [TIMexample on psxdev.net](http://www.psxdev.net/forum/viewtopic.php?f=64&t=313) + * [Lameguy64's Github repo](https://github.com/Lameguy64) diff --git a/VAG.md b/VAG.md new file mode 100644 index 0000000..24f688b --- /dev/null +++ b/VAG.md @@ -0,0 +1,48 @@ +# VAG files + +> VAG is the PlayStation single waveform data format for ADPCM-encoded data of sampled sounds, such as +piano sounds, explosions, and music. The typical extension in DOS is “.VAG”. + +See [FileFormat47.pdf](http://psx.arthus.net/sdk/Psy-Q/DOCS/FileFormat47.pdf), p.209 + + +## WAV creation + +Use ffmpeg to create a 16-bit ADPCM mono WAV file - change -ar to reduce filesize (and quality) + +```bash +$ ffmpeg -i input.mp3 -acodec pcm_s16le -ac 1 -ar 44100 output.wav +``` + +You can use Audacity to edit sound. + +## WAV to VAG convertion using WAV2VAG + +Get here : [WAV2VAG](https://github.com/ColdSauce/psxsdk/blob/master/tools/wav2vag.c) + +Change -freq according to the -ar setting above + +```bash +$ wav2vag input.wav output.vag -sraw16 -freq=44100 (-L) +``` + +### Bug ? + +After conversion with WAV2VAG, the resulting VAG will sometimes have a pop at the very beginning and/or end of the file. + +You can check (and delete) this with PsyQ's VAGEDIT.EXE. + +You can also force the sampling frequency of an existing VAG file. + +## VAGedit + +You can find a graphical editor in the [PsyQ sdk](http://psx.arthus.net/sdk/Psy-Q/PSYQ_SDK.zip) named `VAGEDIT.exe`. + +## VAG & SPU Docs + +See + * libformat47.pdf p.209 + * libover47.pdf, p.271 + * libref47.pdf, p.980 + + * [http://psx.arthus.net/code/VAG/](http://psx.arthus.net/code/VAG) diff --git a/XA.md b/XA.md new file mode 100644 index 0000000..6d74dfd --- /dev/null +++ b/XA.md @@ -0,0 +1,135 @@ +## XA playback + +You need [mkpsxiso](https://github.com/Lameguy64/mkpsxiso) in your $PATH to generate a PSX disk image. +You also need [`psxavenc` and `xainterleave`](https://github.com/ABelliqueux/candyk-psx/tree/master/toolsrc/). + +### Generate interleaved XA file + +```bash +psxavenc -f 37800 -t xa -b 4 -c 2 -F 1 -C 0 "../hello_cdda/audio/beach.wav" "xa/beach.xa" +psxavenc -f 37800 -t xa -b 4 -c 2 -F 1 -C 0 "../hello_cdda/audiofunk.wav" "xa/funk.xa" +xainterleave 1 xa/interleave4.txt xa/inter4.xa +xainterleave 1 xa/interleave8.txt xa/inter8.xa +``` + +Alternatively, you can use the windows tool [`MC32.EXE`](https://psx.arthus.net/tools/pimp-psx.zip) to interleave several PSX media files. + +### Compile + +This will compile and build an iso image : + +```bash +make +``` + +### Clean directory + +```bash +make cleansub +``` + +## Encoding to XA + +You can use a modified version of [`psxavenc`](https://github.com/ABelliqueux/candyk-psx/tree/master/toolsrc/psxavenc) to convert your audio file to a 2336 bytes XA file : + +```bash +./psxavenc -f 37800 -t xa -b 4 -c 2 -F 1 -C 1 "input.wav" "output.xa" +``` + +You can read it back with `XAPLAY.EXE`, that's in `psyq/bin/XAplay`. + +### PSXavenc usage + +``` +./psxavenc +Usage: psxavenc [-f freq] [-b bitdepth] [-c channels] [-F num] [-C num] [-t xa|xacd|spu|str2] + + -f freq Use specified frequency + -t format Use specified output type: + xa [A.] .xa 2336-byte sectors + xacd [A.] .xa 2352-byte sectors + spu [A.] raw SPU-ADPCM data + str2 [AV] v2 .str video 2352-byte sectors + -b bitdepth Use specified bit depth (only 4 bits supported) + -c channels Use specified channel count (1 or 2) + -F num [.xa] Set the file number to num (0-255) + -C num [.xa] Set the channel number to num (0-31) +``` + +## Interleaving XA files + +You can use [`MC32.EXE`](https://psx.arthus.net/tools/pimp-psx.zip) or [`xainterleave`](https://github.com/ABelliqueux/candyk-psx/tree/master/toolsrc/xainterleave) to interleave several PSX media files. + +## xainterleave usage + +`xainterleave ` + +`mode` can be 0 for full raw sectors or 1 for just XA (divisible by 2336) + +`in.txt` is a manifest txt file as seen [here](https://github.com/ABelliqueux/nolibgs_hello_worlds/blob/main/hello_xa/xa/interleave4.txt) + +Example for 1 music file, to be played at 1x CD speed (4 channels): + +``` +1 xa test.xa 1 0 +1 null +1 null +1 null +``` + +Add 4 more 1 null lines for 2x (8 channels). + +``` + 1 xa menu.xa 1 0 +sectors type file xa_file number (0-255) xa_channel number (0-31) +``` + +The format seems to correspond to the [entry_t struct](https://github.com/ABelliqueux/candyk-psx/blob/db71929903cc09398f5efc23973f9e136d123bbb/toolsrc/xainterleave/xainterleave.c#L35). + +## mkpsxiso + +You can use the following syntax to include your XA file in the CD image : + +```xml + +``` + +See here for more details : https://github.com/Lameguy64/mkpsxiso/blob/c44b78e37bbc115591717ac4dd534af6db499ea4/examples/example.xml#L85 + +## PsyQ XA Tools + +[XAPLAY.EXE](https://docs.google.com/uc?export=download&confirm=G9cM&id=0B_GAaDjR83rLZGVaZ2pvV2tjSVE) : Single channel XA playback +[XATOOL.EXE](http://psx.arthus.net/code/XA/xatut.zip) : XA structure inspector +[MC32.EXE](https://psx.arthus.net/tools/pimp-psx.zip) : Converts WAV > XA > Interleaved XA + +## More + +XA tutorial : http://psx.arthus.net/code/XA/XATUT.pdf + +Full XAtut archive : http://psx.arthus.net/code/XA/xatut.zip + +XA ADPCM documentation : http://psx.arthus.net/code/XA/XA%20ADPCM%20documentation.txt + +https://psx-spx.consoledev.net/cdromdrive/#cdrom-xa-audio-adpcm-compression + +PsyQ XA player example : `psyq/addons/scee/CD/XAPLAYER` + +XA SCEE Technical note - July 1998 : http://psx.arthus.net/sdk/Psy-Q/DOCS/CONF/SCEE/98July/xa_sound.pdf + +PSX audio tools : https://forum.xentax.com/viewtopic.php?t=10136 + +PIMP tools : https://psx.arthus.net/tools/pimp-psx.zip + +Source : https://discord.com/channels/642647820683444236/663664210525290507/843211084609617930 + +## Music credits + +Track 1 : +Beach Party by Kevin MacLeod +Link: https://incompetech.filmmusic.io/song/3429-beach-party +License: https://filmmusic.io/standard-license + +Track 2: +Funk Game Loop by Kevin MacLeod +Link: https://incompetech.filmmusic.io/song/3787-funk-game-loop +License: https://filmmusic.io/standard-license