파이프라인을 중지하지 않고 출력 파일을 변경하는 방법

파이프라인을 중지하지 않고 출력 파일을 변경하는 방법

DSP를 수행하기 위해 오디오 파일을 얻기 위해 arecord를 사용하고 있습니다. 문제는 i2s 마이크에서 입력 캡처를 시작할 때마다 파일 시작 부분에 1초 동안 팝이 발생한다는 것입니다. 이 문제를 해결하기 위해 파이프를 사용하려고 합니다. 내가 원하는 것은 파이프라인을 중지하지 않고 파이프라인의 출력을 변경하여 이러한 팝을 방지하고 오디오의 공백을 방지하는 것입니다.

예를 들어, 나는 soundfile1과 soundfile2 사이를 전환하여 다른 파일이 녹음되는 동안 한 파일을 분석할 수 있도록 이와 같은 작업을 수행하고 싶습니다. 녹음을 시작할 때 팝이 나와도 상관없지만, 앞뒤로 전환할 때마다 팝이 나올 수는 없습니다.

arecord -D dmic_sv -c2 -r 48000 -f S32_LE -t wav -V mono -v > soundfile1.wav

arecord -D dmic_sv -c2 -r 48000 -f S32_LE -t wav -V mono -v > soundfile2.wav

불행히도 이것은 "장치 또는 리소스가 사용 중입니다"라는 메시지만 표시됩니다.

답변1

셸에서 실행하고 실행되도록 합니다.

arecord -D dmic_sv -c2 -r 48000 -f S32_LE -t wav -V mono -v \
| while :; do dd bs=384000 count=1 iflag=fullblock 2>/dev/null >>output; done

각각은 dd개별적으로 개봉됩니다 . 각각을 개별적으로 개봉하고 부착하는 것이 output중요합니다 . 이는 you 또는 anew가 next 로 작성 되면 새로운 것이 곧 생성된다는 의미입니다.outputddrm outputmv output soundfile1.wavddoutputoutput

단일 파일 시스템 내에서 발생하는 경우 mv output soundfile1.wav데이터가 손실되지 않습니다. 즉, soundfile1.wav새 스트림을 연결하면 output원래 스트림이 다시 생성됩니다. 이는 파일 이름을 바꾸거나 삭제해도 이미 파일이 열려 있는 프로세스를 방해하지 않기 때문입니다.

cp다른 파일 시스템으로 이동하는 것은 실제로 + 와 동일합니다 unlink. 이 경우 dd와 사이에 일부 추가가 발생할 수 있으며 블록이 손실됩니다. 따라서 다른 파일 시스템으로 직접 이동하지 마십시오. 이 작업을 수행해야 하는 경우 단일 파일 시스템 내에서 이름을 바꾸고 새 파일이 나타날 때까지 기다린 다음 이름이 바뀐 파일을 다른 파일 시스템으로 이동합니다.outputcpunlinkoutputoutput

또 다른 방법은 심볼릭 링크를 사용하는 것입니다. output이름에 대한 심볼릭 링크를 만듭니다 .

ln -s soundfile2.wav output

그런 다음 명령을 실행하십시오. 대상 파일이 존재하지 않을 수 있으며 생성됩니다. 존재하는 경우 데이터가 추가됩니다.

다른 파일로 전환하려는 경우 심볼릭 링크를 자동으로 업데이트합니다.

ln -sf soundfile3.wav output

새 파일이 다른 파일 시스템에 있을 수 있지만 이는 중요하지 않습니다. 또한 기호 링크를 사용하면 중지하지 않고도 데이터 저장을 중지할 수 있습니다 arecord. 지속적으로 실행 중인 명령을 다음으로 리디렉션하면 됩니다 /dev/null.

ln -sf /dev/null output

이는 심볼릭 링크를 다시 변경하고 일반 파일에 저장하기 시작하면 팝업이 실행되지 않을 가능성이 높기 때문에 유용할 수 있습니다.

메소드는 기호 링크 없이 또는 기호 링크와 함께 사용할 수 있습니다. 심볼릭링크 인 경우 output그냥 삭제하시면 다음은 일반파일로 dd생성됩니다 . 일반 파일 output이고 output데이터 손실 없이 심볼릭 링크로 바꾸려면 파일을 새 이름(예: )으로 하드링크 한 다음 자동으로 심볼릭 링크로 ln output soundfile4.wav바꿉니다 .output

노트:

  • iflag=fullblock휴대가 쉽지 않습니다. dd지원하지 않는다면 시도해 보세요 bs=8 count=48000. 그럼에도 불구하고 우리는 샘플 중간에 새 파일로의 변환이 발생하는 것을 원하지 않습니다. 샘플 중 하나는 8바이트(32비트 x 2채널)입니다. 나는 Linux의 파이프에 대해 충분히 익숙하지 않아서 arecord도구가 샘플을 여러 쓰기로 분할하지 않기를 바랄 뿐이므로 dd bs=8그렇지 않더라도 iflag=fullblock확실하지 않습니다. dd읽은 내용이 적은 경우 (비교이것) 그러면 중간 샘플 작성이 끝날 수 있습니다. 새 파일로 변경하면 새 파일이 불완전한 샘플로 시작되어 올바르게 재생되지 않습니다. 그러니 사용할 수 있으면 iflag=fullblock사용하세요. 기억하다dd올바르게 사용하기 어려운 이상한 도구입니다.; iflag=fullblock과민성을 줄이십시오.
  • 세분성을 변경 bs및/또는 늘리거나 줄일 수 있습니다. count예를 들어 초당 bs=38400 count=110개의 프로세스가 실행되므로 전체 설정이 거의 즉시 새 파일로 전환될 수 있습니다. dd반면, 초당 10개의 프로세스는 불필요한 부담이 될 수 있습니다. 당신에게 맞는 것은 무엇이든 가능합니다. 그냥 bs8의 배수로 유지하세요 .
  • CtrlC현재 +를 사용하여 명령을 종료할 때 dd쓰기 없이 종료 할 수 있습니다. bs=384000 count=1캡처된 데이터 중 최대 약 1초가 손실될 수 있습니다 . 중요한 것을 녹음할 때는 Ctrl+를 C1~2초 정도 연기하세요.

관련 정보