diff options
Diffstat (limited to 'examples/mobile/quickhit/ga_src/GEAudioBuffer.cpp')
-rw-r--r-- | examples/mobile/quickhit/ga_src/GEAudioBuffer.cpp | 392 |
1 files changed, 0 insertions, 392 deletions
diff --git a/examples/mobile/quickhit/ga_src/GEAudioBuffer.cpp b/examples/mobile/quickhit/ga_src/GEAudioBuffer.cpp deleted file mode 100644 index 7df701d6..00000000 --- a/examples/mobile/quickhit/ga_src/GEAudioBuffer.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QDebug> -#include <math.h> -#include "GEAudioBuffer.h" - -using namespace GE; - - -struct SWavHeader { - char chunkID[4]; - unsigned int chunkSize; - char format[4]; - - unsigned char subchunk1id[4]; - unsigned int subchunk1size; - unsigned short audioFormat; - unsigned short nofChannels; - unsigned int sampleRate; - unsigned int byteRate; - - unsigned short blockAlign; - unsigned short bitsPerSample; - - unsigned char subchunk2id[4]; - unsigned int subchunk2size; - -}; - -CAudioBuffer::CAudioBuffer() { - m_data = 0; - m_dataLength = 0; - m_sampleFunction = 0; -}; - - -CAudioBuffer::~CAudioBuffer() { - reallocate(0); -} - -void CAudioBuffer::reallocate( int length ) { - if (m_data) delete [] ((char*)m_data); - m_dataLength = length; - if (m_dataLength>0) { - m_data = new char[ m_dataLength ]; - } else m_data = 0; -}; - - -CAudioBuffer* CAudioBuffer::loadWav( QString fileName ) { - QFile *wavFile = new QFile( fileName ); - - - if (wavFile->open(QIODevice::ReadOnly)) { - SWavHeader header; - - wavFile->read( header.chunkID, 4 ); - if (header.chunkID[0]!='R' || header.chunkID[1]!='I' || header.chunkID[2]!='F' || header.chunkID[3]!='F') return 0; // incorrect header - - wavFile->read( (char*)&header.chunkSize,4 ); - wavFile->read( (char*)&header.format,4 ); - - if (header.format[0]!='W' || header.format[1]!='A' || header.format[2]!='V' || header.format[3]!='E') return 0; // incorrect header - - wavFile->read( (char*)&header.subchunk1id,4 ); - if (header.subchunk1id[0]!='f' || header.subchunk1id[1]!='m' || header.subchunk1id[2]!='t' || header.subchunk1id[3]!=' ') return 0; // incorrect header - - wavFile->read( (char*)&header.subchunk1size,4 ); - wavFile->read( (char*)&header.audioFormat,2 ); - wavFile->read( (char*)&header.nofChannels,2 ); - wavFile->read( (char*)&header.sampleRate,4 ); - wavFile->read( (char*)&header.byteRate,4 ); - wavFile->read( (char*)&header.blockAlign,2 ); - wavFile->read( (char*)&header.bitsPerSample,2 ); - - qDebug() << fileName << " opened"; - - while (1) { - if (wavFile->read( (char*)&header.subchunk2id,4 ) != 4) return 0; - if (wavFile->read( (char*)&header.subchunk2size,4 ) != 4) return 0; - //int deb_size = header.subchunk2size; - //char tes[4]; - //memcpy(tes, header.subchunk2id, 4 ); - //if (header.subchunk2id[0]!='d' || header.subchunk2id[1]!='a' || header.subchunk2id[2]!='t' || header.subchunk2id[3]!='a') return 0; // incorrect header - if (header.subchunk2id[0]=='d' && header.subchunk2id[1]=='a' && header.subchunk2id[2]=='t' && header.subchunk2id[3]=='a') break; // found the data, chunk - // this was not the data-chunk. skip it - if (header.subchunk2size<1) return 0; // error in file - char *unused = new char[header.subchunk2size]; - wavFile->read( unused, header.subchunk2size ); - delete [] unused; - } - - - - // the data follows. - if (header.subchunk2size<1) return 0; - - CAudioBuffer *rval = new CAudioBuffer; - rval->m_nofChannels = header.nofChannels; - rval->m_bitsPerSample = header.bitsPerSample; - rval->m_samplesPerSec = header.sampleRate; - rval->m_signedData = 0; // where to know this? - rval->reallocate( header.subchunk2size ); - - wavFile->read( (char*)rval->m_data, header.subchunk2size ); - - // choose a good sampling function. - rval->m_sampleFunction = 0; - if (rval->m_nofChannels==1) { - if (rval->m_bitsPerSample == 8) rval->m_sampleFunction = sampleFunction8bitMono; - if (rval->m_bitsPerSample == 16) rval->m_sampleFunction = sampleFunction16bitMono; - } else { - if (rval->m_bitsPerSample == 8) rval->m_sampleFunction = sampleFunction8bitStereo; - if (rval->m_bitsPerSample == 16) rval->m_sampleFunction = sampleFunction16bitStereo; - } - - return rval; - - - } else { - qDebug() << fileName << " NOT opened"; - return 0; - } - - delete wavFile; -}; - - -CAudioBuffer* CAudioBuffer::loadWav( FILE *wavFile ) { - // read the header. - SWavHeader header; - fread( header.chunkID, 4, 1, wavFile ); - if (header.chunkID[0]!='R' || header.chunkID[1]!='I' || header.chunkID[2]!='F' || header.chunkID[3]!='F') return 0; // incorrect header - - fread( &header.chunkSize, 4, 1, wavFile ); - fread( header.format, 4, 1, wavFile ); - if (header.format[0]!='W' || header.format[1]!='A' || header.format[2]!='V' || header.format[3]!='E') return 0; // incorrect header - - fread( header.subchunk1id, 4, 1, wavFile ); - if (header.subchunk1id[0]!='f' || header.subchunk1id[1]!='m' || header.subchunk1id[2]!='t' || header.subchunk1id[3]!=' ') return 0; // incorrect header - - fread( &header.subchunk1size, 4, 1, wavFile ); - fread( &header.audioFormat, 2, 1, wavFile ); - fread( &header.nofChannels, 2, 1, wavFile ); - fread( &header.sampleRate, 4, 1, wavFile ); - fread( &header.byteRate, 4, 1, wavFile ); - - fread( &header.blockAlign, 2, 1, wavFile ); - fread( &header.bitsPerSample, 2, 1, wavFile ); - - fread( header.subchunk2id, 4, 1, wavFile ); - if (header.subchunk2id[0]!='d' || header.subchunk2id[1]!='a' || header.subchunk2id[2]!='t' || header.subchunk2id[3]!='a') return 0; // incorrect header - fread( &header.subchunk2size, 4, 1, wavFile ); - - - // the data follows. - if (header.subchunk2size<1) return 0; - - CAudioBuffer *rval = new CAudioBuffer; - rval->m_nofChannels = header.nofChannels; - rval->m_bitsPerSample = header.bitsPerSample; - rval->m_samplesPerSec = header.sampleRate; - rval->m_signedData = 0; // where to know this? - rval->reallocate( header.subchunk2size ); - - fread( rval->m_data, 1, header.subchunk2size, wavFile ); - - - - // choose a good sampling function. - rval->m_sampleFunction = 0; - if (rval->m_nofChannels==1) { - if (rval->m_bitsPerSample == 8) rval->m_sampleFunction = sampleFunction8bitMono; - if (rval->m_bitsPerSample == 16) rval->m_sampleFunction = sampleFunction16bitMono; - } else { - if (rval->m_bitsPerSample == 8) rval->m_sampleFunction = sampleFunction8bitStereo; - if (rval->m_bitsPerSample == 16) rval->m_sampleFunction = sampleFunction16bitStereo; - } - - return rval; -}; - - - -AUDIO_SAMPLE_TYPE CAudioBuffer::sampleFunction8bitMono( CAudioBuffer *abuffer, int pos, int channel ) { - return (AUDIO_SAMPLE_TYPE)(((unsigned char*)(abuffer->m_data))[pos]-128)<<8; -}; - -AUDIO_SAMPLE_TYPE CAudioBuffer::sampleFunction16bitMono( CAudioBuffer *abuffer, int pos, int channel ) { - return (AUDIO_SAMPLE_TYPE)(((short*)(abuffer->m_data))[pos]); -}; - -AUDIO_SAMPLE_TYPE CAudioBuffer::sampleFunction8bitStereo( CAudioBuffer *abuffer, int pos, int channel ) { - return ((AUDIO_SAMPLE_TYPE)(((char*)(abuffer->m_data))[pos*abuffer->m_nofChannels + channel])<<8); -}; - - -AUDIO_SAMPLE_TYPE CAudioBuffer::sampleFunction16bitStereo( CAudioBuffer *abuffer, int pos, int channel ) { - return (AUDIO_SAMPLE_TYPE)(((short*)(abuffer->m_data))[pos*abuffer->m_nofChannels + channel]); -}; - -CAudioBufferPlayInstance *CAudioBuffer::playWithMixer( CAudioMixer &mixer ) { - CAudioBufferPlayInstance *i = (CAudioBufferPlayInstance*)mixer.addAudioSource( new CAudioBufferPlayInstance( this )); - return i; -}; - - -CAudioBufferPlayInstance::CAudioBufferPlayInstance() { - m_fixedPos = 0; - m_fixedInc = 0; - m_buffer = 0; - m_fixedLeftVolume = 4096; - m_fixedRightVolume = 4096; - m_destroyWhenFinished = true; - m_finished = false; -}; - -CAudioBufferPlayInstance::CAudioBufferPlayInstance( CAudioBuffer *startPlaying ) { - m_fixedPos = 0; - m_fixedInc = 0; - m_fixedLeftVolume = 4096; - m_fixedRightVolume = 4096; - m_destroyWhenFinished = true; - m_finished = false; - playBuffer( startPlaying, 1.0f, 1.0f ); -}; - -void CAudioBufferPlayInstance::playBuffer( CAudioBuffer *startPlaying, float volume, float speed, int loopTimes ) { - m_buffer = startPlaying; - m_fixedLeftVolume = (int)(4096.0f*volume); - m_fixedRightVolume = m_fixedLeftVolume; - m_fixedPos = 0; - //m_fixedInc = ( startPlaying->getSamplesPerSec() * (int)(4096.0f*speed)) / AUDIO_FREQUENCY; - setSpeed( speed ); - m_loopTimes = loopTimes; - -}; - -CAudioBufferPlayInstance::~CAudioBufferPlayInstance() { - -}; - - -void CAudioBufferPlayInstance::stop() { - m_buffer = 0; - m_finished = true; -}; - -void CAudioBufferPlayInstance::setSpeed( float speed ) { - if (!m_buffer) return; - m_fixedInc = (int)( ((float)m_buffer->getSamplesPerSec() * 4096.0f*speed) / (float)AUDIO_FREQUENCY ); -}; - -void CAudioBufferPlayInstance::setLeftVolume( float vol ) { - m_fixedLeftVolume = (int)(4096.0f*vol); -}; - -void CAudioBufferPlayInstance::setRightVolume( float vol ) { - m_fixedRightVolume = (int)(4096.0f*vol); -}; - -bool CAudioBufferPlayInstance::canBeDestroyed() { - if (m_finished==true && - m_destroyWhenFinished==true) return true; else return false; -}; - - - -// Does not do any bound-checking. Must be checked before called. -int CAudioBufferPlayInstance::mixBlock( AUDIO_SAMPLE_TYPE *target, int samplesToMix ) { - SAMPLE_FUNCTION_TYPE sampleFunction = m_buffer->getSampleFunction(); - if (!sampleFunction) return 0; // unsupported sampletype - AUDIO_SAMPLE_TYPE *t_target = target+samplesToMix*2; - int sourcepos; - //int tempCounter = 0; - - if (m_buffer->getNofChannels() == 2) { // stereo - while (target!=t_target) { - sourcepos = m_fixedPos>>12; - target[0] = (((((sampleFunction)( m_buffer, sourcepos, 0) * (4096-(m_fixedPos&4095)) + (sampleFunction)( m_buffer, sourcepos+1, 0) * (m_fixedPos&4095) ) >> 12) * m_fixedLeftVolume) >> 12); - target[1] = (((((sampleFunction)( m_buffer, sourcepos, 1) * (4096-(m_fixedPos&4095)) + (sampleFunction)( m_buffer, sourcepos+1, 1) * (m_fixedPos&4095) ) >> 12) * m_fixedRightVolume) >> 12); - m_fixedPos+=m_fixedInc; - target+=2; - //tempCounter++; - }; - } else { // mono - int temp; - while (target!=t_target) { - sourcepos = m_fixedPos>>12; - temp = (((sampleFunction)( m_buffer, sourcepos, 0 ) * (4096-(m_fixedPos&4095)) + (sampleFunction)( m_buffer, sourcepos+1, 0 ) * (m_fixedPos&4095) ) >> 12); - target[0] = ((temp*m_fixedLeftVolume)>>12); - target[1] = ((temp*m_fixedRightVolume)>>12); - m_fixedPos+=m_fixedInc; - target+=2; - //tempCounter++; - }; - - }; - - return samplesToMix; -}; - - - -int CAudioBufferPlayInstance::pullAudio( AUDIO_SAMPLE_TYPE *target, int bufferLength ) { - if (!m_buffer) return 0; // no sample associated to mix.. - - int channelLength = ((m_buffer->getDataLength()) / (m_buffer->getNofChannels()*m_buffer->getBytesPerSample()))-2; - - int samplesToWrite = bufferLength/2; - int amount; - int totalMixed = 0; - - - while (samplesToWrite>0) { - int samplesLeft = channelLength - (m_fixedPos>>12); - int maxMixAmount = (int)(((long long int)(samplesLeft)<<12) / m_fixedInc ); // This is how much we can mix at least - //int maxMixAmount = (int)((float)samplesLeft / ((float)m_fixedInc/4096.0f)); - //if (maxMixAmount<1) maxMixAmount = 1; // NOTE, THIS MIGHT CAUSE PROBLEMS. NEEDS CHECKING - if (maxMixAmount>samplesToWrite) { - maxMixAmount=samplesToWrite; - } - - if (maxMixAmount > 0) { - amount=mixBlock(target+totalMixed * 2, maxMixAmount); - - if (amount == 0) - { - // Error! - break; - } - - totalMixed+=amount; - } else { - amount = 0; - m_fixedPos = channelLength<<12; - } - - // sample is ended,.. check the looping variables and see what to do. - if ((m_fixedPos>>12)>=channelLength) { - m_fixedPos -= (channelLength<<12); - if (m_loopTimes>0) m_loopTimes--; - if (m_loopTimes==0) { - stop(); - return totalMixed; - } - } - - samplesToWrite-=amount; - if (samplesToWrite<1) break; - }; - return totalMixed*2; -}; |