수요일, 11월 20, 2019

QT wave file play


인터넷에서 찾으면 .. 나온다.. 라고 하면 글쓴 이유가 없지..

 일단 인터넷에서 찾아 볼 수 있는 흔한 예제...

QFile audio_file(strFullFilePath);
if(audio_file.open(QIDevice::ReadOnly)){
  audio_file.seek(44); // skip wav header
  QByteArray audio_data = audio_file.readAll();
  audio_file.close();

  QBuffer* audio_buffer = new QBuffer(&audio_data);
  
  QAudioFormat  format;

  format.setSampleSize(16);
  format.setSampleRate(44100);
  format.setChannelCount(2);
  format.setCodec("audio/pcm");
  format.setByteOrder(QAudioFormat::LittleEndian);
  format.setSampleType(QAudioFormat::UnsignedInt);

  QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
  if(!info.isFormatSupperted(format)) {      
      return; // Not support format
  }
  
  QAudioOutput* output = new QAudioOutput(info, format);
  output->start(audio_buffer);
}

간결하다. 근데 막상 테스트 해보면.. 안노온다.. 왜일까?

 우선.. output->start(audio_buffer)를 실행하는동안 내 Process는 살아 있어야 한다. 그렇기 때문에 간단히 맨 아래에 5줄 추가

 QEventLoop loop;
 QObject::connect(&output, SIGNAL(stateChanged(QAudio::State)), &loop, SLOT(quit()));
 do {
     loop.exec();
 } while(output.state() == QAudio::ActiveState);


일단 소리는 나온다. 하지만 이쁘게 나오는 경우도 있고 그렇지 않은 경우(도날드덕 목서리 내지는 테이프 빨리 감는소리)도 발생한다.  이 경우에는  약간의 대공사(?)를 진행하여 아래와 같은 코드가 필요하게 된다.

 QFile audio_file(FileName);
 QByteArray audio_Buffer;
 int Channels = 0;      // count of channel
 int SampleRate = 0;    // wave sampling rate
 int BPS = 0;           // Sample Size
 if(audio_file.open(QIODevice::ReadOnly)){
     char stream[4] = {0,};
     audio_file.read(stream, 4); //  Same with "RIFF"   not use
     audio_file.read(stream, 4); //  Chumk size         not use
     audio_file.read(stream, 4); //  Format             not use
     audio_file.read(stream, 4); //  Sub chunk1 ID      not use
     audio_file.read(stream, 4); //  Sub chunk1 size    not use
     audio_file.read(stream, 2); //  Audio Format       not use
     memset(stream,0, 4);
     audio_file.read(stream, 2); //  Channel number    use
     Channels = qFromLittleEndian<quint16>((uchar*)stream);
     memset(stream,0, 4);
     audio_file.read(stream, 4); //  Sample rate       use
     SampleRate = qFromLittleEndian<quint32>((uchar*)stream);
     audio_file.read(stream, 4); //  Byte rate         not use
     audio_file.read(stream, 2); //  Byte Allign       not use(아마도 엔디언 설정인듯)
     memset(stream,0, 4);
     audio_file.read(stream, 2); //  BPS               use
     BPS = qFromLittleEndian<quint16>((uchar*)stream);
     audio_file.read(stream, 4); //  Sub chunk2 ID      not use
     audio_file.read(stream, 4); //  Sub chunk2 size    not use
     audio_Buffer.clear();
     while(!file.atEnd())
     {
         char s[1];
         audio_file.read(s,1);
         audio_Buffer.append(s[0]);
     }
     audio_file.close();
     QBuffer audio_buffer(&audio_Buffer);
     audio_buffer.open(QIODevice::ReadOnly);
     QAudioFormat format;
     format.setSampleSize(BPS);
     format.setSampleRate(SampleRate);
     format.setChannelCount(Channels);
     format.setCodec("audio/pcm");
     format.setByteOrder(QAudioFormat::LittleEndian);
     format.setSampleType(QAudioFormat::UnSignedInt);
     QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
     if (!info.isFormatSupported(format)) {
         qWarning()<<"raw audio format not supported by backend, cannot play audio.";
         return;
     }
     // Create the device and start playing...
     QAudioOutput output(info, format);
     output.start(&audio_buffer);
     // ...then wait for the sound to finish
     QEventLoop loop;
     QObject::connect(&output, SIGNAL(stateChanged(QAudio::State)), &loop, SLOT(quit()));
     do {
         loop.exec();
     } while(output.state() == QAudio::ActiveState);
  }

완벽한 코드는 아니지만, 적어도 웨이브 파일 하나 정도는 잘 나오는 코드인듯 싶다.

수요일, 9월 04, 2019

OpenCV 4.1.1 install on Ubuntu 18.0.4

많은 블러그를 통해 정보를 모아보고 구글햄아를 통해 수정자료를 찾아 적용하여 본 자료를 남긴다.
■ 우선 참고한 블러그 및 사이트
  ● 설치
    nvidia 드라이버 : https://pythonkim.tistory.com/48
    OPENCV with contrib : https://webnautes.tistory.com/1186  기본 정보를 이곳에서 참고
 
  ● 수정정보
    OpenCV archive URL정보
    OpenCV : https://github.com/opencv/opencv/releases
    contrib  : https://github.com/opencv/opencv_contrib/releases
  ※ 해당 버전 우클릭 후 "링크주소 복사"를 통해 사용 (최신버전 4.1.1 사용)

■ cmake 중 옵션 수정 (처리 속도 향상을 위한 조치)
  ● TBB(Threading Building Blocks) : 그다지 성능향상 기대하기 힘듬(대체 되어 돌아가는 것들이 많으므로) => 패스
       -D WITH_TBB=OFF
  ● IPP : Intel core사용시 성능최적화지원 하는 함수들의 묶음(상용 이므로) => 패스
       -D WITH_IPP=OFF
  ● CUDA : OpenCV에서 GPU를 사용하기위함 사용
       -D WITH_CUDA=ON
   ※ 문제점 : cuda lib가 gcc 6이상에서는 compile이 안됨 gcc 5버전을 설치 후  해당 부분만 gcc5 버전으로 컴파일
      -D CUDA_GENERATION="Pascal"
      -D CUDA_HOST_COMPILER:FILEPATH=/usr/bin/gcc-5
  ● OpenCV 버전에 따른 contrib 경로 수정
      -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-4.1.1/modules

※ time make -j(코어수) : Target workstation 성능이 하이엔드 급 (Xeon silver core16)인데도 110분 걸림