mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 01:30:49 +01:00
Add TXTP silence entry
This commit is contained in:
parent
e4ed26e703
commit
f5a9e5d06a
24
doc/TXTP.md
24
doc/TXTP.md
@ -235,6 +235,30 @@ loop_mode = keep
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Silent files
|
||||||
|
You can put `?.` in an entry to make a silent (non-existing) file. By default takes channels and sample rate of nearby files, can be combined with regular commands to configure.
|
||||||
|
```
|
||||||
|
intro.adx
|
||||||
|
?.silence #b 3.0 # 3 seconds of silence
|
||||||
|
loop.adx
|
||||||
|
```
|
||||||
|
|
||||||
|
It also doubles as a quick "silence this file" while keeping the same structure, for complex cases. The `.` can actually be anywhere after `?`, but must appear before commands to function correctly.
|
||||||
|
```
|
||||||
|
layer1a.adx
|
||||||
|
?layer1b.adx
|
||||||
|
group = -L2
|
||||||
|
|
||||||
|
?layer2a.adx
|
||||||
|
layer2b.adx
|
||||||
|
group = -L2
|
||||||
|
|
||||||
|
group = -S2
|
||||||
|
```
|
||||||
|
|
||||||
|
Most of the time you can do the same with `#p`/`#P` padding commands or `#@volume 0.0`. This is mainly for complex engines that combine silent entries in twisted ways. You can't silence `group` with `?group` though since they aren't considered "entries".
|
||||||
|
|
||||||
|
|
||||||
## TXTP COMMANDS
|
## TXTP COMMANDS
|
||||||
You can set file commands by adding multiple `#(command)` after the name. `#(space)(anything)` is considered a comment and ignored, as well as any command not understood.
|
You can set file commands by adding multiple `#(command)` after the name. `#(space)(anything)` is considered a comment and ignored, as well as any command not understood.
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/* main entry */
|
/* main entry */
|
||||||
char filename[TXTP_LINE_MAX];
|
char filename[TXTP_LINE_MAX];
|
||||||
|
int silent;
|
||||||
|
|
||||||
/* TXTP settings (applied at the end) */
|
/* TXTP settings (applied at the end) */
|
||||||
int range_start;
|
int range_start;
|
||||||
@ -206,9 +207,46 @@ static void clean_txtp(txtp_header* txtp, int fail) {
|
|||||||
/* ENTRIES */
|
/* ENTRIES */
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
|
|
||||||
|
static int parse_silents(txtp_header* txtp) {
|
||||||
|
int i;
|
||||||
|
int channels = 0;
|
||||||
|
int sample_rate = 0;
|
||||||
|
int32_t num_samples = 0;
|
||||||
|
|
||||||
|
/* silents use same channels as close files */
|
||||||
|
for (i = 0; i < txtp->vgmstream_count; i++) {
|
||||||
|
if (!txtp->entry[i].silent) {
|
||||||
|
channels = txtp->vgmstream[i]->channels;
|
||||||
|
sample_rate = txtp->vgmstream[i]->sample_rate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* actually open silents */
|
||||||
|
for (i = 0; i < txtp->vgmstream_count; i++) {
|
||||||
|
if (!txtp->entry[i].silent)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
txtp->vgmstream[i] = init_vgmstream_silence(channels, sample_rate, num_samples);
|
||||||
|
if (!txtp->vgmstream[i]) goto fail;
|
||||||
|
|
||||||
|
apply_settings(txtp->vgmstream[i], &txtp->entry[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
fail:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_silent(txtp_entry* entry) {
|
||||||
|
/* should also contain "." in the filename for commands with seconds ("1.0") to work */
|
||||||
|
return entry->filename[0] == '?';
|
||||||
|
}
|
||||||
|
|
||||||
/* open all entries and apply settings to resulting VGMSTREAMs */
|
/* open all entries and apply settings to resulting VGMSTREAMs */
|
||||||
static int parse_entries(txtp_header* txtp, STREAMFILE* sf) {
|
static int parse_entries(txtp_header* txtp, STREAMFILE* sf) {
|
||||||
int i;
|
int i;
|
||||||
|
int has_silents = 0;
|
||||||
|
|
||||||
|
|
||||||
if (txtp->entry_count == 0)
|
if (txtp->entry_count == 0)
|
||||||
@ -222,7 +260,16 @@ static int parse_entries(txtp_header* txtp, STREAMFILE* sf) {
|
|||||||
|
|
||||||
/* open all entry files first as they'll be modified by modes */
|
/* open all entry files first as they'll be modified by modes */
|
||||||
for (i = 0; i < txtp->vgmstream_count; i++) {
|
for (i = 0; i < txtp->vgmstream_count; i++) {
|
||||||
STREAMFILE* temp_sf = open_streamfile_by_filename(sf, txtp->entry[i].filename);
|
STREAMFILE* temp_sf = NULL;
|
||||||
|
|
||||||
|
/* silent entry ignore */
|
||||||
|
if (is_silent(&txtp->entry[i])) {
|
||||||
|
txtp->entry[i].silent = 1;
|
||||||
|
has_silents = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_sf = open_streamfile_by_filename(sf, txtp->entry[i].filename);
|
||||||
if (!temp_sf) {
|
if (!temp_sf) {
|
||||||
VGM_LOG("TXTP: cannot open streamfile for %s\n", txtp->entry[i].filename);
|
VGM_LOG("TXTP: cannot open streamfile for %s\n", txtp->entry[i].filename);
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -239,6 +286,11 @@ static int parse_entries(txtp_header* txtp, STREAMFILE* sf) {
|
|||||||
apply_settings(txtp->vgmstream[i], &txtp->entry[i]);
|
apply_settings(txtp->vgmstream[i], &txtp->entry[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (has_silents) {
|
||||||
|
if (!parse_silents(txtp))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
fail:
|
fail:
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user