QUOTE
Скачать программу: >>>Soldier of Fortune tools<<<
Кто-нибудь игру смотрел?
Музыка находится в \SoF1\base\sound\music\ внутри файлов .ADP, причём разбитых на два файла, например:
lDM1.adp - левый канал (left)
rDM1.adp - правый канал (right)
Первые 4 байта (DWORD) в этих файлах - это частота (обычно у всех 22050 Hz), далее идёт сжатый звук.
Если у файла эти 4 байта отрезать, переименовать в .VOX (Dialogic ADPCM) и открыть в Adobe Audition, то музыка будет играться, даже сносно, но уж сильно зашкаливают пики - такое ощущение, что Audition её сглаживает, потому что скачал в сети сорцы для декодирования Dialogic - так там получилась, примерно, та же самая музыка, только ещё и с треском.
Никто не знает, где можно правильную таблицу ADPCM декодирования дёрнуть? Сдаётся мне, что она там своя, как у EA в NFS и от обычного .VOX отличается.
Думаю, что это .VOX формат, правда модифицированный, потому что:
- У .VOX формата нет заголовка (тут его тоже нет - только эти 4 байта прикрутили), поэтому при декодировании частота всегда указывается вручную.
- Насколько я знаю (смотрел исходные коды декодировщика) стандартный .VOX не поддерживает в явном виде 22050 Hz - только 32000 и 24000 (впрочем, частоту проигрывания никто не мешает вручную поменять).
- .VOX формат поддерживает только одногоканальный звук - поэтому тут каналы по файлам и разбили.
- Ну и, наконец, музыка проигрывается как .VOX, только немного криво из чего следует, что формат правильный, а вот таблица декодирования - нет.
Соображения у кого-нибудь есть? Файлы-примеры надо?
Исходные коды декодеровщика на Си:
oki_adpcm.c
voipcodecs/telephony.h
voipcodes/oki_adpcm.h
Мой отладочный стенд (входной файл "lDM1.adp" с уже отрубленными 4 байтами в начале, выходной - просто потоковое аудио, без .WAV заголовка):
CODE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <malloc.h>
#include "voipcodecs/oki_adpcm.h"
int main(int argc, char *argv[]){
oki_adpcm_state_t *oki_dec_state;
int16_t *post_amp;
uint8_t *oki_data;
int oki_bytes;
int dec_frames;
FILE *fl;
fl = fopen("lDM1.adp", "rb");
fseek(fl, 0, SEEK_END);
oki_bytes = ftell(fl);
fseek(fl, 0, SEEK_SET);
oki_data = (uint8_t *)malloc(oki_bytes);
post_amp = (int16_t *)malloc(oki_bytes*8);
fread(&oki_data[0], oki_bytes, 1, fl);
fclose(fl);
oki_dec_state = oki_adpcm_init(NULL, 24000);
dec_frames = oki_adpcm_decode(oki_dec_state, post_amp, oki_data, oki_bytes);
fl = fopen("lDM1.wav", "wb");
fwrite(&post_amp[0], oki_bytes, 4, fl);
fclose(fl);
oki_adpcm_release(oki_dec_state);
free(post_amp);
free(oki_data);
return(0);
}
#include <stdlib.h>
#include <stdint.h>
#include <malloc.h>
#include "voipcodecs/oki_adpcm.h"
int main(int argc, char *argv[]){
oki_adpcm_state_t *oki_dec_state;
int16_t *post_amp;
uint8_t *oki_data;
int oki_bytes;
int dec_frames;
FILE *fl;
fl = fopen("lDM1.adp", "rb");
fseek(fl, 0, SEEK_END);
oki_bytes = ftell(fl);
fseek(fl, 0, SEEK_SET);
oki_data = (uint8_t *)malloc(oki_bytes);
post_amp = (int16_t *)malloc(oki_bytes*8);
fread(&oki_data[0], oki_bytes, 1, fl);
fclose(fl);
oki_dec_state = oki_adpcm_init(NULL, 24000);
dec_frames = oki_adpcm_decode(oki_dec_state, post_amp, oki_data, oki_bytes);
fl = fopen("lDM1.wav", "wb");
fwrite(&post_amp[0], oki_bytes, 4, fl);
fclose(fl);
oki_adpcm_release(oki_dec_state);
free(post_amp);
free(oki_data);
return(0);
}