>source

처리 과정에서 Ray-Tracing을 통해 청각을 프로그래밍하려고합니다. Ray Tracer의 정보를 통해 샘플을 편집하려면 .wav 파일 (파일 형식 : PCM 서명, 16 비트, 스테레오, 2 바이트/프레임, 리틀 엔디안)을 부동 배열로 변환해야합니다.

오디오 입력 스트림과 DataInputStream을 통해 오디오를 변환했습니다. 여기서 오디오를 바이트 배열로로드합니다.

그런 다음 바이트 배열을 이와 같이 부동 배열로 변환합니다.

byte[] samples;
float[] audio_data = float(samples);

float Array를 다시 .wav 파일로 변환하면 원본 오디오 파일 소리가 들립니다.

그러나 다른 Float Array를 Original 신호에 추가하고 다시 a로 변환하면. 위의 방법을 통해 wav 파일 (같은 신호를 추가하더라도) 원하는 신호 대신 백색 잡음 신호를 얻습니다 (백색 잡음이 변조 된 원래 신호를들을 수 있지만 매우 조용합니다).

이 문제에 대해 전에 읽은 것은 float 배열에서 바이트 배열로 변환하면 문제가 발생할 수 있다는 것입니다. float는 32 비트 데이터 유형이고 바이트 (Java)는 16 비트에 불과하고 바이트가 잘못 혼합되어 화이트 노이즈가 발생하기 때문입니다. 처리에는 부호있는 16 비트 정수 (이름 : "short")가있는 데이터 유형이 있지만 더 이상 진폭을 수정할 수 없으므로 float 값이 필요하므로 short로 변환 할 수 없습니다.

또한 신호를 16 비트 값 (-32768/32767)에서 -1/1의 값으로 변조하고 신호를 믹싱 (추가) 한 후 다시 변조하여 플로트 배열의 오버플로 (진폭)를 처리하려고했습니다. 결과는 나에게 백색 소음을 주었다. 두 개 이상의 신호를 추가하면 아무것도 나에게 아무것도주지 않습니다.

구체적으로 해결하고자하는 문제는 플로트 어레이 형태로 많은 신호 (정확한 지연을 생성하기 위해 적절한 지연으로 1000 개 이상)를 추가하는 것입니다. 그런 다음 화이트 노이즈없이 오디오 파일로 저장하려는 하나의 Float Array에 결합하고 싶습니다.

내가 당신을 도울 수 있기를 바랍니다.


  • 답변 # 1

    진정한 PCM 데이터 포인트가 있으면 간단한 추가를 사용하는 데 아무런 문제가 없습니다. 유일한 문제는 드문 경우이지만 (오디오가 너무 뜨겁지 않다고 가정 할 때) 값이 범위를 벗어난다는 것입니다. 이것은 백색 잡음이 아닌 심한 왜곡을 만드는 경향이 있습니다. 화이트 노이즈가 발생한다는 사실은 PCM 합계를 출력 형식에 맞게 바이트로 올바르게 변환하지 않았 음을 나타냅니다.

    다음은 AudioCue에서 PCM을 바이트로 다시 변환하는 데 사용하는 코드입니다. 형식은 16 비트, 44100fps, 스테레오, 리틀 엔디안 인 것으로 가정합니다. 정규화 된 수레로 PCM을 사용하고 있습니다. 이 알고리즘은 한 번에 버퍼에 해당하는 데이터를 변환합니다.

    for (int i = 0, n = buffer.length; i < n; i++)
        {
            buffer[i] *= 32767;
            audioBytes[i*2] = (byte) buffer[i];
            audioBytes[i*2 + 1] = (byte)((int)buffer[i] >> 8 );
        }
    
    

    때때로 Math.min (Math.max (audioval, -1), 1) 또는 Math.min (Math.max (audioval, -32767), 32767)과 같은 함수를 사용하여 값을 범위 내에 유지합니다. 보다 정교한 리미터 또는 컴프레서 알고리즘은 볼륨을 적합하게 확장합니다. 그러나 여전히 이것이 처리되지 않으면 결과는 백색 잡음이 아닌 왜곡이어야합니다.

    다른 단계에서 오류가 발생하면 더 많은 코드를 확인해야합니다.

    이 모든 것은 1000 포인트 에코 어레이 리버브로 운이 좋기를 바랍니다. 이 접근 방식이 작동하는 것을 듣지 못했습니다. 아마도 지금 계산 부하를 처리 할 수있는 프로세서가 있습니까? (실시간으로 이것을 시도하고 있습니까?) 실시간 잔향을 코딩하는 유일한 성공은 Schroeder 방법을 사용하여 CCMRA Freeberb의 구조와 값을 연결하고 Craig Lindley의 현재 고대 (저작권 코드) 2001) 책 "Digital Audio with Java". 이 책의 대부분은 구식 GUI 코드 (pre-Swing!)를 다루지 만 AllPass 및 Comb 필터에 제공하는 코드는 여전히 유효합니다.

    이 작업을 할 때 참조 및 코드를 작성하기 위해 더 나은 리버브를 찾아낸 것을 기억하지만, 음표를 찾으려고 시도하려면 실제 파기를해야합니다. 알고리즘은 세부 사항이나 의사 코드를 코딩하지 않는 블록 다이어그램을 통해 제시 되었기 때문에 당시 머리 위로 느낌이 들었습니다. 이 작업을 다시 수행하고 Shroeder 형식보다 더 나은 리버브를 원합니다. Schoeder는 너무 타악하지 않은 소리를 전달할 수있었습니다.

    실시간 광선 추적을위한 솔루션을 얻는 것이 귀중한 성과입니다. AR/VR 및 게임의 많은 응용 프로그램.

관련 자료

  • 이전 javascript - "for"루프에 정의 된 "const"변수가 아닌 일반 "const"변수의 유형을 지정해야하는 이유는 무엇입니까?
  • 다음 python - 함수 호출을 컨텍스트에 유지하려면 어떻게해야합니까?