안녕하세요. ㅠ.ㅠ.
아래 문답을 해주셨는데..
아무리 시도를 해봐도 잘 모르겠습니다.
( 혹시 관련 지식을 알수 있는 책이나 참고 사이트를 가르져 주시면 감사드리겠습니다. ㅠ.ㅠ)
TGSM610WaveFormat 이런 타입을 만들어서 acm클래수 중에 어디에 넣어야 할지 잘 모르겠습니다.
급한대로 ACMFormatChooser1 이쪽과 Out쪽에 다 넣어 봤는데 결과는 마찬가지 입니다. ㅠ.ㅠ
시샵님께서 말씀하신대로
구조체의 정보를 정확하게 넣어서 아래 구문이 실행된다면 open에러가 나지 않는다는 말씀이신가요?
WaveOutOpen (@FHandle,FDeviceID,FFmtChooser.WaveFormatEx,DWORD(@WaveOutProc),DWORD(Self),CALLBACK_FUNCTION or WAVE_MAPPED));
FFmtChooser.WaveFormatEx 이 구조체의 값은 에러가 나지 않을때와 값을 직접 넣어서 할때와
차이가 나지 않습니다. (근데도 직접 값을 집어 넣으면 에러가 나구요)
말씀하신 cbSize라는 녀석을 어떻게 FFmtChooser.WaveFormatEx 여기에 넣어 주는지 잘모르겠습니다.
// 코덱선택 대화 상자 클래스 TACMDlg 녀석은.이런식으로 필요 정보를 충당하는데..
FC:TACMFORMATCHOOSEA;
FC.cbStruct := SizeOf(FC);
FC.cbWfx := FFMtSize;
FC.fdwStyle := ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT;
FC.pwfx := FFmt;
Result:=acmFormatChoose(fc) = MMSYSERR_NOERROR; <<- 이것과 같은 것이
필요한게 아닌가요?
시샵님이 말씀하신대로라면
위에서 FFmt:PWaveFormatEx; 의 값만 충당이 되면 Open에러가 나지 않는 다는 말씀이신데요.
PWaveFormatEx <- 에 PGSM610WaveFormat 이녀석을 넣으라는 말씀이신지요?
ㅠ.ㅠ. 자꾸 여쭤봐서 죄송합니다.(그래도 다시..!!)
컴포넌트 소스를 첨부 함니다.~~원본인데 코덱 선택 다얄로그를 도무지 어떻게 없앨지
난감합니다.
혹시 수정해 주실수 있으실런지요?(무리한 부탁이라서 죄송합니다).
추가.
GlobalAllocMem, GlobalFreeMem이건 없어서 AllocMem으로 했는데요? 델파이6에서는 이런 함수가 없는것 같습니다.
( 예전에 Tip란에 올리셨던 Voip예제는 acm컴포넌트가 deAudio가된건가요? DeAudio를 구매해서 사용하기 때문에 이걸로도 시도를 해봤는데.. 이녀석은 음이 깨지더군요. 구연을 잘못했는지. ㅠ.ㅠ)
================================이전문답======================
안녕하세요. 최용일입니다.
뒤에 2바이트정보를 더 써주시면 오픈할때 에러는 안날거구요...
그러니까 넘겨주는 데이터의 크기는 SizeOf(TWaveFormatEx) + 2가 된다는 이야기죠...
TWaveFormatEx만으로는 모든 코덱의 정보를 표시할 수 없습니다. 수없이 많은 코덱이 있고 앞으로도 많은 코덱이 만들어질건데... 저렇게 정형화된 형태로는 그러한 것들을 표시하기가 힘들죠... 그래서 cbSize란 필드를 둬서 코덱에서 필요한 정보를 담을수있도록 한것입니다.
type
PGSM610WaveFormat = ^TGSM610WaveFormat;
TGSM610WaveFormat = packed record
wfx: TWaveFormatEx;
wSamplesPerBlock: Word;
end;
function BuildGSM610Header(SampleRate: integer): PGSM610WaveFormat;
begin
Result := GlobalAllocMem(sizeOf(TGSM610WaveFormat));
with Result^ do
begin
wfx.wFormatTag := WAVE_FORMAT_GSM610;
wfx.nChannels := 1;
wfx.nSamplesPerSec := SampleRate;
wfx.wBitsPerSample := 0;
wfx.nAvgBytesPerSec:= 0;
wfx.nBlockAlign := 65;
wfx.cbSize := 2;
wSamplesPerBlock := 320;
case SampleRate of
8000 : wfx.nAvgBytesPerSec := 1625;
11025: wfx.nAvgBytesPerSec := 2239;
22050: wfx.nAvgBytesPerSec := 4478;
44100: wfx.nAvgBytesPerSec := 8957;
end;
end;
end;
기억이 가물가물하지만... ACMFormatChooser도 WaveFormat를 포인터로 처리하는걸로 알고 있는데... 위함수에서 받은 포인터를 넘겨주시면 될겁니다....
쓰시고 난뒤에 GlobalFreeMem로 메모리를 해제해주셔야 할겁니다.
^^ 항상 즐코하세요...
>그럼 말씀하신대로 자료 타입 만 맞추어 주면 WaveInOpen할때 에러가 없어진다는 말씀이시겠네요.
>뒤에 2바이트가 추가로 붙는 다는 말은 어떤 말씀이신지요?
>
>
>
>
>>안녕하세요. 최용일입니다.
>>
>>아마도 GSM 6.10코덱인거 같은데...
>>
>>CbSize가 2인것에서 알 수 있듯이 뒤에 2바이트가 추가로 더 붙습니다.
>>
>>뒤에 2바이트는 Samples Per Block 입니다.
>>
>>예전에 썼던 컴포넌트지만 지금은 깔리지 않아서 예제는 힘들겠네요...
>>
>>^^ 그럼 즐코하세요...
>>
>>
>>>[질문] ACMComponent 1.6 코덱선택 대화상자를 코딩으로. 답변좀.
>>>안녕하세요.
>>>이전에 두분정도가 저랑 비슷하게 질문을 올리셨었는데.
>>>답을 봐도.. 직접 해봐도 잘 되지 않습니다.
>>>
>>>
>>> with aFmt^ do
>>> begin
>>> wFormatTag := 49;
>>> nChannels := 1;
>>> nSamplesPerSec := 44100;
>>> nAvgBytesPerSec := 8957;
>>> nBlockAlign := 65;
>>> wBitsPerSample := 0;
>>> CbSize := 2;
>>> end;
>>>
>>> SendFrm.ACMFormatChooser1.UseFormat(aFmt,SizeOf(aFmt));
>>> with SendFrm.ACMFormatChooser1 do
>>> begin
>>> wFormatTag := 49;
>>> nChannels := 1;
>>> nSamplesPerSec := 44100;
>>> nAvgBytesPerSec := 8957;
>>> nBlockAlign := 65;
>>> nBitsPerSample := 0;
>>> CbSize := 2;
>>> end;
>>>
>>>위에 처럼 EX구조체에 맞는 데이터는 다 넣어도 AcmIN 컴포넌트에서 WaveInOpen WaveFormatEx에 들어가는게 더 있다는 말씀이신지
>>>FC: TACMFORMATCHOOSEA; 이녀석을 모조리 채우라는 말씀이신지? 잘 모르겠습니다.
>>>브레이크로 찍어 보면 위에 afmt값은 동일하게 들어가는데 말이죠
>>>
>>>TACMDlg 는 TACMFormatChooser를 상속받아서 하는일이 별로 없구.
>>>TACMFormatChooser녀석도 특별한거는 없습니다. 별루 인자값을 채우는건 없구요.
>>>결국 직접 구조체의 파라미터를 채우는 것과 차이는.
>>>acmFormatChoose 이 함수의 호출인데요. 이걸 대체 할수 있는 기능이 필요한
>>>것이 아닌지요?
>>>
>>>acmFormatChoose 이넘오 FC에 구조체를 다 채워서 WaveINOpen시에 오류가 나지 않는
>>>건가요?
>>>
>>>예제 코드를 간단하게 보여주시며 안될까요?
>>>
>>>
>>
>
WaveOutOpen (@FHandle,FDeviceID,FFmtChooser.WaveFormatEx,DWORD(@WaveOutProc),DWORD(Self),CALLBACK_FUNCTION or WAVE_MAPPED));
위에 FFmtChooser.WaveFormatEx에 제가 알려드린값이 들어가면 될겁니다. ACMFormatChooser는 하도 오래전에 사용해서 사용법이 잘 기억이 안나구요...
acmFormatChoose(fc) 이함수가 다이얼로그 띄우는 것일겁니다...
^^ 그럼...