Q&A

  • acm 음성전송에 대한... 죄송합니다. 다시~
안녕하세요. ㅠ.ㅠ.
아래 문답을 해주셨는데..
아무리 시도를 해봐도 잘 모르겠습니다.
( 혹시 관련 지식을 알수 있는 책이나 참고 사이트를 가르져 주시면 감사드리겠습니다. ㅠ.ㅠ)
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시에 오류가 나지 않는
>>>건가요?
>>>
>>>예제 코드를 간단하게 보여주시며 안될까요?
>>>
>>>
>>
>
4  COMMENTS
  • Profile
    최용일 2005.02.14 08:03
    안녕하세요. 최용일입니다.

    WaveOutOpen (@FHandle,FDeviceID,FFmtChooser.WaveFormatEx,DWORD(@WaveOutProc),DWORD(Self),CALLBACK_FUNCTION or WAVE_MAPPED));

    위에 FFmtChooser.WaveFormatEx에 제가 알려드린값이 들어가면 될겁니다. ACMFormatChooser는 하도 오래전에 사용해서 사용법이 잘 기억이 안나구요...

    acmFormatChoose(fc) 이함수가 다이얼로그 띄우는 것일겁니다...

    ^^ 그럼...

  • Profile
    kivalan 2005.02.15 05:01
    계속 답변을 달아 주시는데 고맙고 죄송합니다. 잘 이해가 안가서요..

    acmFormatChoose(fc) 넵 이 함수가 다이얼로그 띄우는것 맞습니다.
    제가 궁금한 것은
    FFmtChooser.WaveFormatEx 형식이 TWAVEFormatEX인데.
    FFmtChooser에는 PWaveFormatEx 타입으로 정의 되어 있습니다. 즉 PWaveFormatEx이
    가르키는 타입은 TWaveFormatEx인데..

    이걸 사용해서 한다고 해도.
        TGSM610WaveFormat = packed record
            wfx: TWaveFormatEx; <- PWaveFormatEx 이걸로 선언해서.
            wSamplesPerBlock: Word;
        end;

    FFmtChooser.WaveFormatEx := GSM610WaveFormat.sfx 이렇게 매핑을 시키라는
    말씀이신지요? ㅠ.ㅠ 결극 내부적으로 GSM610에 대한 정보를 이용할수 있는 방법이
    지금 구조상으로 있는건지요?
    결국 아래 문장이 처리될때?
    WaveOutOpen (@FHandle,FDeviceID,FFmtChooser.WaveFormatEx,DWORD@WaveOutProc),DWORD(Self),CALLBACK_FUNCTION or WAVE_MAPPED));
    FFmtChooser.WaveFormatEx 이것에 대한 값은 TWaveFormatEx여기있는 정보가 다 아닌가요?
    cbSize 에 해당하는 TGSM610WaveFormat에 대한 추가 정보를 WaveOutOpen함수가 처리될때
    인자가 값을 가지고 있는 구조가 있는건지요?

    아~~~ 이러저래 해도 잘 안돼네욤 ^^;




  • Profile
    최용일 2005.02.15 17:55
    안녕하세요. 최용일입니다.

    몇번 말씀을 드렸는데... 이해를 못하시네요... ㅠㅠ

    waveInOpen할때 필요한 정보는 세번째 인자 LPWAVEFORMATEX pwfx에 들어있습니다. 대부분 필수적인 정보는 레코드구조체 안에 정의되어 있지만 코덱에 따라서 있습니다. 이 때문에 이 구조체 안에 cbSize란 필드가 있는거구요. waveInOpen할 때 넘겨주는 인자형은 포인터형입니다. 메모리 번지죠. PWaveFormatEx형을 넘겨주든 다른형의 포인터를 넘겨주든 waveInOpen <= 이넘이 알 수는 없습니다. 단지 넘어온 포인터가 LPWAVEFORMATEX형이라고 생각하고 거기에 맞게 데이터를 추출해서 일을 할 뿐입니다. cbSize에 값이 들어가 있으면 그 값만큼 추가적으로 더 읽어서 작업을 하는거죠..

    PGSM610WaveFormat에 들어있는 값들도 델파이적인게 아니라 메모리차원에서 보면 앞부분은 LPWAVEFORMATEX과 똑같습니다.

    휴...

    TWaveFormatEx의 크기가 24입니다.
    PCM같은 경우는 24바이트의 메모리를 할당해서 그 메모리 번지를 waveInOpen할 때 넘겨주시면 되구요.
    GSM은 26바이트의 메모리를 할당해서 그 메모리 번지를 waveInOpen할 때 넘겨주셔야 합니다.

    TACMFormatChooser는 진짜 오래전에 사용해서 사용법을 다 까먹었습니다...

    하실려고 하시는 일이 정확히 뭔지, 왜 이 컴포넌트를 사용하는지에 대해서 좀더 알려주시면...

    더 낳은 해결책이나 더 좋은 컴포넌트를 알려드릴 수 있을거 같습니다.

    ^^ 항상 즐코하세요...

  • Profile
    kivalan 2005.02.16 04:40
    앗 이제애 이해를 했ㄴ요.
    waveInOpen 인자가 타입형포인터줄 알고 헷갈려 했습니다.
    TACMFormatChooser.UseCB라는 녀석이 Pointer 형을 받아 들이게 되어 있네욤 ㅠ.ㅠ
    테스트를 해보니 잘 됩니다.  
    계속 될 질문에 힘드셨을 텐데.
    다시~ 감사들 드립니다~~ ~~ ^^;



    • 신재민
    • 2005.02.13 09:59
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 히히
      2005.02.14 20:08
      Form에서 보면 KeyPreView가 있습니다. 이넘을 True 로 주면 키보드 Input을 Edit보다 Form의 KeyDown에서...
    • 깜장곰
    • 2005.02.13 02:00
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2005.02.14 21:26
      안녕하세요. 최용일입니다. 메인폼의 OnCreate이벤트에서 아래와 같이 해보세요... procedure TForm1...
    • 김상균
      2005.02.12 18:39
          TPanel((Sender as TImage32).Parent).Color := clActiveCaption;
    • 이중철
      2005.02.14 18:04
      지금 보면 ImgCenter의 Parent를 설정하지 않았네요 설정하지 않으면 (Sender as TImage32).Parent는 nil...
    • nilriri™
      2005.02.12 10:36
      '파일 다운로드' 라는 제목의 윈도우가 생성되는지 감시했다가 핸들값을 얻어다가...프로세스를kill하시면 ...
    • 송인화
    • 2005.02.12 05:15
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 이중철
      2005.02.12 09:15
      strText[1] => A strText[2] => B strText[3] => C 어떤것을 원하나요? for i := 1 to Leng...
    • 송인화
      2005.02.12 18:18
      답변 감사합니다. ^^ 즐거운 주말 보내세요~
    • 김종현
    • 2005.02.12 03:50
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 이중철
      2005.02.12 09:21
      select sum(수량) as 입고 ...... 만약 입고와 출고를 같이 나오게 할려면 상호 Outer join해야 하는데 ...
    • 김종현
      2005.02.12 21:45
      답변 고맙습니다. 죄송한데 제가 완전 초보라서 그러니 좀 자세하게 가르쳐주심 안될까요? 너무 막막...
    • nilriri™
      2005.02.14 21:46
      RDBMS가 오라클 8i이상이라면 쿼리 한번으로 합계 누계까지 가능할껍니다. 물론 다른 디비라도..union a...
    • 송인화
    • 2005.02.11 22:57
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 히히
      2005.02.11 23:49
      ClientSocket의 OnError 이벤트 핸들러를 다음과 같이..... procedure TForm1.ClientSocket1Error(Sende...
    • 송인화
      2005.02.12 02:16
      안녕 하세요.. 답변 감사 드립니다.. OnError 이벤트를 처리하니깐.. 알수가 있더군요.. 한가...
    • 채팅
      2005.02.12 14:52
      clientSocket은 NonBlocking소켓입니다. 그래서 일단 Open메소드를 부르면 연결이 성공하든 실패하든 다음...
    • 송인화
      2005.02.12 19:42
      안녕 하세요.. 답변 감사 드립니다... ClientSocket은 NonBlocking소켓이라구 하셨는데요.. &...
    • kivalan
    • 2005.02.11 22:55
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2005.02.14 08:03
      안녕하세요. 최용일입니다. WaveOutOpen (@FHandle,FDeviceID,FFmtChooser.WaveFormatEx,DWORD(@WaveOut...
    • kivalan
      2005.02.15 05:01
      계속 답변을 달아 주시는데 고맙고 죄송합니다. 잘 이해가 안가서요.. acmFormatChoose(fc) 넵 이 함수...
    • 최용일
      2005.02.15 17:55
      안녕하세요. 최용일입니다. 몇번 말씀을 드렸는데... 이해를 못하시네요... ㅠㅠ waveInOpen할때 필...
    • kivalan
      2005.02.16 04:40
      앗 이제애 이해를 했ㄴ요. waveInOpen 인자가 타입형포인터줄 알고 헷갈려 했습니다. TACMFormatChooser....
    • 남경만
    • 2005.02.11 17:52
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 남경만
      2005.02.13 02:50
      덕분에 쉽게 끝낼 수 있게 되었네요... ㅎㅎㅎ 저도 어여 질문만 하는 사람이 아니고.. 여러분처...
    • 강재규
      2005.02.12 20:35
      제일 간단한 방법인거 같아서 올립니다. Quickrep1의 Properties에 보시면 Page가 있어요... 거기에 Colu...
    • nilriri™
      2005.02.11 23:10
      기존에 하시던것처럼. 디자인을 하신다음에.. qrdbtext컴포넌트를 놓으시고 데이터셋과 필드명을 연결해...
    • kivalan
      2005.02.11 22:21
      젤 좋은 방법은 퀵레포트에서 다단 출력을 지원하는 것이겠지만요.(이부분은 좀 확인이 필요합니다). 간...
    • 김진태
    • 2005.02.10 07:15
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 델티즌
      2005.02.11 09:14
      자주 실수하는 부분이죠. 변수가 문자인 경우는 문자열이 아닌 문자로 취급해야 합니다. case &nb...
    • 김영미
      2005.06.01 21:01
      한참 헤메다가 답변하신 부분 참조합니다. 정말 감사합니다. 항상 행복하시길 빕니다.( __)꾸벅.
    • kivalan
      2005.02.11 05:33
      말그대로 Ordinal type required 순서적인 값을 가지고 있는 타입만 가능하네요. var abc: Char; begin ...
    • nilriri™
      2005.02.11 23:02
      indy 컴포넌트를 이용하시면 좀더 간단할거 같습니다. 꼭 웹브라우져 컨트롤을 사용하셔야 한다면 행...
    • 이재현
      2005.02.12 10:00
      우선 답변 감사드립니다. ^^; 그렇게 간단한거라면 질문을 올리지 않았죠.. ^^;; 자답 입니다.. ^^; ...
    • nilriri™
      2005.02.12 10:48
      그런 방법도 있었군요...^^; 감사합니다... 보통은 자신만 알고 넘어가버리기 쉬운데...힘들게 알아 내...
    • 박지용
      2005.02.11 19:56
      TThread.OnTerminate Even를 사용하시면 될 것 같네요...^^ 그럼.
    • 파멸의슬픔
      2005.02.11 21:03
      간단 예제 올려드려요... 보시구 하세엽 그럼 이만~
    • 김상균
    • 2005.02.08 04:22
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 난 백만당적이다.
      2005.02.08 01:02
      goEdit를 True로 한 다음 OnCanEditCell 이벤트에서 CanEdit 를 False로 하면 됩니다.  ...
    • 이소룡
    • 2005.02.07 17:48
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 델티즌
      2005.02.08 10:16
      2003에서 이상한 현상들이 많이 발생하고 있습니다. 꼭 델파이의 문제는 아니듯 싶습니다. 2003 서비스팩...
    • 김춘수
      2005.02.07 22:44
      2003에 사용하는데 전혀 이상무입니다. 델파이7, 5 모두 사용 혹시 델파이 원본이 이상한것 아닐까요 ...
    • 난 백만당적이다.
      2005.02.07 20:06
      테이블은 단지 보여지는 기능만 하게 하구요... 저장은 쿼리로 하면 문제가 해결될것같은데요.... 여러개...
    • 무심코
      2005.02.07 22:15
      첨에 델파이를 쓸때 저도 이부분에 대해서 무척 고민에 빠졌습니다. DataSource.AutoEdit 를 false 로 해...