mirror of
https://github.com/ScrelliCopter/VGM-Tools
synced 2025-02-21 04:09:25 +11:00
neotools: use common wave writer in adpcm.c
This commit is contained in:
@@ -11,7 +11,7 @@ target_link_libraries(adpcm Common::wave $<$<C_COMPILER_ID:Clang,GNU>:m>)
|
|||||||
|
|
||||||
add_executable(adpcmb adpcmb.c)
|
add_executable(adpcmb adpcmb.c)
|
||||||
target_compile_options(adpcmb PRIVATE ${WARNINGS})
|
target_compile_options(adpcmb PRIVATE ${WARNINGS})
|
||||||
target_link_libraries(adpcmb Common::headers)
|
target_link_libraries(adpcmb Common::wave)
|
||||||
|
|
||||||
add_executable(neoadpcmextract adpcm.h libadpcma.c neoadpcmextract.c)
|
add_executable(neoadpcmextract adpcm.h libadpcma.c neoadpcmextract.c)
|
||||||
set_property(TARGET neoadpcmextract PROPERTY C_STANDARD 99)
|
set_property(TARGET neoadpcmextract PROPERTY C_STANDARD 99)
|
||||||
|
|||||||
@@ -13,51 +13,11 @@
|
|||||||
; Valley Bell
|
; Valley Bell
|
||||||
;----------------------------------------------------------------------------------------------------------------------------*/
|
;----------------------------------------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wave.h"
|
||||||
|
#include "util.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include "util.h"
|
|
||||||
|
|
||||||
// -- from mmsystem.h --
|
|
||||||
//FIXME: DEELT THIS
|
|
||||||
#define MAKEFOURCC(ch0, ch1, ch2, ch3) \
|
|
||||||
((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \
|
|
||||||
((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 ))
|
|
||||||
|
|
||||||
// -- from mmreg.h, slightly modified --
|
|
||||||
|
|
||||||
/* general waveform format structure (information common to all formats) */
|
|
||||||
typedef struct waveformat_tag {
|
|
||||||
uint16_t wFormatTag; /* format type */
|
|
||||||
uint16_t nChannels; /* number of channels (i.e. mono, stereo...) */
|
|
||||||
uint32_t nSamplesPerSec; /* sample rate */
|
|
||||||
uint32_t nAvgBytesPerSec; /* for buffer estimation */
|
|
||||||
uint16_t nBlockAlign; /* block size of data */
|
|
||||||
uint16_t wBitsPerSample;
|
|
||||||
} WAVEFORMAT;
|
|
||||||
|
|
||||||
/* flags for wFormatTag field of WAVEFORMAT */
|
|
||||||
#define WAVE_FORMAT_PCM 1
|
|
||||||
|
|
||||||
// -- from mm*.h end --
|
|
||||||
|
|
||||||
#define FOURCC_RIFF MAKEFOURCC('R', 'I', 'F', 'F')
|
|
||||||
#define FOURCC_WAVE MAKEFOURCC('W', 'A', 'V', 'E')
|
|
||||||
#define FOURCC_fmt_ MAKEFOURCC('f', 'm', 't', ' ')
|
|
||||||
#define FOURCC_data MAKEFOURCC('d', 'a', 't', 'a')
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t RIFFfcc; // 'RIFF'
|
|
||||||
uint32_t RIFFLen;
|
|
||||||
uint32_t WAVEfcc; // 'WAVE'
|
|
||||||
uint32_t fmt_fcc; // 'fmt '
|
|
||||||
uint32_t fmt_Len;
|
|
||||||
WAVEFORMAT fmt_Data;
|
|
||||||
uint32_t datafcc; // 'data'
|
|
||||||
uint32_t dataLen;
|
|
||||||
} WAVE_FILE;
|
|
||||||
|
|
||||||
|
|
||||||
static const long stepsizeTable[16] =
|
static const long stepsizeTable[16] =
|
||||||
@@ -169,66 +129,76 @@ static FORCE_INLINE uint32_t DeltaTReg2SampleRate(uint16_t DeltaN, uint32_t Cloc
|
|||||||
return (uint32_t)(DeltaN * (Clock / 72.0) / 65536.0 + 0.5);
|
return (uint32_t)(DeltaN * (Clock / 72.0) / 65536.0 + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int decode(const char* inPath, const char* outPath, uint32_t OutSmplRate)
|
static int decode(const char* inPath, const char* outPath, uint32_t sampleRate)
|
||||||
{
|
{
|
||||||
FILE* hFile = fopen(inPath, "rb");
|
FILE* inFile = fopen(inPath, "rb");
|
||||||
if (hFile == NULL)
|
if (inFile == NULL)
|
||||||
{
|
{
|
||||||
printf("Error opening input file!\n");
|
printf("Error opening input file!\n");
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
fseek(hFile, 0x00, SEEK_END);
|
fseek(inFile, 0, SEEK_END);
|
||||||
unsigned int AdpcmSize = ftell(hFile);
|
long adpcmSize = ftell(inFile);
|
||||||
|
fseek(inFile, 0, SEEK_SET);
|
||||||
|
|
||||||
fseek(hFile, 0x00, SEEK_SET);
|
uint8_t* adpcmData = malloc((size_t)adpcmSize);
|
||||||
uint8_t* AdpcmData = malloc(AdpcmSize);
|
fread(adpcmData, 0x01, adpcmSize, inFile);
|
||||||
fread(AdpcmData, 0x01, AdpcmSize, hFile);
|
fclose(inFile);
|
||||||
fclose(hFile);
|
|
||||||
|
|
||||||
unsigned int WaveSize = AdpcmSize * 2; // 4-bit ADPCM -> 2 values per byte
|
long wavSize = adpcmSize * 2; // 4-bit ADPCM -> 2 values per byte
|
||||||
int16_t* WaveData = malloc(WaveSize * 2);
|
int16_t* wavData = malloc((size_t)wavSize * sizeof(int16_t));
|
||||||
printf("Decoding ...");
|
printf("Decoding ...");
|
||||||
YM2610_ADPCM_Decode(AdpcmData, WaveData, WaveSize);
|
YM2610_ADPCM_Decode(adpcmData, wavData, wavSize);
|
||||||
printf(" OK\n");
|
printf(" OK\n");
|
||||||
|
|
||||||
WAVE_FILE WaveFile;
|
// Write decoded sample as WAVE
|
||||||
WaveFile.RIFFfcc = FOURCC_RIFF;
|
FILE* outFile = fopen(outPath, "wb");
|
||||||
WaveFile.WAVEfcc = FOURCC_WAVE;
|
if (outFile == NULL)
|
||||||
WaveFile.fmt_fcc = FOURCC_fmt_;
|
|
||||||
WaveFile.fmt_Len = sizeof(WAVEFORMAT);
|
|
||||||
|
|
||||||
WAVEFORMAT* TempFmt = &WaveFile.fmt_Data;
|
|
||||||
TempFmt->wFormatTag = WAVE_FORMAT_PCM;
|
|
||||||
TempFmt->nChannels = 1;
|
|
||||||
TempFmt->wBitsPerSample = 16;
|
|
||||||
TempFmt->nSamplesPerSec = OutSmplRate ? OutSmplRate : 22050;
|
|
||||||
TempFmt->nBlockAlign = TempFmt->nChannels * TempFmt->wBitsPerSample / 8;
|
|
||||||
TempFmt->nAvgBytesPerSec = TempFmt->nBlockAlign * TempFmt->nSamplesPerSec;
|
|
||||||
|
|
||||||
WaveFile.datafcc = FOURCC_data;
|
|
||||||
WaveFile.dataLen = WaveSize * 2;
|
|
||||||
WaveFile.RIFFLen = 0x04 + 0x08 + WaveFile.fmt_Len + 0x08 + WaveFile.dataLen;
|
|
||||||
|
|
||||||
hFile = fopen(outPath, "wb");
|
|
||||||
if (hFile == NULL)
|
|
||||||
{
|
{
|
||||||
printf("Error opening output file!\n");
|
printf("Error opening output file!\n");
|
||||||
free(AdpcmData);
|
free(adpcmData);
|
||||||
free(WaveData);
|
free(wavData);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
waveWrite(&(const WaveSpec)
|
||||||
|
{
|
||||||
|
.format = WAVE_FMT_PCM,
|
||||||
|
.channels = 1,
|
||||||
|
.rate = sampleRate ? sampleRate : 22050,
|
||||||
|
.bytedepth = 2
|
||||||
|
},
|
||||||
|
wavData, (size_t)wavSize * sizeof(int16_t), &waveStreamDefaultCb, outFile);
|
||||||
|
fclose(outFile);
|
||||||
|
|
||||||
fwrite(&WaveFile, sizeof(WAVE_FILE), 0x01, hFile);
|
|
||||||
fwrite(WaveData, 0x02, WaveSize, hFile);
|
|
||||||
fclose(hFile);
|
|
||||||
printf("File written.\n");
|
printf("File written.\n");
|
||||||
|
|
||||||
free(AdpcmData);
|
free(adpcmData);
|
||||||
free(WaveData);
|
free(wavData);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct waveformat_tag {
|
||||||
|
uint16_t wFormatTag; /* format type */
|
||||||
|
uint16_t nChannels; /* number of channels (i.e. mono, stereo...) */
|
||||||
|
uint32_t nSamplesPerSec; /* sample rate */
|
||||||
|
uint32_t nAvgBytesPerSec; /* for buffer estimation */
|
||||||
|
uint16_t nBlockAlign; /* block size of data */
|
||||||
|
uint16_t wBitsPerSample;
|
||||||
|
} WAVEFORMAT;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char RIFFfcc[4];
|
||||||
|
uint32_t RIFFLen;
|
||||||
|
char WAVEfcc[4];
|
||||||
|
char fmt_fcc[4];
|
||||||
|
uint32_t fmt_Len;
|
||||||
|
WAVEFORMAT fmt_Data;
|
||||||
|
char datafcc[4];
|
||||||
|
uint32_t dataLen;
|
||||||
|
} WAVE_FILE;
|
||||||
|
|
||||||
static int encode(const char* inPath, const char* outPath)
|
static int encode(const char* inPath, const char* outPath)
|
||||||
{
|
{
|
||||||
FILE* hFile = fopen(inPath, "rb");
|
FILE* hFile = fopen(inPath, "rb");
|
||||||
@@ -240,7 +210,7 @@ static int encode(const char* inPath, const char* outPath)
|
|||||||
|
|
||||||
WAVE_FILE WaveFile;
|
WAVE_FILE WaveFile;
|
||||||
fread(&WaveFile.RIFFfcc, 0x0C, 0x01, hFile);
|
fread(&WaveFile.RIFFfcc, 0x0C, 0x01, hFile);
|
||||||
if (WaveFile.RIFFfcc != FOURCC_RIFF || WaveFile.WAVEfcc != FOURCC_WAVE)
|
if (memcmp(WaveFile.RIFFfcc, "RIFF", 4) != 0 || memcmp(WaveFile.WAVEfcc, "WAVE", 4) != 0)
|
||||||
{
|
{
|
||||||
fclose(hFile);
|
fclose(hFile);
|
||||||
printf("This is no wave file!\n");
|
printf("This is no wave file!\n");
|
||||||
@@ -249,7 +219,7 @@ static int encode(const char* inPath, const char* outPath)
|
|||||||
|
|
||||||
unsigned int TempLng = fread(&WaveFile.fmt_fcc, 0x04, 0x01, hFile);
|
unsigned int TempLng = fread(&WaveFile.fmt_fcc, 0x04, 0x01, hFile);
|
||||||
fread(&WaveFile.fmt_Len, 0x04, 0x01, hFile);
|
fread(&WaveFile.fmt_Len, 0x04, 0x01, hFile);
|
||||||
while(WaveFile.fmt_fcc != FOURCC_fmt_)
|
while (memcmp(WaveFile.fmt_fcc, "fmt ", 4) != 0)
|
||||||
{
|
{
|
||||||
if (!TempLng) // TempLng == 0 -> EOF reached
|
if (!TempLng) // TempLng == 0 -> EOF reached
|
||||||
{
|
{
|
||||||
@@ -267,7 +237,7 @@ static int encode(const char* inPath, const char* outPath)
|
|||||||
fseek(hFile, TempLng, SEEK_SET);
|
fseek(hFile, TempLng, SEEK_SET);
|
||||||
|
|
||||||
WAVEFORMAT* TempFmt = &WaveFile.fmt_Data;
|
WAVEFORMAT* TempFmt = &WaveFile.fmt_Data;
|
||||||
if (TempFmt->wFormatTag != WAVE_FORMAT_PCM)
|
if (TempFmt->wFormatTag != WAVE_FMT_PCM)
|
||||||
{
|
{
|
||||||
fclose(hFile);
|
fclose(hFile);
|
||||||
printf("Error in wave file: Compressed wave file are not supported!\n");
|
printf("Error in wave file: Compressed wave file are not supported!\n");
|
||||||
@@ -288,7 +258,7 @@ static int encode(const char* inPath, const char* outPath)
|
|||||||
|
|
||||||
TempLng = fread(&WaveFile.datafcc, 0x04, 0x01, hFile);
|
TempLng = fread(&WaveFile.datafcc, 0x04, 0x01, hFile);
|
||||||
fread(&WaveFile.dataLen, 0x04, 0x01, hFile);
|
fread(&WaveFile.dataLen, 0x04, 0x01, hFile);
|
||||||
while(WaveFile.datafcc != FOURCC_data)
|
while (memcmp(WaveFile.datafcc, "data", 4) != 0)
|
||||||
{
|
{
|
||||||
if (!TempLng) // TempLng == 0 -> EOF reached
|
if (!TempLng) // TempLng == 0 -> EOF reached
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user