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