
Амеба

Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград
Репутация: 55 Всего: 459
|
Значит Dll ину я нашел в инете взял самую новую версию и сделал для нее заголовок. Не полный, только те функции которые были необходимы, лень было все конверить  . Код | unit mpg123;
interface
type mpg123_errors = ( MPG123_DONE = -12, //**< Message: Track ended. */ MPG123_NEW_FORMAT = -11, //**< Message: Output format will be different on next call. */ MPG123_NEED_MORE = -10, //**< Message: For feed reader: "Feed me more!" */ MPG123_ERR = -1, //**< Generic Error */ MPG123_OK = 0, //**< Success */ MPG123_BAD_OUTFORMAT, //**< Unable to set up output format! */ MPG123_BAD_CHANNEL, //**< Invalid channel number specified. */ MPG123_BAD_RATE, //**< Invalid sample rate specified. */ MPG123_ERR_16TO8TABLE, //**< Unable to allocate memory for 16 to 8 converter table! */ MPG123_BAD_PARAM, //**< Bad parameter id! */ MPG123_BAD_BUFFER, //**< Bad buffer given -- invalid pointer or too small size. */ MPG123_OUT_OF_MEM, //**< Out of memory -- some malloc() failed. */ MPG123_NOT_INITIALIZED, //**< You didn't initialize the library! */ MPG123_BAD_DECODER, //**< Invalid decoder choice. */ MPG123_BAD_HANDLE, //**< Invalid mpg123 handle. */ MPG123_NO_BUFFERS, //**< Unable to initialize frame buffers (out of memory?). */ MPG123_BAD_RVA, //**< Invalid RVA mode. */ MPG123_NO_GAPLESS, //**< This build doesn't support gapless decoding. */ MPG123_NO_SPACE, //**< Not enough buffer space. */ MPG123_BAD_TYPES, //**< Incompatible numeric data types. */ MPG123_BAD_BAND, //**< Bad equalizer band. */ MPG123_ERR_NULL, //**< Null pointer given where valid storage address needed. */ MPG123_ERR_READER, //**< Error reading the stream. */ MPG123_NO_SEEK_FROM_END,//**< Cannot seek from end (end is not known). */ MPG123_BAD_WHENCE, //**< Invalid 'whence' for seek function.*/ MPG123_NO_TIMEOUT, //**< Build does not support stream timeouts. */ MPG123_BAD_FILE, //**< File access error. */ MPG123_NO_SEEK, //**< Seek not supported by stream. */ MPG123_NO_READER, //**< No stream opened. */ MPG123_BAD_PARS, //**< Bad parameter handle. */ MPG123_BAD_INDEX_PAR, //**< Bad parameters to mpg123_index() */ MPG123_OUT_OF_SYNC, //**< Lost track in bytestream and did not try to resync. */ MPG123_RESYNC_FAIL, //**< Resync failed to find valid MPEG data. */ MPG123_NO_8BIT, //**< No 8bit encoding possible. */ MPG123_BAD_ALIGN, //**< Stack aligmnent error */ MPG123_NULL_BUFFER, //**< NULL input buffer with non-zero size... */ MPG123_NO_RELSEEK, //**< Relative seek not possible (screwed up file offset) */ MPG123_NULL_POINTER, //**< You gave a null pointer somewhere where you shouldn't have. */ MPG123_BAD_KEY, //**< Bad key value given. */ MPG123_NO_INDEX, //**< No frame index in this build. */ MPG123_INDEX_FAIL //**< Something with frame index went wrong. */ );
mpg123_enc_enum = ( MPG123_ENC_8 = $00f //**< 0000 0000 1111 Some 8 bit integer encoding. */ ,MPG123_ENC_16 = $040 //**< 0000 0100 0000 Some 16 bit integer encoding. */ ,MPG123_ENC_32 = $100 //**< 0001 0000 0000 Some 32 bit integer encoding. */ ,MPG123_ENC_SIGNED = $080 //**< 0000 1000 0000 Some signed integer encoding. */ ,MPG123_ENC_FLOAT = $800 //**< 1110 0000 0000 Some float encoding. */ ,MPG123_ENC_SIGNED_16 = (MPG123_ENC_16 or MPG123_ENC_SIGNED or $10) //**< 0000 1101 0000 signed 16 bit */ ,MPG123_ENC_UNSIGNED_16 = (MPG123_ENC_16 or $20) //**< 0000 0110 0000 unsigned 16 bit*/ ,MPG123_ENC_UNSIGNED_8 = $01 //**< 0000 0000 0001 unsigned 8 bit*/ ,MPG123_ENC_SIGNED_8 = (MPG123_ENC_SIGNED or $02) //**< 0000 1000 0010 signed 8 bit*/ ,MPG123_ENC_ULAW_8 = $04 //**< 0000 0000 0100 ulaw 8 bit*/ ,MPG123_ENC_ALAW_8 = $08 //**< 0000 0000 1000 alaw 8 bit */ ,MPG123_ENC_SIGNED_32 = MPG123_ENC_32 or MPG123_ENC_SIGNED or $10 //**< 0001 1001 0000 signed 32 bit */ ,MPG123_ENC_UNSIGNED_32 = MPG123_ENC_32 or $20 //**< 0001 0010 0000 unsigned 32 bit */ ,MPG123_ENC_FLOAT_32 = $200 //**< 0010 0000 0000 32bit float */ ,MPG123_ENC_FLOAT_64 = $400 //**< 0100 0000 0000 64bit float */ ,MPG123_ENC_ANY = ( MPG123_ENC_SIGNED_16 or MPG123_ENC_UNSIGNED_16 or MPG123_ENC_UNSIGNED_8 or MPG123_ENC_SIGNED_8 or MPG123_ENC_ULAW_8 or MPG123_ENC_ALAW_8 or MPG123_ENC_FLOAT_32 or MPG123_ENC_FLOAT_64 ) //**< any encoding */ );
pmpg123_handle = Pointer; function mpg123_init() : mpg123_errors; cdecl; function mpg123_new(const decoder : PChar; var error : integer) : pmpg123_handle; cdecl; function mpg123_open(mh : pmpg123_handle; const path : PChar) : mpg123_errors; cdecl; function mpg123_getformat(mh : pmpg123_handle; var rate : LongInt; var channels : Integer; var encoding : Integer) : mpg123_errors; cdecl;
function mpg123_plain_strerror(errcode : Integer) : PChar; cdecl; function mpg123_strerror(mh : pmpg123_handle) : PChar; cdecl; function mpg123_format_none(mh : pmpg123_handle) : mpg123_errors; cdecl; function mpg123_format(mh : pmpg123_handle; rate : LongInt; channels : Integer; encodings : LongInt) : mpg123_errors; cdecl;
function mpg123_outblock(mh : pmpg123_handle) : Cardinal; cdecl; function mpg123_read(mh : pmpg123_handle; outmemory : PByte; outmemsize : Cardinal; var done : Cardinal) : mpg123_errors; cdecl;
function mpg123_close(mh : pmpg123_handle) : mpg123_errors; cdecl; procedure mpg123_delete(mh : pmpg123_handle); cdecl; procedure mpg123_exit(); cdecl;
implementation
const mpg123Lib = 'libmpg123.dll';
function mpg123_init; external mpg123Lib name 'mpg123_init'; function mpg123_new; external mpg123Lib name 'mpg123_new'; function mpg123_open; external mpg123Lib name 'mpg123_open'; function mpg123_getformat; external mpg123Lib name 'mpg123_getformat'; function mpg123_plain_strerror; external mpg123Lib name 'mpg123_plain_strerror'; function mpg123_strerror; external mpg123Lib name 'mpg123_strerror'; function mpg123_format_none; external mpg123Lib name 'mpg123_format_none'; function mpg123_format; external mpg123Lib name 'mpg123_format'; function mpg123_outblock; external mpg123Lib name 'mpg123_outblock'; function mpg123_read; external mpg123Lib name 'mpg123_read'; function mpg123_close; external mpg123Lib name 'mpg123_close'; procedure mpg123_delete; external mpg123Lib name 'mpg123_delete'; procedure mpg123_exit; external mpg123Lib name 'mpg123_exit';
end.
|
Дальше использовал свой модуль для создания Wav файлов Код | unit WaveUtils;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; Const noError = 0; ReadError = 1; HeaderError = 2; DataError = 3; FileCorrupt = 4; IncorectFileFormat = 5; HeaderWriteError = 6; StreamError = 7;
type TWaveHeaderChank = packed record //Заголвок (чанк) формата wFormatTag : Smallint; wChannels : WORD; wSamplesPerSec : Cardinal; wAvgBytesPerSec: Cardinal; wBlockAlign : WORD; wBitsPerSample : WORD; wcbSize : WORD; end; TWaveResult = record //Минимальная структура ERROR : WORD; //Используеися для возвращения результата wSamplesPerSec : Cardinal; //разбора Wav файла wBitsPerSample : WORD; wChannels : WORD; Data : TMemoryStream; end; Function ReadWave(FileName : AnsiString) : TWaveResult; Function WriteWave(FileName : AnsiString; data : TWaveResult) : WORD;
implementation
uses math;
Function ReadWave(FileName : AnsiString) : TWaveResult; var f : TFileStream; wFileSize : Cardinal; wChankSize : Cardinal; ID : array[0..3] of Char; Header : TWaveHeaderChank; RealFileSize : Cardinal; Begin FillChar(Result, SizeOf(Result), 0); Try f := TFileStream.Create(FileName, fmOpenRead); f.Seek(0, soFromBeginning); f.ReadBuffer(ID[0], 4); //читаем тип файла if String(ID) <> 'RIFF' //Определяем тип файла then Begin Result.ERROR := IncorectFileFormat; f.Free; exit; end;
f.ReadBuffer(wFileSize, 4); //читаем размер файла
if f.size <> (wFileSize + 8) //Определяем соответствие указанного размера then //и размера файла(на случай если был поврежден при Begin //передаче) Result.ERROR := FileCorrupt; f.Free; exit; end; f.ReadBuffer(ID[0], 4);
if String(ID) <> 'WAVE' //Определяем формат файла then Begin Result.ERROR := IncorectFileFormat; f.Free; exit; end; wChankSize := 0; repeat //Ищем чанк формата f.Seek(wChankSize, soFromCurrent);//Пропускаем все дополнительные чанки f.ReadBuffer(ID[0], 4); //Читаем идентификатор чанка f.ReadBuffer(wChankSize, 4); //Читаем размер чанка if wChankSize > High(integer) //Проверяем размер загловка на разумность then //размера вероятно можно установить чило и Begin //меньше например 100 Result.ERROR := DataError; f.Free; exit; end;
until (String(ID)='fmt ') or (String(ID)='data'); if String(ID)='data' //Проверяем найден ли заголовок формата then Begin Result.ERROR := HeaderError; f.Free; exit; end; f.ReadBuffer(Header, Min(wChankSize, SizeOf(TWaveHeaderChank))); //Читаем заголовок
if wChankSize > SizeOf(TWaveHeaderChank) //Смещаем указатель чтения в конец блока then //нужно только для больших заголовков f.Seek(wChankSize - SizeOf(TWaveHeaderChank), soFromCurrent);
wChankSize := 0; repeat //Ищем чанк данных f.Seek(wChankSize, soFromCurrent);//Пропускаем все дополнительные чанки f.ReadBuffer(ID[0], 4); //Читаем идентификатор чанка f.ReadBuffer(wChankSize, 4); //Читаем размер чанка until String(ID)='data'; Result.ERROR := noError; //Заполняем структуру результата Result.wSamplesPerSec := Header.wSamplesPerSec; Result.wBitsPerSample := Header.wBitsPerSample; Result.wChannels := Header.wChannels; //Копируем данные в память Result.Data := TMemoryStream.Create; Result.Data.Seek(0, soFromBeginning); Result.Data.Size := wChankSize; //Выделяем память под данные f.ReadBuffer(Result.Data.Memory^, wChankSize); //Копируем данные в память Except Result.ERROR := ReadError; end; f.Free; end;
Function WriteWave(FileName : AnsiString; data : TWaveResult) : WORD; var f : TFileStream; wFileSize : Cardinal; wChankSize : Cardinal; ID : array[0..3] of Char; Header : TWaveHeaderChank; Begin Result := noError; Try f := TFileStream.Create(FileName, fmCreate); f.Seek(0, soFromBeginning); Header.wFormatTag := 1; Header.wChannels := data.wChannels; Header.wSamplesPerSec := data.wSamplesPerSec; Header.wBlockAlign := data.wChannels * (data.wBitsPerSample div 8); Header.wAvgBytesPerSec:= data.wSamplesPerSec * Header.wBlockAlign; Header.wBitsPerSample := data.wBitsPerSample; Header.wcbSize := 0; //нет дополнительного блока ID := 'RIFF'; f.WriteBuffer(ID, 4); wFileSize := 0; //пока не известен f.WriteBuffer(wFileSize, 4); ID := 'WAVE'; f.WriteBuffer(ID, 4); //Запись идентификатора формата ID := 'fmt '; f.WriteBuffer(ID, 4); //Запись идентификатора чанка формата wChankSize := SizeOf(Header); f.WriteBuffer(wChankSize, 4); //Запись размера чанка f.WriteBuffer(Header, SizeOf(Header)); //Запись чанка формата except Result := HeaderWriteError; end; Try ID := 'data'; f.WriteBuffer(ID, 4); //Запись чанка данных wChankSize := data.Data.Size; //Запись размера чанка f.WriteBuffer(wChankSize, 4); //Запись данных data.Data.Seek(0, soFromBeginning); f.CopyFrom(data.Data, data.Data.Size); except Result := StreamError; end; f.Seek(SizeOf(ID), soFromBeginning); //Поиск записи размера файла wFileSize := f.Size - SizeOf(ID) - SizeOf(wFileSize); f.Write(wFileSize, 4); //Запись размера файла - заголовок f.Free; end;
end.
|
И собственно тестовый проект (переделаный пример из С кода) Код | unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, WaveUtils, mpg123;
type TForm1 = class(TForm) Button2: TButton; procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
var buf : array [0..16383] of byte;
procedure TForm1.Button2Click(Sender: TObject); var buffer_size : integer; outbuf : array [0..65535] of byte;
Res : TWaveResult; done: Cardinal; err : mpg123_errors; err2: Integer; mh : pmpg123_handle; FileName : AnsiString; rate, channels, encoding : Integer; begin mh := nil; FillChar(Res, sizeof(Res), 0);
FileName := 'Ìóñîðíûé âåòåð.MP3'; try err := mpg123_init(); if err <> MPG123_OK then raise Exception.Create('Fail');
mh := mpg123_new(nil, err2); if mh = nil then raise Exception.Create('Fail');
err := mpg123_open(mh, PChar(FileName)); if (err <> MPG123_OK) then raise Exception.Create('Fail');
err := mpg123_getformat(mh, rate, channels, encoding); if (err <> MPG123_OK) then raise Exception.Create('Fail');
if(mpg123_enc_enum(encoding) <> MPG123_ENC_SIGNED_16) then raise Exception.Create('Fail');
mpg123_format_none(mh); mpg123_format(mh, rate, channels, encoding);
Res.Data := TMemoryStream.Create; Res.wChannels := channels; Res.wBitsPerSample := 16; //16 áèò íà êàíàë Res.wSamplesPerSec := rate;
buffer_size := length(outbuf); Repeat err := mpg123_read( mh, @outbuf[0], buffer_size, done); Res.Data.WriteBuffer(outbuf[0], done); until err <> MPG123_OK;
if (err <> MPG123_DONE) then raise Exception.Create('Fail');
err2 := WriteWave(ChangeFileExt(FileName, '.wav'), Res); if (err2 <> noError) then raise Exception.Create('Fail');
except ShowMessage('Fail'); end;
Res.Data.Free;
mpg123_close(mh); mpg123_delete(mh); mpg123_exit(); end;
end.
|
Проект и Dll в атаче. P.S. Имя файла забил в проект руками, там поменять надо. Работает только для для mp3 16 бит на канал, при желании можно доработать.
Присоединённый файл ( Кол-во скачиваний: 19 )
LibMp3Delphi.zip 333,85 Kb
--------------------
Vit вечная память.Обсуждение действий администрации форума производятся только в этом форумегениальность идеи состоит в том, что ее невозможно придумать
|