-
Люди, помогите, никак не могу разобраться с fmod. В коде прописал Module := FMUSIC_LoadSong(PChar(dlgOpen.Files[0])); Stream := FSOUND_Stream_Open(PChar(dlgOpen.Files[0]), ......); файл миди проигрывается поток замечательно, но вопрос в другом: Каким образом перегнать это в вав? Говорят, что можно взять данные из буфера и сохранить в вав. Будьте добры напишите КАК это сделать. А дальше я уж LAMEом это в мп3 перекодирую.
-
Можно и сразу не сохраняя в wav кодировать в mp3 lame'ом.
-
В LAMEе есть такая ф-ция beEncodeChunk(). Как в нее подать FMODовский поток STREAM чтобы закодировать в мп3?
-
Надо fmod'ом считать данные в буфер, после передать указатель на этот буфер ф-ции beEncodeChunk(). Что-то типа: beEncodeChunk(beStream, SizeOfRead div 2, BufWave, BufMP3, Encoded);
Где, SizeOfRead - сколько байт источника было считано BufWave - указатель на этот буфер BufMP3 - сюда пишется результат Encoded - сколько байт закодировано
BufWave:PSHORT; BufMP3: PBYTE;
-
Спасибо, попробую. А не объяснишь почему SizeOfRead пополам делить надо?
-
И еще вопрос: 3-й параметр ф-ции beEncodeChunc (допустим у меня он pBuffer). Как fmod'ом считать в него данные?
-
> VoVan © (19.03.08 18:56) [4]
Просто этот пример для 16 бит стерео, а SizeOfRead - кол-во семплов считанного WAV файла.
> VoVan © (19.03.08 19:29) [5]
Здесь я сказать не могу, т.к. не работал с этой библиотекой. Могу только дать пример с bass'ом.
-
Ан нет, не совсем я прав.
SizeOfRead - сколько байт источника было считано а вот BufWave:PShort - 2 байта.
Итого кол-во семплов SizeOfRead div 2.
-
А дай плиз пример с бассом.
-
function EncodeToMP3(InFile:string; OutFile:string):boolean;
var
Progress:Int64;
NumSamples:DWORD; InBufSize: DWORD; OutBufSize:DWORD;
BufWave:PSHORT; BufMP3: PBYTE;
BassChan:HSTREAM;
beStream:THBESTREAM; beConfig:TBECONFIG;
fWrite:TFileStream;
SizeOfRead:DWORD; Encoded: DWORD;
ErrRes:TBeErr;
i, WAVLeng, SampleSize:DWORD;
s:string;
begin
Result:=false;
BassChan:=BASS_StreamCreateFile(false, PChar(InFile), 0, 0, BASS_STREAM_DECODE);
if BassChan=0 then begin
BASS_StreamFree(BassChan);
Exit;
end;
FillChar(LameConfig, SizeOf(LameConfig), 0);
beConfig.Format.dwConfig:=BE_CONFIG_LAME;
beConfig.Format.LHV1.dwStructVersion:=1;
beConfig.Format.LHV1.dwStructSize:=SizeOf(LameConfig);
beConfig.Format.LHV1.dwSampleRate:=44100;
beConfig.Format.LHV1.dwReSampleRate:=0;
beConfig.Format.LHV1.nMode:=BE_MP3_MODE_STEREO;
beConfig.Format.LHV1.dwBitrate:=192;
beConfig.Format.LHV1.dwMaxBitrate:=320;
beConfig.Format.LHV1.nPreset:=LQP_HIGH_QUALITY;
beConfig.Format.LHV1.dwMpegVersion:=MPEG1;
beConfig.Format.LHV1.dwPsyModel:=0;
beConfig.Format.LHV1.dwEmphasis:=0;
beConfig.Format.LHV1.bPrivate:=false;
beConfig.Format.LHV1.bCRC:=false;
beConfig.Format.LHV1.bCopyright:=false;
beConfig.Format.LHV1.bOriginal:=false;
beConfig.Format.LHV1.bWriteVBRHeader:=false;
beConfig.Format.LHV1.bEnableVBR:=false;
beConfig.Format.LHV1.nVBRQuality:=2;
beConfig.Format.LHV1.nVbrMethod:=VBR_METHOD_NONE;
beConfig.Format.LHV1.dwVbrAbr_bps:=0;
WAVLeng:=BASS_ChannelGetLength(BassChan);
ErrRes:=beInitStream(beConfig, NumSamples, OutBufSize, beStream);
if ErrRes<>BE_ERR_SUCCESSFUL then begin
beCloseStream(beStream);
BASS_StreamFree(BassChan);
Exit;
end;
InBufSize:=NumSamples*4;
s:=ExtractFileName(InFile);
OutFile:=OutFile+Copy(s, 1, Length(s)-Length(ExtractFileExt(s)))+'.mp3';
fWrite:=TFileStream.Create(OutFile, fmCreate);
try
BufWave:=AllocMem(InBufSize);
BufMP3:=AllocMem(OutBufSize);
FillChar(BufWave^, InBufSize, 0);
FillChar(BufMP3^, OutBufSize, 0);
try
i:=0;
Progress:=0;
while i<>WAVLeng do begin
if i+InBufSize<WAVLeng then SizeOfRead:=InBufSize
else SizeOfRead:=WAVLeng-i;
BASS_ChannelGetData(BassChan, BufWave, SizeOfRead);
ErrRes:=beEncodeChunk(beStream, SizeOfRead div 2, BufWave, BufMP3, Encoded);
if ErrRes<>BE_ERR_SUCCESSFUL then Exit;
fWrite.WriteBuffer(BufMP3^, Encoded);
i:=i+SizeOfRead;
if Terminated then Exit;
end;
ErrRes:=beDeinitStream(beStream, BufMP3, Encoded);
if ErrRes<>BE_ERR_SUCCESSFUL then Exit;
fWrite.WriteBuffer(BufMP3^, Encoded);
finally
fWrite.Free;
BASS_StreamFree(BassChan);
beCloseStream(beStream);
end;
finally
FreeMem(BufWave);
FreeMem(BufMP3);
end;
Result:=true;
end; Но это только для кодирования файлов 44100 кГц, 16 бит, Стерео.
-
А как бы сделать то же самое, только с миди :) ?
-
Вот блин, к bass'у для работы с MIDI нужно подключать плагин, а так код остаётся тот же.
-
А что делать с NumSamples? В миди ведь нету сэмплов. Или я что-то путаю?
-
Ф-ция BASS_ChannelGetData() записывает в буфер уже декодированные данные в виде PCM.
-
Насчет плагина. Где его взять, как его подключить и как с ним работать?
-
Все добро качается с оф. сайта www.un4seen.com. Загрузка плагина проста, всего две функции BASS_PluginLoad() BASS_PluginFree()
После загрузки плагина работа с потоком не меняется, он создаётся так же BASS_StreamCreateFile(), bass сама определяет какую библиотеку использовать при воспроизведении формата, отлично от того, кот-е поддреживает bass.dll (есс-но при условии что загружен плагин).
В принципе работа с библиотекой достаточна проста, всё неплохо написано в хелпе к ней. К тому же, с ней идут и примеры.
-
HPLUGIN BASS_PluginLoad( char *file, DWORD flags );
здесь *file = "bassmidi.dll"?
-
да
-
Усе. Вроде бы с теорией разобрался. Огромное спасибо. Буду пытаться кодить.
-
потестил ф-цию function EncodeToMP3(InFile:string; OutFile:string):boolean; вылетает(выдает ошибку) на определенной итерации цикла while.
encoded ... 0 i ... 9216 InBufSize ... 4608 OutBufSize ... 7920 SizeOfRead ... 4608 WavLeng ... 42158
на следующем круге i=13824, encoded=288 (все предыдущие encoded были 0) вылетает при попытке записи fWrite.WriteBufferStream
-
Есть кое какие ошибки. А так работает? function EncodeToMP3(InFile:string; OutFile:string):boolean;
var
NumSamples:DWORD;
InBufSize: DWORD;
OutBufSize:DWORD;
BufWave:PSHORT;
BufMP3: PBYTE;
BassChan:HSTREAM;
beStream:THBESTREAM;
beConfig:TBECONFIG;
fWrite:TFileStream;
SizeOfRead:DWORD;
Encoded: DWORD;
ErrRes:TBeErr;
i, WAVLeng:DWORD;
begin
Result:=false;
BassChan:=BASS_StreamCreateFile(false, PChar(InFile), 0, 0, BASS_STREAM_DECODE);
if BassChan=0 then begin
BASS_StreamFree(BassChan);
Exit;
end;
FillChar(beConfig, SizeOf(beConfig), 0);
beConfig.Format.dwConfig:=BE_CONFIG_LAME;
beConfig.Format.LHV1.dwStructVersion:=1;
beConfig.Format.LHV1.dwStructSize:=SizeOf(beConfig);
beConfig.Format.LHV1.dwSampleRate:=44100;
beConfig.Format.LHV1.dwReSampleRate:=0;
beConfig.Format.LHV1.nMode:=BE_MP3_MODE_STEREO;
beConfig.Format.LHV1.dwBitrate:=192;
beConfig.Format.LHV1.dwMaxBitrate:=320;
beConfig.Format.LHV1.nPreset:=LQP_HIGH_QUALITY;
beConfig.Format.LHV1.dwMpegVersion:=MPEG1;
WAVLeng:=BASS_ChannelGetLength(BassChan);
ErrRes:=beInitStream(beConfig, NumSamples, OutBufSize, beStream);
if ErrRes<>BE_ERR_SUCCESSFUL then begin
beCloseStream(beStream);
BASS_StreamFree(BassChan);
Exit;
end;
InBufSize:=NumSamples*4;
fWrite:=TFileStream.Create(OutFile, fmCreate);
try
BufWave:=AllocMem(InBufSize);
BufMP3:=AllocMem(OutBufSize);
try
i:=0;
while i<>WAVLeng do begin
if i+InBufSize<WAVLeng then SizeOfRead:=InBufSize
else SizeOfRead:=WAVLeng-i;
BASS_ChannelGetData(BassChan, BufWave, SizeOfRead);
ErrRes:=beEncodeChunk(beStream, SizeOfRead div 2, BufWave, BufMP3, Encoded);
if ErrRes<>BE_ERR_SUCCESSFUL then Exit;
fWrite.WriteBuffer(BufMP3^, Encoded);
i:=i+SizeOfRead;
end;
ErrRes:=beDeinitStream(beStream, BufMP3, Encoded);
if ErrRes<>BE_ERR_SUCCESSFUL then Exit;
fWrite.WriteBuffer(BufMP3^, Encoded);
finally
fWrite.Free;
BASS_StreamFree(BassChan);
beCloseStream(beStream);
end;
finally
FreeMem(BufWave);
FreeMem(BufMP3);
end;
Result:=true;
end;
-
И midi вроде норм. кодирует.
-
Ругается на beConfig.Format.dwConfig:=BE_CONFIG_LAME; исправил на beConfig.dwConfig:=BE_CONFIG_LAME;
и все равно выкидывает на fWrite.WriteBuffer(BufMP3^, Encoded);
А у тебя работает нормально?
-
После вызова ErrRes:=beEncodeChunk(beStream, SizeOfRead div 2, BufWave, BufMP3, Encoded); переменные InBufSize и OutBufSize принимают какие-то странно большие значения Encoded при каждом новом запуске проги разные
-
Да. А у тебя какие заголовочные файлы к lame_enc.dll, от TLame?
-
чуть другие. А откуда скачать от TLame?
-
-
Я брал инфу для заголовочных файлов из исходников CDex и TLame.
-
вот у меня как раз был хедер с mp3export.pas. Взял от TLame, теперь заработало. Огромное спасибо. А в случае с миди, достаточно просто подключить плагин, или надо еще в начале выходного mp3-файла что-то прописывать?
-
Достаточно просто подключить плагин. По крайней мере я попробовал кодировать с midi никаких проблем не вызвало.
-
А у меня вот какая проблема: при кодированиии вав все отлично, а миди вроде кодируется тоже нормально, но когда я его воспроизвожу звука почему-то нет.
|