libpsxav: fix EOF flag being misapplied in xa/xacd output
This commit is contained in:
parent
bea15ca01f
commit
f623e56035
|
@ -232,23 +232,30 @@ uint32_t psx_audio_xa_get_sector_interleave(psx_audio_xa_settings_t settings) {
|
||||||
return interleave;
|
return interleave;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void psx_audio_xa_encode_init_sector(uint8_t *buffer, psx_audio_xa_settings_t settings) {
|
static inline void psx_audio_xa_sync_subheader_copy(psx_cdrom_sector_mode2_t *buffer) {
|
||||||
if (settings.format == PSX_AUDIO_XA_FORMAT_XACD) {
|
memcpy(buffer->subheader + 1, buffer->subheader, sizeof(psx_cdrom_sector_xa_subheader_t));
|
||||||
memset(buffer, 0, 2352);
|
|
||||||
memset(buffer+0x001, 0xFF, 10);
|
|
||||||
buffer[0x00F] = 0x02;
|
|
||||||
} else {
|
|
||||||
memset(buffer + 0x10, 0, 2336);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[0x010] = settings.file_number;
|
static void psx_audio_xa_encode_init_sector(psx_cdrom_sector_mode2_t *buffer, psx_audio_xa_settings_t settings) {
|
||||||
buffer[0x011] = settings.channel_number & 0x1F;
|
if (settings.format == PSX_AUDIO_XA_FORMAT_XACD) {
|
||||||
buffer[0x012] = 0x24 | 0x40;
|
memset(buffer, 0, PSX_CDROM_SECTOR_SIZE);
|
||||||
buffer[0x013] =
|
memset(buffer->sync + 1, 0xFF, 10);
|
||||||
(settings.stereo ? 1 : 0)
|
buffer->header.mode = 0x02;
|
||||||
| (settings.frequency >= PSX_AUDIO_XA_FREQ_DOUBLE ? 0 : 4)
|
} else {
|
||||||
| (settings.bits_per_sample >= 8 ? 16 : 0);
|
memset(buffer->subheader, 0, PSX_CDROM_SECTOR_SIZE);
|
||||||
memcpy(buffer + 0x014, buffer + 0x010, 4);
|
}
|
||||||
|
|
||||||
|
buffer->subheader[0].file = settings.file_number;
|
||||||
|
buffer->subheader[0].channel = settings.channel_number & PSX_CDROM_SECTOR_XA_CHANNEL_MASK;
|
||||||
|
buffer->subheader[0].submode =
|
||||||
|
PSX_CDROM_SECTOR_XA_SUBMODE_AUDIO
|
||||||
|
| PSX_CDROM_SECTOR_XA_SUBMODE_FORM2
|
||||||
|
| PSX_CDROM_SECTOR_XA_SUBMODE_RT;
|
||||||
|
buffer->subheader[0].coding =
|
||||||
|
(settings.stereo ? PSX_CDROM_SECTOR_XA_CODING_STEREO : PSX_CDROM_SECTOR_XA_CODING_MONO)
|
||||||
|
| (settings.frequency >= PSX_AUDIO_XA_FREQ_DOUBLE ? PSX_CDROM_SECTOR_XA_CODING_FREQ_DOUBLE : PSX_CDROM_SECTOR_XA_CODING_FREQ_SINGLE)
|
||||||
|
| (settings.bits_per_sample >= 8 ? PSX_CDROM_SECTOR_XA_CODING_BITS_8 : PSX_CDROM_SECTOR_XA_CODING_BITS_4);
|
||||||
|
psx_audio_xa_sync_subheader_copy(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
int psx_audio_xa_encode(psx_audio_xa_settings_t settings, psx_audio_encoder_state_t *state, int16_t* samples, int sample_count, uint8_t *output) {
|
int psx_audio_xa_encode(psx_audio_xa_settings_t settings, psx_audio_encoder_state_t *state, int16_t* samples, int sample_count, uint8_t *output) {
|
||||||
|
@ -261,8 +268,8 @@ int psx_audio_xa_encode(psx_audio_xa_settings_t settings, psx_audio_encoder_stat
|
||||||
if (settings.stereo) { sample_count <<= 1; }
|
if (settings.stereo) { sample_count <<= 1; }
|
||||||
|
|
||||||
for (i = 0, j = 0; i < sample_count || ((j % 18) != 0); i += sample_jump, j++) {
|
for (i = 0, j = 0; i < sample_count || ((j % 18) != 0); i += sample_jump, j++) {
|
||||||
uint8_t *sector_data = output + ((j/18) * xa_sector_size) - xa_offset;
|
psx_cdrom_sector_mode2_t *sector_data = (psx_cdrom_sector_mode2_t*) (output + ((j/18) * xa_sector_size) - xa_offset);
|
||||||
uint8_t *block_data = sector_data + 0x18 + ((j%18) * 0x80);
|
uint8_t *block_data = sector_data->data + ((j%18) * 0x80);
|
||||||
|
|
||||||
if (init_sector) {
|
if (init_sector) {
|
||||||
psx_audio_xa_encode_init_sector(sector_data, settings);
|
psx_audio_xa_encode_init_sector(sector_data, settings);
|
||||||
|
@ -275,7 +282,7 @@ int psx_audio_xa_encode(psx_audio_xa_settings_t settings, psx_audio_encoder_stat
|
||||||
memcpy(block_data + 12, block_data + 8, 4);
|
memcpy(block_data + 12, block_data + 8, 4);
|
||||||
|
|
||||||
if ((j+1)%18 == 0) {
|
if ((j+1)%18 == 0) {
|
||||||
psx_cdrom_calculate_checksums(sector_data, PSX_CDROM_SECTOR_TYPE_MODE2_FORM2);
|
psx_cdrom_calculate_checksums((uint8_t*) sector_data, PSX_CDROM_SECTOR_TYPE_MODE2_FORM2);
|
||||||
init_sector = 1;
|
init_sector = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -285,8 +292,9 @@ int psx_audio_xa_encode(psx_audio_xa_settings_t settings, psx_audio_encoder_stat
|
||||||
|
|
||||||
void psx_audio_xa_encode_finalize(psx_audio_xa_settings_t settings, uint8_t *output, int output_length) {
|
void psx_audio_xa_encode_finalize(psx_audio_xa_settings_t settings, uint8_t *output, int output_length) {
|
||||||
if (output_length >= 2336) {
|
if (output_length >= 2336) {
|
||||||
output[output_length - 2352 + 0x12] |= 0x80;
|
psx_cdrom_sector_mode2_t *sector = (psx_cdrom_sector_mode2_t*) &output[output_length - 2352];
|
||||||
output[output_length - 2352 + 0x18] |= 0x80;
|
sector->subheader[0].submode |= PSX_CDROM_SECTOR_XA_SUBMODE_EOF;
|
||||||
|
psx_audio_xa_sync_subheader_copy(sector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,58 @@ void psx_audio_spu_set_flag_at_sample(uint8_t* spu_data, int sample_pos, int fla
|
||||||
|
|
||||||
#define PSX_CDROM_SECTOR_SIZE 2352
|
#define PSX_CDROM_SECTOR_SIZE 2352
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t minute;
|
||||||
|
uint8_t second;
|
||||||
|
uint8_t sector;
|
||||||
|
uint8_t mode;
|
||||||
|
} psx_cdrom_sector_header_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t file;
|
||||||
|
uint8_t channel;
|
||||||
|
uint8_t submode;
|
||||||
|
uint8_t coding;
|
||||||
|
} psx_cdrom_sector_xa_subheader_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t sync[12];
|
||||||
|
psx_cdrom_sector_header_t header;
|
||||||
|
uint8_t data[0x920];
|
||||||
|
} psx_cdrom_sector_mode1_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t sync[12];
|
||||||
|
psx_cdrom_sector_header_t header;
|
||||||
|
psx_cdrom_sector_xa_subheader_t subheader[2];
|
||||||
|
uint8_t data[0x918];
|
||||||
|
} psx_cdrom_sector_mode2_t;
|
||||||
|
|
||||||
|
_Static_assert(sizeof(psx_cdrom_sector_mode1_t) == PSX_CDROM_SECTOR_SIZE, "Invalid Mode1 sector size");
|
||||||
|
_Static_assert(sizeof(psx_cdrom_sector_mode2_t) == PSX_CDROM_SECTOR_SIZE, "Invalid Mode2 sector size");
|
||||||
|
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CHANNEL_MASK 0x1F
|
||||||
|
|
||||||
|
#define PSX_CDROM_SECTOR_XA_SUBMODE_EOR 0x01
|
||||||
|
#define PSX_CDROM_SECTOR_XA_SUBMODE_VIDEO 0x02
|
||||||
|
#define PSX_CDROM_SECTOR_XA_SUBMODE_AUDIO 0x04
|
||||||
|
#define PSX_CDROM_SECTOR_XA_SUBMODE_DATA 0x08
|
||||||
|
#define PSX_CDROM_SECTOR_XA_SUBMODE_TRIGGER 0x10
|
||||||
|
#define PSX_CDROM_SECTOR_XA_SUBMODE_FORM2 0x20
|
||||||
|
#define PSX_CDROM_SECTOR_XA_SUBMODE_RT 0x40
|
||||||
|
#define PSX_CDROM_SECTOR_XA_SUBMODE_EOF 0x80
|
||||||
|
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_MONO 0x00
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_STEREO 0x01
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_CHANNEL_MASK 0x03
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_FREQ_DOUBLE 0x00
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_FREQ_SINGLE 0x04
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_FREQ_MASK 0x0C
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_BITS_4 0x00
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_BITS_8 0x10
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_BITS_MASK 0x30
|
||||||
|
#define PSX_CDROM_SECTOR_XA_CODING_EMPHASIS 0x40
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PSX_CDROM_SECTOR_TYPE_MODE1,
|
PSX_CDROM_SECTOR_TYPE_MODE1,
|
||||||
PSX_CDROM_SECTOR_TYPE_MODE2_FORM1,
|
PSX_CDROM_SECTOR_TYPE_MODE2_FORM1,
|
||||||
|
|
Loading…
Reference in New Issue