2013-06-18 2 views
1

은 그렇게 같이하는 SourceDataLine를 만들 수 있습니다SourceDataLine에 쓸 수있는 데이터의 형식은 무엇입니까? 자바에서

AudioFormat af = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100.0, 16, 1, 2, 44100.0, false);  
SourceDataLine sdl = AudioSystem.getSourceDataLine(af); 

된 후에는 데이터를 열고 쓸 수 있습니다 :

byte[] data = new byte[1024]; 
fillwithsounds(data); 

sdl.open() 
sdl.start() 
sdl.write(data, 0, 1024); 

이 모든 모노 데이터에 대한 잘 작동합니다.

스테레오 데이터를 쓸 수 있도록 바이트 배열을 변경해야하는 방법에 대한 온라인 설명서를 찾을 수 없습니다.

나는 내가 AudioFormat을 만들 때 채널의 양을 증가해야 할 것 같다

- 그것을 스테레오를 만들기 위해 - 그리고 나는 반 프레임 율 필요가 이해가 안

(그렇지 않으면 자바는 IllegalArgumentException를 슬로우) 왜 이것이, 또는 DataSourceLine에 피드하는 데이터의 새로운 형식이어야하는지.

오디오 형식에 대한 경험이 조금 더있는 사람이이 문제에 대해 밝힐 수 있습니다. 미리 감사드립니다!

+0

저는 모노 프레임, 모노 프레임, 모노 프레임으로 구성된 바이트 배열 대신에 이론을 세우고 있습니다. 바이트 배열은 이제 왼쪽 프레임, 오른쪽 프레임, 왼쪽 프레임, 오른쪽 프레임, 왼쪽 프레임, 오른쪽 프레임으로 구성됩니다. 나는 그것을 구현하려했지만, 나에게 현명한 것을주는 것이 아니라, 나를 정적으로 보냈다. –

+0

* "그 후에 데이터를 열어서 쓸 수 있습니다 : 이 모든 것이 모노 데이터에 적합합니다."* 거의 다 됐습니다. 원래 형식으로 16 바이트 프레임마다 작성한 내용을 두 번 씁니다. 효과적으로 '두 명의 스피커를 통한 모노'이지만, 다른 채널에 쓸 다른 무언가가 있다면 대신 작성하십시오. –

+0

* "구현하려했지만, .."* 더 빨리 도움을 받으려면 [SSCCE] (http://sscce.org/)를 게시하십시오. –

답변

2

를, 내가 재생 오디오를 스테레오 얻을 수 있습니다 (정적 소프트가 있지만, 나는 명확하게 원래의 트랙을들을 수)이 사용 :

 audioFmt = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
      44100, 16, 2, 4, 44100, false); 

비트 인코딩을 반으로 줄이지 않고 프레임 당 바이트를 두 배로 늘리고 싶을 것입니다. 어떤 8 비트 인코딩이 좋을지 모르겠지만 확실히 16 비트 인코딩보다 잡음이 많을 것입니다!

결과 파일의 길이가 두 배입니다. 그런 다음 "모노"재생 (두 스테레오 채널이 동일)을 위해 16 비트 샘플을 만들고 다음 두 위치로 복사 할 2 바이트 쌍을 가져올 수 있습니다.

을 감안할 때 :

frame = F 
little end byte = A 
big end byte = B 
AB = 16-bit little-endian encoding 
left channel = L 
right channel = R 

원래 모노 :

F1A, F1B, F2A, F2B, F3A, F3B ... 위의 형식을 사용하여

스테레오 :

F1AL , F1BL, F1AR, F1BR, F2AL, F2BL, F2AR, F2BR, F3AL, F3BL, F3AR, F3BR ...

왼쪽과 오른쪽의 순서가 잘 어울릴 수 있습니다. 그러나 당신이 아이디어를 얻기를 바랍니다!

+0

고맙습니다. 이론을 구현하기 위해이 함수를 작성했지만 매우 이상한 결과가 나타납니다. http://pastebin.com/L86ZmXrg 답변의 첫 번째 줄에서 언급 한 AudioFormat을 정확하게 사용하고 있습니다. "매우 이상한 결과"에 대한 나의 정의와 함께 새로운 코멘트를 쓸 것입니다. –

+0

"매우 이상한 결과"를 보려면 http://home.coolkev.com/BeforeProgram.mp3과 http://home.coolkev.com을 비교하십시오. /AfterProgram.mp3 –

+0

붙여 넣기 기능이 정상적으로 보입니다. Audacity에 두 파일을 가져 왔습니다. 그들은 모두 32 비트 인코딩 (16이 아님)을 사용하며 모노로 표시되어 있다고 말합니다. 따라서 원본 파일은 프레임 당 4 바이트를 사용하지 않습니다. 2. 출력 포맷을 2 채널로 설정 했습니까? 결과가 MONO 인 이유는 무엇입니까? Java에서 32 비트를 16 비트로 변환하는 방법을 모르겠습니다. 복잡한 변환 (모노에서 스테레오로 또는 그 반대로)에서는 Audacity를 사용합니다. 루프를 확장하여 i를 4 씩 증가시키고 각각 4 바이트를 전송할 수 있으며 그에 따라 출력 형식을 프레임 당 2 채널 및 8 바이트로 조정할 수 있으며 32 비트 인코딩을 유지할 수 있습니다. –

0

나는 지금 해결책을 찾아 냈고 앤드류 톰슨의 의견을 통해 내가 필요한 것을 정확히 설명했다.

각 프레임을 두 번 써야한다는 것을 알았습니다. Java가 내 모노 채널에 사용했던 프레임 크기를 사용하지 못하게한다는 사실을 파악했습니다. (IllegalArgumentException을 던졌습니다)

그래서 Java를 만족시키기 위해 프레임 속도를 절반으로 줄 였지만 바이트 배열을 수정하는 것을 기억하지 못했습니다.

"프레임 당 2 바이트, 1 채널"바이트 []를 취하여 "프레임 당 1 바이트, 2 채널"바이트 []로 변환하는 코드를 구현했습니다.

private static final float LEFT = -1; 
private static final float CENTER = 0; 
private static final float RIGHT = 1; 

private byte[] monoToStereo(byte[] data, float pan){ 
    byte[] output = new byte[data.length]; 
    for (int i = 0; i < (data.length - 2); i+=2){ 
     int currentvalue = (data[i+1]*256 + data[i])/(256*2); 
     if (pan == LEFT || pan == CENTER){ 
      output[i] = (byte) currentvalue; 
     } else { 
      output[i] = 0; 
     } 
     if (pan == RIGHT || pan == CENTER){ 
      output[i+1] = (byte) currentvalue; 
     } else { 
      output[i+1] = 0; 
     } 
    } 
    return output; 
} 

다음과 같이 내가 스테레오에 사용하는 형식은

관련 문제