-
Всем привет. Столкнулся с такой проблемкой: при попытке преобразования миди в мп3 отсутствует звук при воспроизведении полученного мп3-файла, причем если сжимать в мп3 вав-файлы со звуком все в порядке. Пользовался bass.dll, bassmidi.dll, lame_inc.dll.
-
Вот кусок кода:
function EncodeToMP3(InFile:string; OutFile:string):boolean;
var
NumSamples:DWORD;
InBufSize: DWORD;
OutBufSize:DWORD;
BufMIDI:PSHORT;
BufMP3: PBYTE;
BassChan:HSTREAM;
beStream:THBESTREAM;
beConfig:TBECONFIG;
fWrite:TFileStream;
SizeOfRead:DWORD;
Encoded: DWORD;
ErrRes:TBeErr;
i, MIDILeng:DWORD; s: string;
begin
Result:=false;
BassChan:=BASS_MIDI_StreamCreateFile(false, PChar(InFile), 0, 0, BASS_STREAM_DECODE, 44100);
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.nQuality:=2;
beConfig.Format.LHV1.dwMpegVersion:=MPEG1;
MIDILeng:=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
BufMIDI:=AllocMem(InBufSize);
BufMP3:=AllocMem(OutBufSize);
try
i:=0;
while i<>MIDILeng do begin
if i+InBufSize<MIDILeng then SizeOfRead:=InBufSize
else SizeOfRead:=MIDILeng-i;
BASS_ChannelGetData(BassChan, BufMIDI, SizeOfRead);
ErrRes:=beEncodeChunk(beStream, SizeOfRead div 2, BufMIDI, 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(BufMIDI);
FreeMem(BufMP3);
end;
Result:=true;
end;
-
> При кодировании в MP3 отсутствует звук
Потому что полная ахинея этом в алгоритме . Ты пытаешься кодировать в mp3 не результат синтеза, а сами midi-данные.
-
> Сергей М. © (25.03.08 08:41) [2]
Покажите мне строку, где кодируются сами MIDI данные, если это BASS_ChannelGetData(BassChan, BufMIDI, SizeOfRead);, то вы глубоко не правы.
-
> VoVan © (25.03.08 05:16)
У тебя точно MIDI файл, самим bass'ом он проигрывается?
-
> Efir (25.03.08 20:44) [3]
> Покажите мне строку, где кодируются сами MIDI данные
beEncodeChunk
-
> Сергей М. © (26.03.08 08:27) [5]
И что в ней не то? BufMIDI - это уже декодированные WAVE данные. Вообще всё должно нормально работать, если только автор не намудрил где-то в других местах программы.
-
> Efir (26.03.08 21:04) [6]
Посмотрите пожалуйста на вот такую программку ( выложил сюда: http://vovand.narod.ru/proga.rar ) не знаю где там можно было намудрить, но звука нет.
-
> Efir (26.03.08 21:04) [6]
> это уже декодированные WAVE данные
Т.е. ты хочегь сказать, что синтез происходит при вызове ф-ции
BASS_MIDI_StreamCreateFile
?
В таком случае она должна работать по времени не меньше времени звучания всей midi-"композиции"..
-
Рендеринг (тот самый синтез) должен происходить при вызове BASS_ChannelPlay, а им здесь и не пахнет, как не пахнет и захватом стрима-результата рендеринга.
В то же время в строке
MIDILeng:=BASS_ChannelGetLength(BassChan);
полная лажа.
-
> VoVan © (27.03.08 07:38) [7]
У меня нормально работает. Midi файлы я использовал те, которые в самой Windows XP есть.
> Сергей М. © (27.03.08 08:47) [8]
BASS_MIDI_StreamCreateFile - создание потока. BASS_ChannelGetLength - размер данных (байт), но уже в виде PCM. BASS_ChannelGetData - непосредственно декодирование в PCM. beEncodeChunk - кодирование в mp3.
> Рендеринг (тот самый синтез) должен происходить при вызове > BASS_ChannelPlay, а им здесь и не пахнет, как не пахнет > и захватом стрима-результата рендеринга.
При вызове BASS_ChannelPlay происходит воспроизведение, а нафих оно нам нужно, если происходит непосредственное кодирование.
Прежде чем спорить, может просто проверить.
-
> BASS_MIDI_StreamCreateFile - создание потока
Потока каких данных ? PCM ? MID ?
> BASS_ChannelGetLength - размер данных (байт), но уже в виде > PCM
Они с какой луны свалятся ? Какой конкретно синтезатор сделал это чудесное превращение ? Как он умудрился сделать это мгновенно ?
> BASS_ChannelGetData - непосредственно декодирование в PCM
Откуда тогда взялся "размер данных (байт), но уже в виде PCM", если "декодирование в PCM" начнется только сейчас ?
> beEncodeChunk - кодирование в mp3.
Да хрен бы с ним, с мп3) тут дури и безо всяких мп3 по самое нехочу)
> При вызове BASS_ChannelPlay происходит воспроизведение,
Воспроизведение и есть процесс вывода на некий дивайс результатов синтеза.
> а нафих оно нам нужно, если происходит непосредственное > кодирование
Какое такое "непосредственное" ?
У меня, к примеру, sf-совместимый чипсет, и я хочу получить результирующий поток, сгенерированный ЭТИМ чипсетом на основании КОНКРЕТНОГО саундфонта с КОНКРЕТНЫМИ его параметрами.
ОТКУДА ф-ции басса знают о том, какой саундфонт я выбрал и какие параметры синтеза мне нужны ?
Да ниоткуда !
Ни с какой луны он и в басс не свалятся !
Басс будет толкать миди-поток в указанный мной синтез-дивайс (или дифолтный миди-дивайс - не знаю, да и по барабану оно), который сможет выполнить интересующий меня рендеринг не иначе как в РЕАЛЬНОМ РЕЖИМЕ ВРЕМЕНИ !
Так что горбатого ты тут лепишь, любезный)
-
> Сергей М. © (27.03.08 22:00) [11]
Чесно говоря я не могу понять, что Вы мне пытаетесь объяснить. Приведённый алгоритм в принципе рабочий, а Вы пытаетесь доказать что он работать не должен.
Ладно с самого начала.
BASS_Init(-1, 44100, 0, Handle, nil); инициализация BASS'a
hStream:=BASS_StreamCreateFile(false, PChar(InFile), 0, 0, BASS_STREAM_DECODE); - получаем хэндл потока с флагом BASS_STREAM_DECODE, то есть воспроизводить мы ничего не собираемся.
BASS_ChannelGetLength(BassChan); - длина потока в байтах. Так уж получилось но BASS выдаёт длину WAVE DATA, и не ко мне вопрос почему так, а к un4seen.
BASS_ChannelGetData(BassChan, BufMIDI, SizeOfRead); - эта функция заполняет BufMIDI или значением FFT или WAVE DATA (в зависимости от третьего флага). Если Вы и мне не верите, то посмотрите примеры, посталяемые с библиотекой (например SampleVis).
beEncodeChunk - кодирание.
-
> непосредственно декодирование в PCM
А это вообще ахинея, если
> BASS_ChannelGetLength - размер данных (байт), но уже в виде > PCM.
С какой луны свалился "размер", если "декодирование" еще и не начиналось ?
Да и само выражение "декодирование в PCM" есть ахинея, особенно когда речь идет об исходных данных в формате mid.
-
Тогда объясните мне почему алгоритм работает???
-
> Efir (27.03.08 22:32) [12]
Я тебе пытаюсь объяснить, что не следует тупо тыкать якобы работающими (что-то там якобы делающими, но непонятно что) примерами, демонстрируя при этом полнейшее дилетантство в теории и механизме происходящего при этом.
Вот и все)
Еще раз тебе говорю - я хочу, чтобы n-й трек некоей midi-композиции, хранящейся в mid-файле, в результирующем файле звучал так как я хочу, например, милицейским свистком, даже если пач там ссылается на Grand Piano в соответствии с GM.
Вопрос тебе на засыпку - услышу ли я этот вожделенный свисток в результате работы твоего якобы "в принципе работающего" кода, который сгенерирует мне какой-то там якобы ожидаемый wav (или мп3 - монопенисуально в дан.контексте) и который я укажу к воспроизведению любому "в принципе работающему" плейеру ?
-
> объясните мне почему алгоритм работает?
Оно мне надо, тебе объяснять, если ты уперся рогом ?)
-
При получении хендла ф-цией BASS_StreamCreateFile, BASS сам сканирует файл и знает о нём всё.
-
С тобой все ясно. разговор закончен.
-
> Сергей М. © (27.03.08 22:46) [15]
Согласен, в теории и механизме я разбираюсь хреново.
Вопрос автора стоял в перекодировании MID файла в mp3. Алгоритм я ему привёл, который у меня работает корректно.
> Еще раз тебе говорю - я хочу, чтобы n-й трек некоей midi- > композиции, хранящейся в mid-файле, в результирующем файле > звучал так как я хочу, например, милицейским свистком, даже > если пач там ссылается на Grand Piano в соответствии с GM. > > > Вопрос тебе на засыпку - услышу ли я этот вожделенный свисток > в результате работы твоего якобы "в принципе работающего" > кода, который сгенерирует мне какой-то там якобы ожидаемый > wav (или мп3 - монопенисуально в дан.контексте) и который > я укажу к воспроизведению любому "в принципе работающему" > плейеру ?
Это уже сложный вопрос. Откуда я знаю как работает BASS. Я не гуру в этой области, но вопрос был и я ответил на него в силу своих знаний. Никто не мешает Вам меня поправить или привести свой вариант, в конце концов это форум.
|