인터넷에서 찾으면 .. 나온다.. 라고 하면 글쓴 이유가 없지..
일단 인터넷에서 찾아 볼 수 있는 흔한 예제...
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 useSampleRate = 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 useaudio_file.read(stream, 4); // Sub chunk2 size not useaudio_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 finishQEventLoop loop;QObject::connect(&output, SIGNAL(stateChanged(QAudio::State)), &loop, SLOT(quit()));do {loop.exec();} while(output.state() == QAudio::ActiveState);}
완벽한 코드는 아니지만, 적어도 웨이브 파일 하나 정도는 잘 나오는 코드인듯 싶다.