bool CWinGlkOGGSound::Play(int iRepeat, int iVolume, bool PauseState) { m_pReadPtr = m_pData; if (m_pReadPtr == NULL) return false; // Open the stream ov_callbacks VorbisCBs; VorbisCBs.read_func = VorbisRead; VorbisCBs.close_func = VorbisClose; VorbisCBs.seek_func = VorbisSeek; VorbisCBs.tell_func = VorbisTell; if (ov_open_callbacks(this,&m_Stream,NULL,0,VorbisCBs) < 0) return false; m_StreamOpen = true; vorbis_info* Info = ov_info(&m_Stream,-1); // Create a buffer if (CreateBuffer(Info->channels,Info->rate,16) == false) return false; // Set the duration of the sample if (iRepeat > 0) m_Duration = (DWORD)ceil(1000.0 * iRepeat * ov_time_total(&m_Stream,-1)); else m_Duration = -1; // Fill the buffer with sample data m_iRepeat = (iRepeat < 0) ? -1 : iRepeat - 1; if (FillBuffer(GetBufferSize()) == false) return false; // Set the volume for the buffer SetVolume(iVolume); // Start the buffer playing return PlayBuffer(PauseState); }
void kGUIAudio::Play(int rate,int channels,const unsigned char *sample,unsigned long samplesize,bool copy,bool loop) { AudioBuffer *ab; // kGUI::Trace("Play:Lock (%s)\n",m_mutex.GetIsLocked()==true?"locked":"unlocked"); m_mutex.Lock(); if(m_playing==false) { // kGUI::Trace("Play:%08x, Not Playing, reset packets!\n",this); m_playbuffer=0; m_numbuffers=0; } m_rate=rate; m_channels=channels; m_loop=loop; // kGUI::Trace("Play:%08x, Adding Packet, rate=%d,channels=%d,size=%d\n",this,rate,channels,samplesize); /* can we append this packet to the last pending packet? */ if(copy && m_numbuffers>m_playbuffer) { ab=m_buffers.GetEntry(m_numbuffers-1); ab->Append(samplesize,sample); } else { /* buffer sample data */ ab=m_manager->GetBuffer(); m_buffers.SetEntry(m_numbuffers,ab); ab->Set(samplesize,sample,copy); ++m_numbuffers; } PlayBuffer(); m_mutex.UnLock(); }
int audio_thread(void *param) { SND_EVENT evnt; int buffsize; int samples; int err; char *errstr; int active; if((err = CreateBuffer(snd_format|PCM_RING,0, &hBuff)) != 0) { errstr = "Cannot create sound buffer\n\r"; goto exit_whith_error; }; SetVolume(hBuff,-900,-900); if((err = GetBufferSize(hBuff, &buffsize)) != 0) { errstr = "Cannot get buffer size\n\r"; goto exit_whith_error; }; __sync_or_and_fetch(&threads_running,AUDIO_THREAD); resampler_size = buffsize = buffsize/2; samples = buffsize/4; while( player_state != CLOSED) { uint32_t offset; double event_stamp, wait_stamp; int too_late = 0; switch(sound_state) { case PREPARE: mutex_lock(&astream.lock); if(astream.count < buffsize*2) { memset(astream.buffer+astream.count, 0, buffsize*2-astream.count); astream.count = buffsize*2; }; SetBuffer(hBuff, astream.buffer, 0, buffsize*2); astream.count -= buffsize*2; if(astream.count) memcpy(astream.buffer, astream.buffer+buffsize*2, astream.count); mutex_unlock(&astream.lock); SetTimeBase(hBuff, audio_base); case PAUSE_2_PLAY: GetTimeStamp(hBuff, &last_time_stamp); // printf("last audio time stamp %f\n", last_time_stamp); if((err = PlayBuffer(hBuff, 0)) !=0 ) { errstr = "Cannot play buffer\n\r"; goto exit_whith_error; }; active = 1; sync_audio(hBuff, buffsize); sound_state = PLAY; // printf("render: set audio latency to %f\n", audio_delta); /* breaktrough */ case PLAY: GetNotify(&evnt); if(evnt.code != 0xFF000001) { printf("invalid event code %d\n\r", evnt.code); continue; } if(evnt.stream != hBuff) { printf("invalid stream %x hBuff= %x\n\r", evnt.stream, hBuff); continue; }; offset = evnt.offset; mutex_lock(&astream.lock); if(astream.count < buffsize) { memset(astream.buffer+astream.count, 0, buffsize-astream.count); astream.count = buffsize; }; SetBuffer(hBuff, astream.buffer, offset, buffsize); { double val = 0; int16_t *src = (int16_t*)astream.buffer; int samples = buffsize/2; int i; for(i = 0, val = 0; i < samples/2; i++, src++) if(val < abs(*src)) val= abs(*src); // * *src; sound_level_0 = val; //sqrt(val / (samples/2)); for(i = 0, val = 0; i < samples/2; i++, src++) if(val < abs(*src)) val= abs(*src); // * *src; sound_level_1 = val; //sqrt(val / (samples/2)); // printf("%d\n", sound_level); }; samples_written+= buffsize/4; astream.count -= buffsize; if(astream.count) memcpy(astream.buffer, astream.buffer+buffsize, astream.count); mutex_unlock(&astream.lock); break; case PLAY_2_STOP: if( active ) { ResetBuffer(hBuff, SND_RESET_ALL); audio_base = -1.0; active = 0; } sound_state = STOP; break; case PLAY_2_PAUSE: if( active ) { StopBuffer(hBuff); }; sound_state = PAUSE; case PAUSE: case STOP: delay(1); }; } __sync_and_and_fetch(&threads_running,~AUDIO_THREAD); StopBuffer(hBuff); DestroyBuffer(hBuff); return 0; exit_whith_error: printf(errstr); return -1; };
int WavPlayer::PlayAudio() { unsigned long len; void *pcmbuffer; int ret; pcmbuffer = LoadPCM(FileName, &len); if(!pcmbuffer) { fprintf(stderr, "%s: %s\n", FileName, strerror(errno)); exit(EXIT_FAILURE); } unsigned char* bytes = (unsigned char*)pcmbuffer; int index = 0; // 'RIFF' getWord(bytes, index); index += 4; // int Length getWord(bytes, index); index += 4; // 'WAVE' getWord(bytes, index); index += 4; // 'fmt ' getWord(bytes, index); index += 4; // int Format Length int fmtLen = getWord(bytes, index); index += 4; AudioFormat = getHalf(bytes, index); index += 2; NumChannels = getHalf(bytes, index); index += 2; SampleRate = getWord(bytes, index); index += 4; ByteRate = getWord(bytes, index); index += 4; BlockAlign = getHalf(bytes, index); index += 2; BitsPerSample = getHalf(bytes, index); index += 2; index += fmtLen - 16; while(!isDataChunk(bytes, index)) { // Any Chunk getWord(bytes, index); index += 4; // Any Chunk Length int anyChunkLen = getWord(bytes, index); index += 4 + anyChunkLen; } // 'data' getWord(bytes, index); index += 4; // int Data Length unsigned long dataLen = getWord(bytes, index); index += 4; unsigned char* target = &bytes[index]; ret = PlayBuffer((void *)target, dataLen); free(pcmbuffer); return ret; }