mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-29 19:37:30 +01:00
Minor doc
This commit is contained in:
parent
f3c3d4563e
commit
4a338564e6
@ -21,7 +21,9 @@
|
||||
#define VERSION "(unknown version)"
|
||||
#endif
|
||||
|
||||
#define SAMPLE_BUFFER_SIZE 0x8000
|
||||
/* low values are ok as there is very little performance difference, but higher
|
||||
* may improve write I/O in some systems as this*channels doubles as output buffer */
|
||||
#define SAMPLE_BUFFER_SIZE 32768
|
||||
|
||||
/* getopt globals (the horror...) */
|
||||
extern char * optarg;
|
||||
|
35
doc/DEV.md
35
doc/DEV.md
@ -19,17 +19,16 @@ There are no hard coding rules but for consistency one could follow the style us
|
||||
- lowercase_helper_structs, UPPERCASE_MAIN_STRUCTS
|
||||
- spaces in calcs/ifs/etc may be added as desired for clarity
|
||||
ex. `if (simple_check)` or `if ( complex_and_important_stuff(weird + weird) )`
|
||||
- goto are used to abort and reach "fail" sections (typical C cleanup style)
|
||||
|
||||
But other styles may be found, this isn't very important as most files are isolated.
|
||||
But other styles may be found, this isn't very important as most files are isolated. When modifying a file or section of the code just try to follow the style set there so code doesn't clash too much.
|
||||
|
||||
### Code quality
|
||||
There is quite a bit of code that could be improved overall, but given how niche the project is priority is given to adding and improving formats. Some of the code can be inefficient or duplicated at places, but it isn't that much of a problem if gives clarity. vgmstream's performance is fast enough (as it mainly deals with playing songs in real time) so that favors clarity over optimization.
|
||||
|
||||
Similarly, parts may segfault or even cause infinite loops on bad data, but it's fixed as encountered rather than worrying too much about improbable cases. There isn't an automated test suite at the moment, so tests are manually done as needed.
|
||||
There is quite a bit of code that could be improved overall, but given how niche the project is priority is given to adding and improving formats. Parts may segfault or even cause infinite loops on bad data, but it's fixed as encountered rather than worrying too much about improbable cases. There isn't an automated test suite at the moment, so tests are manually done as needed.
|
||||
|
||||
For regression testing there is a simple script that compares output of a previous version of vgmstream_cli with current. Some bugs may drastically change output when fixed (for example adjusting loops or decoding) so it could be hard to automate and maintain.
|
||||
|
||||
Code is checked for leaks at times using detection tools, but most of vgmstream formats are quite simple and don't need to manage memory. It's mainly useful for files using external decoders or complex segmented/layered layout combos.
|
||||
Code is checked for leaks from time to time using detection tools, but most of vgmstream formats are quite simple and don't need to manage memory. It's mainly useful for files using external decoders or complex segmented/layered layout combos.
|
||||
```
|
||||
# recommended to compile with debug info, for example:
|
||||
make vgmstream_cli EXTRA_CFLAGS="-g" STRIP=echo
|
||||
@ -38,6 +37,10 @@ make vgmstream_cli EXTRA_CFLAGS="-g" STRIP=echo
|
||||
drmemory -- vgmstream_cli -o file.ext
|
||||
```
|
||||
|
||||
Some of the code can be inefficient or duplicated at places, but it isn't that much of a problem if gives clarity. vgmstream's performance is fast enough (as it mainly deals with playing songs in real time) so that favors clarity over optimization. Performance bottlenecks are mainly:
|
||||
- I/O: since I/O is buffered it's possible to needlessly trash the buffers when reading previous/next offsets back and forth. It's better to read linearly using big enough data chunks and cache values.
|
||||
- for loops: since your average audio file contains millions of samples, this means lots of loops. Care should be taken to avoid unnecessary function calls or recalculations per single sample when multiple samples could be processed at once.
|
||||
|
||||
|
||||
## Source structure
|
||||
|
||||
@ -57,6 +60,28 @@ drmemory -- vgmstream_cli -o file.ext
|
||||
./xmplay/ XMPlay plugin
|
||||
```
|
||||
|
||||
## Terminology
|
||||
Quick list of some audio terms used through vgmstream, applied to code. Mainly meant for the neophyte, hopefully helps new people willing to contribute. vgmstream isn't too complex and with some perseverance one can add a new format (*meta*) easily enough.
|
||||
|
||||
- stream: an audio file, or a section inside it, or data 'lane' within, as the name implies. Just a generic term for a data chunk.
|
||||
- Streams normally have a header that tells how to play the file, and encoded ('compressed') audio data.
|
||||
- encoder: program or code that transforms audio samples to encoded data.
|
||||
- decoder: program or code that transforms encoded data to audio samples.
|
||||
- encoded data: bunch of bytes (sometimes bits) that decode into one or many samples (for one or many channels) with a decoder.
|
||||
- audio sample: digital audio unit (single value) to define playable sound. A sound is a wave, and an array of many samples (digital) together make a wave (analog).
|
||||
- Each output channel has its own set of samples.
|
||||
- Normally `1 sample` actually means `1 sample for every channel` (common standard that makes code logic simpler).
|
||||
- If an stereo file has `1000000` samples it actually means `2*1000000` total samples.
|
||||
- sample rate: number of samples per second (in *hz*). Also called frequency.
|
||||
- If a file has a sample rate *44100hz* and lasts *30 seconds* this means `44100 * 30 = 1323000` samples.
|
||||
- Since many samples together make a wave, the higher the sample rate the more samples we have, and the better-sounding wave we get.
|
||||
- frame: smallest part of data that a decoder can transform into samples.
|
||||
- A frame can contain samples for one or many channels, depending on the encoder.
|
||||
- interleave: size of encoded data for one channel. Some encoders only take a single (mono) channel at a time, so to make stereo or more we interlace frames.
|
||||
- For example 1 frame L, 1 frame R, 1 frame L, 1 frame R, etc. Or 10 frames L, 10 frames R, etc.
|
||||
- block: a generic section of data, made of one or many frames for all channels.
|
||||
|
||||
|
||||
## Overview
|
||||
vgmstream works by parsing a music stream header (*meta/*), preparing/controlling data and sample buffers (*layout/*) and decoding the compressed data into listenable PCM samples (*coding/*).
|
||||
|
||||
|
@ -51,6 +51,7 @@ atrac9_codec_data *init_atrac9(atrac9_config *cfg) {
|
||||
data->data_buffer_size = data->info.superframeSize;
|
||||
/* extra leeway as Atrac9Decode seems to overread ~2 bytes (doesn't affect decoding though) */
|
||||
data->data_buffer = calloc(sizeof(uint8_t), data->data_buffer_size + 0x10);
|
||||
/* while ATRAC9 uses float internally, Sony's API only return PCM16 */
|
||||
data->sample_buffer = calloc(sizeof(sample_t), data->info.channels * data->info.frameSamples * data->info.framesInSuperframe);
|
||||
|
||||
data->samples_to_discard = cfg->encoder_delay;
|
||||
|
@ -1159,26 +1159,26 @@ int w_bits(vgm_bitstream * ob, int num_bits, uint32_t value) {
|
||||
/* CUSTOM STREAMFILES */
|
||||
/* ******************************************** */
|
||||
|
||||
STREAMFILE* setup_subfile_streamfile(STREAMFILE *streamFile, off_t subfile_offset, size_t subfile_size, const char* extension) {
|
||||
STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
|
||||
STREAMFILE* setup_subfile_streamfile(STREAMFILE *sf, off_t subfile_offset, size_t subfile_size, const char* extension) {
|
||||
STREAMFILE *temp_sf = NULL, *new_sf = NULL;
|
||||
|
||||
new_streamFile = open_wrap_streamfile(streamFile);
|
||||
if (!new_streamFile) goto fail;
|
||||
temp_streamFile = new_streamFile;
|
||||
new_sf = open_wrap_streamfile(sf);
|
||||
if (!new_sf) goto fail;
|
||||
temp_sf = new_sf;
|
||||
|
||||
new_streamFile = open_clamp_streamfile(temp_streamFile, subfile_offset,subfile_size);
|
||||
if (!new_streamFile) goto fail;
|
||||
temp_streamFile = new_streamFile;
|
||||
new_sf = open_clamp_streamfile(temp_sf, subfile_offset, subfile_size);
|
||||
if (!new_sf) goto fail;
|
||||
temp_sf = new_sf;
|
||||
|
||||
if (extension) {
|
||||
new_streamFile = open_fakename_streamfile(temp_streamFile, NULL,extension);
|
||||
if (!new_streamFile) goto fail;
|
||||
temp_streamFile = new_streamFile;
|
||||
new_sf = open_fakename_streamfile(temp_sf, NULL, extension);
|
||||
if (!new_sf) goto fail;
|
||||
temp_sf = new_sf;
|
||||
}
|
||||
|
||||
return temp_streamFile;
|
||||
return temp_sf;
|
||||
|
||||
fail:
|
||||
close_streamfile(temp_streamFile);
|
||||
close_streamfile(temp_sf);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -37,9 +37,12 @@ static const int IK1[4] = { 0, 0, 832, 880 };
|
||||
* int coef tables commonly use N = 6 or 8, so K0 0.9375*64 = 60 or 0.9375*256 = 240
|
||||
* PS1 XA is apparently upsampled and interpolated to 44100, vgmstream doesn't simulate this.
|
||||
*
|
||||
* XA has an 8-bit decoding and "emphasis" modes, that no PS1 game actually uses, but apparently
|
||||
* are supported by the CD hardware and will play if found.
|
||||
*
|
||||
* Info (Green Book): https://www.lscdweb.com/data/downloadables/2/8/cdi_may94_r2.pdf
|
||||
* BRR info (no$sns): http://problemkaputt.de/fullsnes.htm#snesapudspbrrsamples
|
||||
* (bsnes): https://gitlab.com/higan/higan/blob/master/higan/sfc/dsp/brr.cpp
|
||||
* (bsnes): https://github.com/byuu/bsnes/blob/master/bsnes/sfc/dsp/SPC_DSP.cpp#L316
|
||||
*/
|
||||
|
||||
void decode_xa(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user