안녕하세요.
gsm으로 음성을 녹음시키려 하는데 제대로 되지 않네요
녹음은 정상적으로 되는것 같은데 플레이를 해보면
처음 0.5초가량만 빼놓고는 엄청난 노이즈음이 섞여 들려
음성을 분간할수가 없습니다. gsm이 아닌 pcm등의
고용량의 포멧으로 녹음할때에는 잘 들리는것도 이상합니다.
아래는 재생과 녹음의 소스인데
제가 잘못한 부분이 어디인지 알려주시면 정말 감사하겠습니다.
(음성 컴포넌트로는 ACMIn, ACMOut, ACMConvertor를 사용하였습니다)
ps. 혹시 gsm보다 음성압축률이 더 좋은 코덱이 있나요?
그것을 녹음및 플레이할수 있는 컴포넌트도 있다면 좋을텐데..
알고 계신분 있으시다면 리플좀 부탁드립니다.
{------------------------------------------------------------------}
[녹음]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ACMOut, ACMIn, ACMConvertor, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ACMConvertor1: TACMConvertor;
ACMIn1: TACMIn;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ACMIn1BufferFull(Sender: TObject; Data: Pointer;
Size: Integer);
private
{ Private declarations }
public
{ Public declarations }
SaveFile:TFileStream;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
try
ACMConvertor1.ChooseFormatIn(True);
except
showmessage('지원하지 않는 파일형식');
end;
ACMIn1.Open(ACMConvertor1.FormatIn);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
ACMIn1.Close;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SaveFile := TFileStream.Create('c:test.dat',fmCreate or fmOpenReadWrite);
SaveFile.Position := 0;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
try
SaveFile.Free;
except
end;
end;
procedure TForm1.ACMIn1BufferFull(Sender: TObject; Data: Pointer;
Size: Integer);
begin
SaveFile.Write(Data^,Size);
end;
end.
{------------------------------------------------------------------}
[재생]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ACMOut, ACMIn, ACMConvertor, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
ACMConvertor1: TACMConvertor;
ACMOut1: TACMOut;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
OpenFile:TFileStream;
end;
procedure PlayWaveStream(Stream:TStream;Size:integer;aFormat:TACMWaveFormat);
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure PlayWaveStream(Stream:TStream;Size:integer;aFormat:TACMWaveFormat);
var
data:PChar;
gauage,buffersize:integer;
begin
Stream.Position := 0;
buffersize := 1024;
gauage := 0;
GetMem(data,buffersize);
With TACMOut.Create(nil) Do
begin
Open(aFormat);
while gauage <= Stream.Size do
begin
Stream.Read(data^,buffersize);
Play(data^,buffersize);
gauage := gauage + buffersize;
end;
end;
FreeMem(data,buffersize);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
try
ACMConvertor1.ChooseFormatOut(True);
PlayWaveStream(OpenFile,1024,ACMConvertor1.FormatOut);
except
showmessage('지원하지 않는 파일형식');
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
OpenFile := TFileStream.Create('c:test.dat', fmOpenRead);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
try
OpenFile.Free;
except
end;
end;
end.
{-------------------------------------------------------------------}
제가 알기로는 MS에서 사용할수 없게끔 프로텍션을 걸어 놓은 것으로압니다.
따라서 일련의 특정한 초기화 방법을 사용해야 제대로 돌아가게 됩니다.
그방법은 물론 MS가 안가르쳐 줍니다.
아마도 MS가 GSM에 압축방식에 대한 특허료를 지불하고
코덱을 만들어서 일겁니다.
G723.1인가 하고 Wma도 역시 마찬가지 이유로 공개되지 않았습니다.
하지만 방법은 존재하죠, 어떤분이 쓰신 사용법 입니다.
저도 안해봤습니다.
라이센스에 위배되는지도 모릅니다. 주의해서 쓰시길 바랍니다.
------------------------------------------------------------
GSM610, G723.1 사용법
type
TSelectCodec = (PCM, ADPCM, GSM610, G723);
type
TACMWaveFormat = packed record
case integer of
0 : (Format :TWaveFormatEx);
1 : (RawData :Array[0..128] of byte);
end;
TG723WaveFormat = record
wf :TWaveFormatEx;
extra :array[0..128] of BYTE;
end;
function TACMConfig.ACMConfig: Pointer;
Var
GSMWaveFmtEx :array[0..49] of Byte;
G723WaveFormat :TG723WaveFormat;
outp :PChar;
begin
getmem(outp,50);
if codec = GSM610 then begin
GSMWaveFmtEx[0] := $31;
GSMWaveFmtEx[1] := $00;
GSMWaveFmtEx[2] := $01;
GSMWaveFmtEx[3] := $00;
GSMWaveFmtEx[4] := $40;
GSMWaveFmtEx[5] := $1F;
GSMWaveFmtEx[6] := $00;
GSMWaveFmtEx[7] := $00;
GSMWaveFmtEx[8] := $59;
GSMWaveFmtEx[9] := $06;
GSMWaveFmtEx[10] := $00;
GSMWaveFmtEx[11] := $00;
GSMWaveFmtEx[12] := $41;
GSMWaveFmtEx[13] := $00;
GSMWaveFmtEx[14] := $00;
GSMWaveFmtEx[15] := $00;
GSMWaveFmtEx[16] := $02;
GSMWaveFmtEx[17] := $00;
GSMWaveFmtEx[18] := $40;
GSMWaveFmtEx[19] := $01;
GSMWaveFmtEx[20] := $2A;
GSMWaveFmtEx[21] := $2E;
GSMWaveFmtEx[22] := $66;
GSMWaveFmtEx[23] := $6D;
GSMWaveFmtEx[24] := $74;
GSMWaveFmtEx[25] := $29;
GSMWaveFmtEx[26] := $00;
GSMWaveFmtEx[27] := $2A;
GSMWaveFmtEx[28] := $2E;
GSMWaveFmtEx[29] := $66;
GSMWaveFmtEx[30] := $6D;
GSMWaveFmtEx[31] := $74;
GSMWaveFmtEx[32] := $00;
GSMWaveFmtEx[33] := $41;
GSMWaveFmtEx[34] := $6E;
GSMWaveFmtEx[35] := $79;
GSMWaveFmtEx[36] := $20;
GSMWaveFmtEx[37] := $66;
GSMWaveFmtEx[38] := $69;
GSMWaveFmtEx[39] := $6C;
GSMWaveFmtEx[40] := $65;
GSMWaveFmtEx[41] := $28;
GSMWaveFmtEx[42] := $2A;
GSMWaveFmtEx[43] := $2E;
GSMWaveFmtEx[44] := $2A;
GSMWaveFmtEx[45] := $29;
GSMWaveFmtEx[46] := $00;
GSMWaveFmtEx[47] := $2A;
GSMWaveFmtEx[48] := $2E;
GSMWaveFmtEx[49] := $2A;
move(GSMWaveFmtEx[0],outp^,50) ;
end;
if codec = G723 then begin
G723WaveFormat.wf.wFormatTag := 66;
G723WaveFormat.wf.nChannels := 1;
G723WaveFormat.wf.nSamplesPerSec := 8000;
G723WaveFormat.wf.nAvgBytesPerSec := 800;
G723WaveFormat.wf.nBlockAlign := 24;
G723WaveFormat.wf.wBitsPerSample := 0;
G723WaveFormat.wf.cbSize := 10;
G723WaveFormat.extra[0] := 2;
G723WaveFormat.extra[1] := 0;
G723WaveFormat.extra[2] := $CE;
G723WaveFormat.extra[3] := $9A;
G723WaveFormat.extra[4] := $32;
G723WaveFormat.extra[5] := $F7;
G723WaveFormat.extra[6] := $A2;
G723WaveFormat.extra[7] := $AE;
G723WaveFormat.extra[8] := $DE;
G723WaveFormat.extra[9] := $AC;
move(G723WaveFormat, outp^, 50);
end;
if codec = PCM then begin
getmem(fc.pwfx, 50);
fc.pwfx.wFormatTag := 1;
fc.pwfx.nChannels := 1;
fc.pwfx.nSamplesPerSec := 8000;
fc.pwfx.nAvgBytesPerSec := 8000;
fc.pwfx.nBlockAlign := 1;
fc.pwfx.wbitspersample := 8;
fc.pwfx.cbSize := 129;
move(fc.pwfx^,outp^,50);
end;
Result := outp;
end;