void cEntity::SetPitchFromSpeed(void) { const double EPS = 0.0000001; double xz = sqrt(m_Speed.x * m_Speed.x + m_Speed.z * m_Speed.z); // Speed XZ-plane component if ((abs(xz) < EPS) && (abs(m_Speed.y) < EPS)) { // atan2() may overflow or is undefined, pick any number SetPitch(0); return; } SetPitch(atan2(m_Speed.y, xz) * 180 / PI); }
void cMonster::SetPitchAndYawFromDestination(bool a_IsFollowingPath) { Vector3d BodyDistance; if (!a_IsFollowingPath && (GetTarget() != nullptr)) { BodyDistance = GetTarget()->GetPosition() - GetPosition(); } else { BodyDistance = m_NextWayPointPosition - GetPosition(); } double BodyRotation, BodyPitch; BodyDistance.Normalize(); VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, BodyRotation, BodyPitch); SetYaw(BodyRotation); Vector3d HeadDistance; if (GetTarget() != nullptr) { if (GetTarget()->IsPlayer()) // Look at a player { HeadDistance = GetTarget()->GetPosition() - GetPosition(); } else // Look at some other entity { HeadDistance = GetTarget()->GetPosition() - GetPosition(); // HeadDistance.y = GetTarget()->GetPosY() + GetHeight(); } } else // Look straight { HeadDistance = BodyDistance; HeadDistance.y = 0; } double HeadRotation, HeadPitch; HeadDistance.Normalize(); VectorToEuler(HeadDistance.x, HeadDistance.y, HeadDistance.z, HeadRotation, HeadPitch); if ((std::abs(BodyRotation - HeadRotation) < 70) && (std::abs(HeadPitch) < 60)) { SetHeadYaw(HeadRotation); SetPitch(-HeadPitch); } else { SetHeadYaw(BodyRotation); SetPitch(0); } }
void cMonster::SetPitchAndYawFromDestination() { Vector3d FinalDestination = m_FinalDestination; if (m_Target != NULL) { if (m_Target->IsPlayer()) { FinalDestination.y = ((cPlayer *)m_Target)->GetStance(); } else { FinalDestination.y = GetHeight(); } } Vector3d Distance = FinalDestination - GetPosition(); if (Distance.SqrLength() > 0.1f) { { double Rotation, Pitch; Distance.Normalize(); VectorToEuler(Distance.x, Distance.y, Distance.z, Rotation, Pitch); SetHeadYaw(Rotation); SetPitch(-Pitch); } { Vector3d BodyDistance = m_Destination - GetPosition(); double Rotation, Pitch; Distance.Normalize(); VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, Rotation, Pitch); SetYaw(Rotation); } } }
Sound& Sound::operator =(const Sound& right) { // Here we don't use the copy-and-swap idiom, because it would mess up // the list of sound instances contained in the buffers // Detach the sound instance from the previous buffer (if any) if (myBuffer) { Stop(); myBuffer->DetachSound(this); myBuffer = NULL; } // Copy the sound attributes if (right.myBuffer) SetBuffer(*right.myBuffer); SetLoop(right.GetLoop()); SetPitch(right.GetPitch()); SetVolume(right.GetVolume()); SetPosition(right.GetPosition()); SetRelativeToListener(right.IsRelativeToListener()); SetMinDistance(right.GetMinDistance()); SetAttenuation(right.GetAttenuation()); return *this; }
Character::Character(std::string fromString) { std::vector<std::string> tokens = utils::Tokenfy(fromString, '|'); if (tokens[0] == "PLAYER_OBJECT") { SetName(tokens[57]); SetLastname(tokens[58]); SetRace(tokens[59]); SetGender(tokens[60]); SetFace(tokens[61]); SetSkin(tokens[62]); SetZone(tokens[63]); SetLevel(std::stoi(tokens[64])); SetHp(std::stoi(tokens[65])); SetMaxHp(std::stoi(tokens[66])); SetBp(std::stoi(tokens[67])); SetMaxBp(std::stoi(tokens[68])); SetMp(std::stoi(tokens[69])); SetMaxMp(std::stoi(tokens[70])); SetEp(std::stoi(tokens[71])); SetMaxEp(std::stoi(tokens[72])); SetStrength(std::stoi(tokens[73])); SetConstitution(std::stoi(tokens[74])); SetIntelligence(std::stoi(tokens[75])); SetDexterity(std::stoi(tokens[76])); SetX(std::stof(tokens[77])); SetY(std::stof(tokens[78])); SetZ(std::stof(tokens[79])); SetPitch(std::stof(tokens[80])); SetYaw(std::stof(tokens[81])); } // if (tokens[0] == "NPC_OBJECT") { // // } }
void cMonster::SetPitchAndYawFromDestination() { Vector3d FinalDestination = m_FinalDestination; if (m_Target != nullptr) { if (m_Target->IsPlayer()) { FinalDestination.y = static_cast<cPlayer *>(m_Target)->GetStance() - 1; } else { FinalDestination.y = m_Target->GetPosY() + GetHeight(); } } Vector3d BodyDistance; if (!m_IsFollowingPath && (m_Target != nullptr)) { BodyDistance = m_Target->GetPosition() - GetPosition(); } else { BodyDistance = m_NextWayPointPosition - GetPosition(); } double BodyRotation, BodyPitch; BodyDistance.Normalize(); VectorToEuler(BodyDistance.x, BodyDistance.y, BodyDistance.z, BodyRotation, BodyPitch); SetYaw(BodyRotation); Vector3d Distance = FinalDestination - GetPosition(); { double HeadRotation, HeadPitch; Distance.Normalize(); VectorToEuler(Distance.x, Distance.y, Distance.z, HeadRotation, HeadPitch); if (std::abs(BodyRotation - HeadRotation) < 90) { SetHeadYaw(HeadRotation); SetPitch(-HeadPitch); } else // We're not an owl. If it's more than 120, don't look behind and instead look at where you're walking. { SetHeadYaw(BodyRotation); SetPitch(-BodyPitch); } } }
void AudioSourceOJM::parseM30() { M30Header Head; size_t sizeLeft; ifile->read(reinterpret_cast<char*>(&Head), sizeof(M30Header)); std::vector<char> Buffer(Head.payload_size); sizeLeft = Head.payload_size; for (int i = 0; i < Head.sample_count; i++) { if (sizeLeft < 52) break; // wrong number of samples M30Entry Entry; ifile->read(reinterpret_cast<char*>(&Entry), sizeof(M30Entry)); sizeLeft -= sizeof(M30Entry); sizeLeft -= Entry.sample_size; int OJMIndex = Entry.ref; if (Entry.codec_code == 0) OJMIndex += 1000; else if (Entry.codec_code != 5) continue; // Unknown sample id type. std::vector<char> SampleData(Entry.sample_size); ifile->read(&SampleData[0], Entry.sample_size); if (Head.encryption_flag & 16) NamiXOR(&SampleData[0], Entry.sample_size); else if (Head.encryption_flag & 32) F412XOR(&SampleData[0], Entry.sample_size); // Sample data is done. Now the bits that are specific to raindrop.. auto NewSample = std::make_shared<SoundSample>(); SFM30 ToLoad; ToLoad.Buffer = std::move(SampleData); ToLoad.DataLength = Entry.sample_size; OggVorbis_File vf; ov_open_callbacks(&ToLoad, &vf, nullptr, 0, M30InterfaceOgg); TemporaryState.File = &vf; TemporaryState.Info = vf.vi; if (vf.vi) { TemporaryState.Enabled = OJM_OGG; NewSample->SetPitch(Speed); NewSample->Open(this); TemporaryState.Enabled = 0; } ov_clear(&vf); Arr[OJMIndex] = NewSample; } }
void Source::SetPitch(float value) { #ifdef HAS_AUDIO_SOURCE impl->SetPitch(value); #else (void)value; throw System::PunkException(L"Audio source is not available"); #endif }
//----------------------------------------------------------------------------- // Purpose: Pitches the camera forward axis toward the camera's down axis a // given number of degrees. //----------------------------------------------------------------------------- void CCamera::Pitch(float fDegrees) { if (fDegrees != 0) { float fPitch = GetPitch(); fPitch += fDegrees; SetPitch(fPitch); } }
Sound::Sound(const SoundBuffer& buffer, bool loop, float pitch, float volume, const Vector3f& position) : myBuffer(NULL) { SetBuffer(buffer); SetLoop(loop); SetPitch(pitch); SetVolume(volume); SetPosition(position); }
// // Simulation // Bool TrackCam::Simulate(FamilyNode *viewNode, F32 time) { Bool bindMod1 = Common::Input::GetModifierKey(1); Bool bindMod2 = Common::Input::GetModifierKey(2); if (trackObj.Alive()) { // Check that we are allowed to track this object if (!CanTrack(trackObj)) { trackObj = FindObject(trackObj, FO_NEXT); } } else { // If object is dead, go to next object trackObj = FindObject(trackObj, FO_NEXT); } if (trackObj.Alive()) { switchDelay = DEFAULT_SWITCH_DELAY; if (rScroll) { if (bindMod1 && bindMod2) { SetRadius(targetRadius + (F32(dy) * time * swoopRate * 2.0F)); } else if (!bindMod1 && !bindMod2) { if (dx) { // Circle about the object qView.Rotate(time * F32(-dx) * DEG2RAD * spinRate, Matrix::I.up); } if (dy) { SetPitch(pitch + (time * F32(-dy) * DEG2RAD * spinRate)); } } else if (Input::GetKeyState() & Input::LBUTTONDOWN) { // Circle about the object SetRadius(targetRadius + (F32(dy) * time * swoopRate * 2.0F)); // Set mouse to centre of screen Input::SetMousePos(Vid::backBmp.Width() >> 1, Vid::backBmp.Height() >> 1); } // Set mouse to centre of screen Input::SetMousePos(Vid::backBmp.Width() >> 1, Vid::backBmp.Height() >> 1); }
NzSoundEmitter::NzSoundEmitter(const NzSoundEmitter& emitter) { alGenSources(1, &m_source); SetAttenuation(emitter.GetAttenuation()); SetMinDistance(emitter.GetMinDistance()); SetPitch(emitter.GetPitch()); // Pas de copie de position ou de vitesse SetVolume(emitter.GetVolume()); }
SoundEmitter::SoundEmitter(const SoundEmitter& emitter) { alGenSources(1, &m_source); SetAttenuation(emitter.GetAttenuation()); SetMinDistance(emitter.GetMinDistance()); SetPitch(emitter.GetPitch()); // No copy for position or velocity SetVolume(emitter.GetVolume()); }
void hdW32SoundVoiceDevice::AquireVoice() { if ( !voice_ ) { alGenSources( 1, &voice_ ); HEART_CHECK_OPENAL_ERRORS(); SetVolume(volume_); SetPitch(pitch_); } }
////////////////////OPERATIONS//////////////////// int Pitch::Set(char* mess, float value){ switch (FindMsg(mess)){ case 31: SetPitch(value); return 1; case 32: SetPitch((int) value); return 1; default: return DelayLine::Set(mess,value); } }
AudioSource::AudioSource(AudioBuffer* buff) { alGenSources(1, &source); SetGain(1); SetPitch(1); SetLooping(false); SetPosition(0,0,0); SetVelocity(0,0,0); alSourcei(source, AL_BUFFER, buff->GetBuffer()); }
// WRITE REGISTERS: called by main emu void SPU_writeRegister(unsigned long reg, unsigned short val) { const unsigned long r=reg&0xfff; regArea[(r-0xc00)>>1] = val; if(r>=0x0c00 && r<0x0d80) // some channel info? { int ch=(r>>4)-0xc0; // calc channel switch(r&0x0f) { case 0: SetVolumeL((unsigned char)ch,val); // l volume break; case 2: SetVolumeR((unsigned char)ch,val); // r volume break; case 4: SetPitch(ch,val); // pitch break; case 6: s_chan[ch].pStart=spuMemC+((unsigned long) val<<3); // start break; case 8: // level with pre-calcs { const unsigned long lval=val;unsigned long lx; s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0; s_chan[ch].ADSRX.AttackRate = ((lval>>8) & 0x007f)^0x7f; s_chan[ch].ADSRX.DecayRate = 4*(((lval>>4) & 0x000f)^0x1f); s_chan[ch].ADSRX.SustainLevel = (lval & 0x000f) << 27; break; } case 10: // adsr times with pre-calcs { const unsigned long lval=val;unsigned long lx; s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0; s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1; s_chan[ch].ADSRX.SustainRate = ((lval>>6) & 0x007f)^0x7f; s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0; s_chan[ch].ADSRX.ReleaseRate = 4*((lval & 0x001f)^0x1f); break; } case 12: // adsr volume... mmm have to investigate this break; case 14: // loop? s_chan[ch].pLoop=spuMemC+((unsigned long) val<<3); s_chan[ch].bIgnoreLoop=1; break; } return; }
int AdSyn::Set(char* mess, float value){ switch(FindMsg(mess)){ case 31: SetPitch(value); return 1; default: return SinSyn::Set(mess, value); } }
void BassSoundEngine::Update(float dwTimeMilliSecond) { if(ScreenState==SCREEN_GAMEMAIN) { if(BASS_ChannelIsActive(channel[0])!=BASS_ACTIVE_PLAYING || !channel[0]){ if(m_pAudio) // audio stopped, resume audio in video m_pAudio->put_Volume(Lin2dB(defaultVolume)); }else{ // channel 0 is active if(m_pAudio) m_pAudio->put_Volume(-10000); if(pitch_factor!=0) SetPitch(pitch_factor,0,true), pitch_factor = 0; if(sampleRate_factor!=0) SetSampleRate(sampleRate_factor,0,true), sampleRate_factor = 0; if(tempo_factor!=0) SetTempo(tempo_factor,0,true), tempo_factor = 0; } } for(int i = 0; i < nowChannel; i++) { if(channel[i]!=NULL) { float volume; BASS_ChannelGetAttribute(channel[i], BASS_ATTRIB_VOL, &volume); if(volume==0){ BASS_ChannelStop(channel[i]); channel[i] = NULL; } if(volume>volumeDes[i]) { volume -= soundSpd*dwTimeMilliSecond; if(volume<volumeDes[i]) volume = volumeDes[i]; } if(volume<volumeDes[i]) { volume += soundSpd*dwTimeMilliSecond; if(volume>volumeDes[i]) volume = volumeDes[i]; } BASS_ChannelSetAttribute(channel[i], BASS_ATTRIB_VOL, volume); if(volume==0) FreeChannel(i, true); } } }
int PVTransp::Connect(char* mess, void* input){ switch(FindMsg(mess)){ case 31: SetPitch(m_pitch, (SndObj*) input); return 1; default: return SpecMult::Connect(mess, input); } }
CCamera_Scene::CCamera_Scene(Ogre::Camera* pOgreCamera, const fVector3& fvPos, FLOAT fAddHeight, FLOAT fPitch, FLOAT fDistance, FLOAT fDirection) : CCamera(pOgreCamera) { //----------------------------------------------- // 进行初始化设置 SetLookAt(fvPos); SetAddHeight(fAddHeight); SetPitch(fPitch); SetApprochPitch( fPitch ); SetDistance(fDistance); SetDirection(fDirection); m_status = NORMAL_STATUS; m_fOffset = 0.0f; Fairy::EffectManager::getSingleton().setEffectCameraShakeCallback(&s_EffectCameraShakeCallback); }
void FmodSoundEngine::Update(float dwTimeMilliSecond) { FMOD::Channel **channel = (FMOD::Channel**)this->channel; if(ScreenState==SCREEN_GAMEMAIN){ bool status = false; channel[0]->isPlaying(&status); if(!status || !channel[0]){ // audio stopped, resume audio in video if(m_pAudio) m_pAudio->put_Volume(Lin2dB(defaultVolume)); }else{ // channel 0 is active if(m_pAudio) m_pAudio->put_Volume(-10000); if(pitch_factor!=0) SetPitch(pitch_factor,0,true), pitch_factor = 0; if(sampleRate_factor!=0) SetSampleRate(sampleRate_factor,0,true), sampleRate_factor = 0; if(tempo_factor!=0) SetTempo(tempo_factor,0,true), tempo_factor = 0; } } system->update(); for(int i = 0; i < nowChannel; i++) { if(channel[i]!=NULL) { float volume; result = channel[i]->getVolume(&volume); if(volume>volumeDes[i]) { volume -= soundSpd*dwTimeMilliSecond; if(volume<volumeDes[i]) volume = volumeDes[i]; } else if(volume<volumeDes[i]) { volume += soundSpd*dwTimeMilliSecond; if(volume>volumeDes[i]) volume = volumeDes[i]; } channel[i]->setVolume(volume); if(volume==0) FreeChannel(i, true); } } }
void OpenALSound::Reactivate() { if ( MGDF_OK == _soundManager->AcquireSource( &_sourceId ) ) { alSourcei( _sourceId, AL_BUFFER, _bufferId ); if ( alGetError() != AL_NO_ERROR ) { LOG( "Unable to allocate buffer to audio source", LOG_ERROR ); Deactivate(); } else { SetSourceRelative( _isSourceRelative ); SetVolume( _volume ); SetPitch( _pitch ); SetLooping( _isLooping ); if ( _isLooping && _wasPlaying ) { //resume any looping sample that was playing before it was deactivated Play(); } } } }
bool Source::Play(bool bRestart) { // Is a buffer loaded? Buffer *pBuffer = static_cast<Buffer*>(GetBuffer()); if (!pBuffer) return false; // Error! // Paused? if (IsPaused() && !bRestart) { FSOUND_SetPaused(m_nChannel, 0); } else { // Play if (IsPlaying()) { if (!bRestart) return true; // Done Stop(); } m_nChannel = pBuffer->Play(); // Add source to sound manager static_cast<SoundManager&>(GetSoundManager()).AddActiveSource(*this); // Get frequency and setup pitch m_nFrequency = FSOUND_GetFrequency(m_nChannel); float fPitch = m_fPitch; m_fPitch = -1.0f; SetPitch(fPitch); // Set volume pBuffer->SetVolume(m_nChannel, m_fVolume); // [HACK] HW sound: We have to pause the playback if we want to change the looping mode... // FSOUND_SetPaused(m_nChannel, 1); pBuffer->SetLooping(m_nChannel, m_bLooping); // FSOUND_SetPaused(m_nChannel, 0); // Set attributes SetAttribute(Position, m_vAttributes[Position]); SetAttribute(Velocity, m_vAttributes[Velocity]); } // Done return true; }
Character::Character(std::string name, std::string lastname, std::string race, std::string gender, std::string face, std::string skin, std::string zone, int level, int hp, int maxHp, int bp, int maxBp, int mp, int maxMp, int ep, int maxEp, int strength, int constitution, int intelligence, int dexterity, float x, float y, float z, float pitch, float yaw) { SetName(name); SetLastname(lastname); SetRace(race); SetGender(gender); SetFace(face); SetSkin(skin); SetZone(zone); SetHead("head"); SetChest("chest"); SetArms("arms"); SetHands("hands"); SetLegs("legs"); SetFeet("feet"); SetCloak("cloak"); SetNecklace("necklace"); SetRingOne("ringOne"); SetRingTwo("ringTwo"); SetRightHand("rightHand"); SetLeftHand("leftHand"); SetLevel(level); SetHp(hp); SetMaxHp(maxHp); SetBp(bp); SetMaxBp(maxBp); SetMp(mp); SetMaxMp(maxMp); SetEp(ep); SetMaxEp(maxEp); SetStrength(strength); SetConstitution(constitution); SetIntelligence(intelligence); SetDexterity(dexterity); SetX(x); SetY(y); SetZ(z); SetPitch(pitch); SetYaw(yaw); }
int PVTransp::Set(char* mess, float value){ switch(FindMsg(mess)){ case 31: SetPitch(value, m_input2); return 1; case 32: SetMode((int)value); return 1; default: return SpecMult::Set(mess, value); } }
//----------------------------------------------------------------------------- // Purpose: Sets the camera target, rebuilding the view matrix. // Input : ViewTarget - the point in world space that the camera should look at. //----------------------------------------------------------------------------- void CCamera::SetViewTarget(const Vector &ViewTarget) { Vector ViewOrigin; Vector ViewForward; GetViewPoint( ViewOrigin ); VectorSubtract(ViewTarget, ViewOrigin, ViewForward); VectorNormalize(ViewForward); // // Ideally we could replace the math below with standard VectorAngles stuff, but Hammer // camera matrices use a different convention from QAngle (sadly). // float fYaw = RAD2DEG(atan2(ViewForward[0], ViewForward[1])); SetYaw(fYaw); float fPitch = -RAD2DEG(asin(ViewForward[2])); SetPitch(fPitch); }
CRenderableAnimatedInstanceModel::CRenderableAnimatedInstanceModel(const std::string &Name, const std::string &CoreName) { m_AnimatedInstanceModel = NULL; m_bIsOk = true; CAnimatedCoreModel * l_AnimatedCoreModel = CORE->GetAnimatedModelManager()->GetResource(CoreName); if (l_AnimatedCoreModel == NULL) { m_bIsOk = false; } else { m_AnimatedInstanceModel = new CAnimatedInstanceModel(); m_AnimatedInstanceModel->Initialize(l_AnimatedCoreModel); m_AnimatedInstanceModel->InitD3D(CORE->GetRenderManager()); SetName(Name); SetPitch(0.0); SetPosition(0.0); SetRoll(0.0); SetVisible(false); SetYaw(0.0); } }
EXPORT_GCC void CALLBACK SPU2write(unsigned long reg, unsigned short val) { long r=reg&0xffff; regArea[r>>1] = val; // printf("SPU2: %04x to %08x\n", val, reg); if((r>=0x0000 && r<0x0180)||(r>=0x0400 && r<0x0580)) // some channel info? { int ch=(r>>4)&0x1f; if(r>=0x400) ch+=24; switch(r&0x0f) { //------------------------------------------------// r volume case 0: SetVolumeL((unsigned char)ch,val); break; //------------------------------------------------// l volume case 2: SetVolumeR((unsigned char)ch,val); break; //------------------------------------------------// pitch case 4: SetPitch(ch,val); break; //------------------------------------------------// level with pre-calcs case 6: { const unsigned long lval=val;unsigned long lx; //---------------------------------------------// s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0; s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f; s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f; s_chan[ch].ADSRX.SustainLevel=lval & 0x000f; //---------------------------------------------// if(!iDebugMode) break; //---------------------------------------------// stuff below is only for debug mode s_chan[ch].ADSR.AttackModeExp=(lval&0x8000)?1:0; //0x007f lx=(((lval>>8) & 0x007f)>>2); // attack time to run from 0 to 100% volume lx = (lx < 31) ? lx : 31; // no overflow on shift! if(lx) { lx = (1<<lx); if(lx<2147483) lx=(lx*ATTACK_MS)/10000L; // another overflow check else lx=(lx/10000L)*ATTACK_MS; if(!lx) lx=1; } s_chan[ch].ADSR.AttackTime=lx; s_chan[ch].ADSR.SustainLevel= // our adsr vol runs from 0 to 1024, so scale the sustain level (1024*((lval) & 0x000f))/15; lx=(lval>>4) & 0x000f; // decay: if(lx) // our const decay value is time it takes from 100% to 0% of volume { lx = ((1<<(lx))*DECAY_MS)/10000L; if(!lx) lx=1; } s_chan[ch].ADSR.DecayTime = // so calc how long does it take to run from 100% to the wanted sus level (lx*(1024-s_chan[ch].ADSR.SustainLevel))/1024; } break; //------------------------------------------------// adsr times with pre-calcs case 8: { const unsigned long lval=val;unsigned long lx; //----------------------------------------------// s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0; s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1; s_chan[ch].ADSRX.SustainRate = (lval>>6) & 0x007f; s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0; s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f; //----------------------------------------------// if(!iDebugMode) break; //----------------------------------------------// stuff below is only for debug mode s_chan[ch].ADSR.SustainModeExp = (lval&0x8000)?1:0; s_chan[ch].ADSR.ReleaseModeExp = (lval&0x0020)?1:0; lx=((((lval>>6) & 0x007f)>>2)); // sustain time... often very high lx = (lx < 31) ? lx : 31; // values are used to hold the volume if(lx) // until a sound stop occurs { // the highest value we reach (due to lx = (1<<lx); // overflow checking) is: if(lx<2147483) lx=(lx*SUSTAIN_MS)/10000L; // 94704 seconds = 1578 minutes = 26 hours... else lx=(lx/10000L)*SUSTAIN_MS; // should be enuff... if the stop doesn't if(!lx) lx=1; // come in this time span, I don't care :) } s_chan[ch].ADSR.SustainTime = lx; lx=(lval & 0x001f); s_chan[ch].ADSR.ReleaseVal =lx; if(lx) // release time from 100% to 0% { // note: the release time will be lx = (1<<lx); // adjusted when a stop is coming, if(lx<2147483) lx=(lx*RELEASE_MS)/10000L; // so at this time the adsr vol will else lx=(lx/10000L)*RELEASE_MS; // run from (current volume) to 0% if(!lx) lx=1; } s_chan[ch].ADSR.ReleaseTime=lx; if(lval & 0x4000) // add/dec flag s_chan[ch].ADSR.SustainModeDec=-1; else s_chan[ch].ADSR.SustainModeDec=1; } break; //------------------------------------------------// } iSpuAsyncWait=0; return; }
void AudioSourceOJM::parseOMC() { OMC_header Head; int acc_keybyte = 0xFF; int acc_counter = 0; int Offset = 20; int SampleID = 0; ifile->read(reinterpret_cast<char*>(&Head), sizeof(OMC_header)); // Parse WAV data first while (Offset < Head.ogg_start) { CheckInterruption(); OMC_WAV_header WavHead; ifile->read(reinterpret_cast<char*>(&WavHead), sizeof(OMC_WAV_header)); Offset += sizeof(OMC_WAV_header) + WavHead.chunk_size; if (WavHead.chunk_size == 0) { SampleID++; continue; } std::vector<char> Buffer(WavHead.chunk_size); ifile->read(&Buffer[0], WavHead.chunk_size); omc_rearrange(&Buffer[0], WavHead.chunk_size); omc_xor(&Buffer[0], WavHead.chunk_size, acc_keybyte, acc_counter); int ifmt; switch (WavHead.bits_per_sample) { case 8: ifmt = SF_FORMAT_PCM_U8; break; case 16: ifmt = SF_FORMAT_PCM_16; break; case 24: ifmt = SF_FORMAT_PCM_24; break; case 32: ifmt = SF_FORMAT_PCM_32; break; default: ifmt = 0; } SF_INFO Info; Info.format = ifmt | SF_FORMAT_RAW; Info.samplerate = WavHead.sample_rate; Info.channels = WavHead.num_channels; SFM30 ToLoad; ToLoad.Buffer = std::move(Buffer); ToLoad.DataLength = WavHead.chunk_size; auto NewSample = std::make_shared<SoundSample>(); TemporaryState.File = sf_open_virtual(&M30Interface, SFM_READ, &Info, &ToLoad); TemporaryState.Info = &Info; TemporaryState.Enabled = OJM_WAV; NewSample->SetPitch(Speed); NewSample->Open(this); TemporaryState.Enabled = false; Arr[SampleID] = NewSample; SampleID++; } SampleID = 1000; // We start from the first OGG file.. while (Offset < Head.fsize) { CheckInterruption(); OMC_OGG_header OggHead; ifile->read(reinterpret_cast<char*>(&OggHead), sizeof(OMC_OGG_header)); Offset += sizeof(OMC_OGG_header) + OggHead.sample_size; if (OggHead.sample_size == 0) { SampleID++; continue; } std::vector<char> Buffer(OggHead.sample_size); ifile->read(&Buffer[0], OggHead.sample_size); auto NewSample = std::make_shared<SoundSample>(); SFM30 ToLoad; ToLoad.Buffer = Buffer; ToLoad.DataLength = OggHead.sample_size; OggVorbis_File vf; ov_open_callbacks(&ToLoad, &vf, nullptr, 0, M30InterfaceOgg); TemporaryState.File = &vf; TemporaryState.Info = vf.vi; TemporaryState.Enabled = OJM_OGG; NewSample->SetPitch(Speed); NewSample->Open(this); TemporaryState.Enabled = false; ov_clear(&vf); Arr[SampleID] = NewSample; SampleID++; } }