From 34054d2d599fa22d001ee1b8abbbd5ab19bdd660 Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Fri, 20 Apr 2018 08:56:34 -0700 Subject: [PATCH 1/7] Reset N163 level offset in sound engine, when switching files. --- Source/FamiTrackerDoc.cpp | 14 +++++++------- Source/FamiTrackerDoc.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/FamiTrackerDoc.cpp b/Source/FamiTrackerDoc.cpp index 980f938b..3ec52101 100644 --- a/Source/FamiTrackerDoc.cpp +++ b/Source/FamiTrackerDoc.cpp @@ -400,7 +400,7 @@ void CFamiTrackerDoc::DeleteContents() m_iExpansionChip = SNDCHIP_NONE; m_iVibratoStyle = VIBRATO_OLD; m_bLinearPitch = DEFAULT_LINEAR_PITCH; - N163LevelOffset = 0; + SetN163LevelOffset(0); m_iChannelsAvailable = CHANNELS_DEFAULT; m_iSpeedSplitPoint = DEFAULT_SPEED_SPLIT_POINT; @@ -461,7 +461,7 @@ void CFamiTrackerDoc::CreateEmpty() // Auto-select new style vibrato for new modules m_iVibratoStyle = VIBRATO_NEW; m_bLinearPitch = DEFAULT_LINEAR_PITCH; - N163LevelOffset = 0; + SetN163LevelOffset(0); m_iNamcoChannels = 0; // // // @@ -1308,7 +1308,7 @@ BOOL CFamiTrackerDoc::OpenDocument(LPCTSTR lpszPathName) // Auto-select old style vibrato for old files m_iVibratoStyle = VIBRATO_OLD; m_bLinearPitch = false; - N163LevelOffset = 0; + SetN163LevelOffset(0); } else { if (!OpenDocumentNew(OpenFile)) @@ -1356,7 +1356,7 @@ BOOL CFamiTrackerDoc::OpenDocumentOld(CFile *pOpenFile) m_iVibratoStyle = VIBRATO_OLD; m_bLinearPitch = false; - N163LevelOffset = 0; + SetN163LevelOffset(0); // // // local structs struct { @@ -4283,13 +4283,13 @@ void CFamiTrackerDoc::SetLinearPitch(bool Enable) // N163 Volume Offset int CFamiTrackerDoc::GetN163LevelOffset() const { - return N163LevelOffset; + return _N163LevelOffset; } void CFamiTrackerDoc::SetN163LevelOffset(int offset) { - if (N163LevelOffset != offset) { + if (_N163LevelOffset != offset) { ModifyIrreversible(); - N163LevelOffset = offset; + _N163LevelOffset = offset; theApp.LoadSoundConfig(); } } diff --git a/Source/FamiTrackerDoc.h b/Source/FamiTrackerDoc.h index 9571f14d..116a9ac9 100644 --- a/Source/FamiTrackerDoc.h +++ b/Source/FamiTrackerDoc.h @@ -512,7 +512,7 @@ class CFamiTrackerDoc : public CDocument, public CFTMComponentInterface unsigned int m_iNamcoChannels; vibrato_t m_iVibratoStyle; // 0 = old style, 1 = new style bool m_bLinearPitch; - int N163LevelOffset; + int _N163LevelOffset; machine_t m_iMachine; // // // NTSC / PAL unsigned int m_iEngineSpeed; // Refresh rate From 84338cd4dda83adaa21df207f87ce6686a27beb6 Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 22 Apr 2018 00:01:08 -0700 Subject: [PATCH 2/7] Make CFamiTrackerDoc::LoadImportFile(path) static. --- Source/FamiTrackerDoc.cpp | 2 +- Source/FamiTrackerDoc.h | 2 +- Source/ModuleImportDlg.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/FamiTrackerDoc.cpp b/Source/FamiTrackerDoc.cpp index 3ec52101..36093c3a 100644 --- a/Source/FamiTrackerDoc.cpp +++ b/Source/FamiTrackerDoc.cpp @@ -2613,7 +2613,7 @@ bool CFamiTrackerDoc::WriteBlock_ParamsExtra(CDocumentFile *pDocFile, const int // FTM import //// -CFamiTrackerDoc *CFamiTrackerDoc::LoadImportFile(LPCTSTR lpszPathName) const +CFamiTrackerDoc *CFamiTrackerDoc::LoadImportFile(LPCTSTR lpszPathName) { // Import a module as new subtunes CFamiTrackerDoc *pImported = new CFamiTrackerDoc(); diff --git a/Source/FamiTrackerDoc.h b/Source/FamiTrackerDoc.h index 116a9ac9..95709bc5 100644 --- a/Source/FamiTrackerDoc.h +++ b/Source/FamiTrackerDoc.h @@ -118,7 +118,7 @@ class CFamiTrackerDoc : public CDocument, public CFTMComponentInterface bool HasLastLoadFailed() const; // Import - CFamiTrackerDoc* LoadImportFile(LPCTSTR lpszPathName) const; + static CFamiTrackerDoc* LoadImportFile(LPCTSTR lpszPathName); bool ImportInstruments(CFamiTrackerDoc *pImported, int *pInstTable); bool ImportGrooves(CFamiTrackerDoc *pImported, int *pGrooveMap); // // // bool ImportDetune(CFamiTrackerDoc *pImported); // // // diff --git a/Source/ModuleImportDlg.cpp b/Source/ModuleImportDlg.cpp index 4799874c..8f334ccf 100644 --- a/Source/ModuleImportDlg.cpp +++ b/Source/ModuleImportDlg.cpp @@ -96,7 +96,7 @@ void CModuleImportDlg::OnBnClickedCancel() bool CModuleImportDlg::LoadFile(CString Path, CFamiTrackerDoc *pDoc) { - m_pImportedDoc = pDoc->LoadImportFile(Path); + m_pImportedDoc = CFamiTrackerDoc::LoadImportFile(Path); // Check if load failed if (m_pImportedDoc == NULL) From 718e95e0753fdbca63951fde495b1b46e0f378ad Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 22 Apr 2018 00:02:47 -0700 Subject: [PATCH 3/7] style --- Source/FamiTrackerDoc.cpp | 5 +++++ Source/SoundGen.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/FamiTrackerDoc.cpp b/Source/FamiTrackerDoc.cpp index 36093c3a..dc92ecc7 100644 --- a/Source/FamiTrackerDoc.cpp +++ b/Source/FamiTrackerDoc.cpp @@ -268,6 +268,8 @@ BOOL CFamiTrackerDoc::OnNewDocument() if (!CDocument::OnNewDocument()) return FALSE; + // CFamiTrackerDoc::OnNewDocument calls CDocument::OnNewDocument() and CreateEmpty(). Both call DeleteContents. + // Opening files doesn't call CDocument::OnNewDocument() but calls CreateEmpty(). Only the latter calls DeleteContents. CreateEmpty(); return TRUE; @@ -452,6 +454,9 @@ void CFamiTrackerDoc::SetModifiedFlag(BOOL bModified) void CFamiTrackerDoc::CreateEmpty() { + // CFamiTrackerDoc::OnNewDocument calls CDocument::OnNewDocument() and CreateEmpty(). Both call DeleteContents. + // OpenDocument() doesn't call CDocument::OnNewDocument() but calls CreateEmpty(). Only the latter calls DeleteContents. + m_csDocumentLock.Lock(); // Allocate first song diff --git a/Source/SoundGen.cpp b/Source/SoundGen.cpp index afffe655..0c80a8f0 100644 --- a/Source/SoundGen.cpp +++ b/Source/SoundGen.cpp @@ -745,7 +745,7 @@ bool CSoundGen::ResetAudioDevice() m_pAPU->SetChipLevel(CHIP_LEVEL_MMC5, float(pSettings->ChipLevels.iLevelMMC5 / 10.0f)); m_pAPU->SetChipLevel(CHIP_LEVEL_FDS, float(pSettings->ChipLevels.iLevelFDS / 10.0f)); m_pAPU->SetChipLevel(CHIP_LEVEL_N163, float( - (pSettings->ChipLevels.iLevelN163 + m_pDocument->GetN163LevelOffset())/ 10.0f)); + (pSettings->ChipLevels.iLevelN163 + m_pDocument->GetN163LevelOffset()) / 10.0f)); m_pAPU->SetChipLevel(CHIP_LEVEL_S5B, float(pSettings->ChipLevels.iLevelS5B / 10.0f)); /* m_pAPU->SetChipLevel(SNDCHIP_NONE, 0);//pSettings->ChipLevels.iLevel2A03); From 2c77f05b5e8c67793db90f2866de98d2896a59df Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 22 Apr 2018 00:03:33 -0700 Subject: [PATCH 4/7] Independent document files don't reload sound configuration. --- Source/FamiTrackerDoc.cpp | 27 ++++++++++++++++++++++++--- Source/FamiTrackerDoc.h | 1 + 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Source/FamiTrackerDoc.cpp b/Source/FamiTrackerDoc.cpp index dc92ecc7..7e9db5e5 100644 --- a/Source/FamiTrackerDoc.cpp +++ b/Source/FamiTrackerDoc.cpp @@ -402,7 +402,15 @@ void CFamiTrackerDoc::DeleteContents() m_iExpansionChip = SNDCHIP_NONE; m_iVibratoStyle = VIBRATO_OLD; m_bLinearPitch = DEFAULT_LINEAR_PITCH; - SetN163LevelOffset(0); + + // SetN163LevelOffset() + // If we're closing the program, tries to initialize a dead sound engine. + // If we're creating file, this gets called twice. + _N163LevelOffset = INT_MIN; + // If we're switching files, setting to 0 will fail to reinitialize the sound engine. + // If we set to INT_MIN, opening a file will reinitialize the sound engine unnecessarily. + // Honestly it doesn't matter. + // So leave it stale. m_iChannelsAvailable = CHANNELS_DEFAULT; m_iSpeedSplitPoint = DEFAULT_SPEED_SPLIT_POINT; @@ -523,6 +531,11 @@ void CFamiTrackerDoc::OnFileSaveAs() DoSave(newName); } +bool CFamiTrackerDoc::isMainDocument() { + CFrameWnd *pFrameWnd = dynamic_cast(theApp.m_pMainWnd); + return pFrameWnd && pFrameWnd->GetActiveDocument() == this; +} + // CFamiTrackerDoc serialization (never used) void CFamiTrackerDoc::Serialize(CArchive& ar) @@ -1342,7 +1355,9 @@ BOOL CFamiTrackerDoc::OpenDocument(LPCTSTR lpszPathName) m_bFileLoadFailed = false; m_bBackupDone = false; // // // - theApp.GetSoundGenerator()->DocumentPropertiesChanged(this); + if (isMainDocument()) { + theApp.GetSoundGenerator()->DocumentPropertiesChanged(this); + } return TRUE; } @@ -4295,7 +4310,13 @@ void CFamiTrackerDoc::SetN163LevelOffset(int offset) { if (_N163LevelOffset != offset) { ModifyIrreversible(); _N163LevelOffset = offset; - theApp.LoadSoundConfig(); + + if (isMainDocument()) { + theApp.LoadSoundConfig(); // CSoundGen::ResetAudioDevice looks at GetN163LevelOffset() + // TODO I should move N163 volume loading logic to DocumentPropertiesChanged? I'm not sure. + // TODO: theApp.GetSoundGenerator()->SetN163LevelOffset(offset)? + // Maybe I should pull out "primary FT doc connected to synth" and "imported FT doc" into separate classes. + } } } diff --git a/Source/FamiTrackerDoc.h b/Source/FamiTrackerDoc.h index 95709bc5..64595057 100644 --- a/Source/FamiTrackerDoc.h +++ b/Source/FamiTrackerDoc.h @@ -571,5 +571,6 @@ class CFamiTrackerDoc : public CDocument, public CFTMComponentInterface DECLARE_MESSAGE_MAP() public: afx_msg void OnFileSaveAs(); + bool isMainDocument(); afx_msg void OnFileSave(); }; From 635707cdc613929d4b972708980f5516d2aa8a09 Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 22 Apr 2018 07:19:14 -0700 Subject: [PATCH 5/7] Fix bug where cancelled module imports change vibrato and linear pitch in synth, but not module. --- Source/SoundGen.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/SoundGen.cpp b/Source/SoundGen.cpp index 0c80a8f0..15654a56 100644 --- a/Source/SoundGen.cpp +++ b/Source/SoundGen.cpp @@ -364,6 +364,8 @@ CChannelHandler *CSoundGen::GetChannel(int Index) const void CSoundGen::DocumentPropertiesChanged(CFamiTrackerDoc *pDocument) { + if (pDocument != m_pDocument) + return; ASSERT(pDocument != NULL); SetupVibratoTable(pDocument->GetVibratoStyle()); // // // From 218b5bb28567a50a72a0d4dcc32bebabd334c35f Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 22 Apr 2018 07:26:52 -0700 Subject: [PATCH 6/7] Move N163 offset loading to CSoundGen::DocumentPropertiesChanged(document). --- Source/FamiTrackerDoc.cpp | 19 +++---------------- Source/FamiTrackerDoc.h | 1 - Source/SoundGen.cpp | 23 +++++++++++++++++++++-- Source/SoundGen.h | 1 + 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/Source/FamiTrackerDoc.cpp b/Source/FamiTrackerDoc.cpp index 7e9db5e5..af53c846 100644 --- a/Source/FamiTrackerDoc.cpp +++ b/Source/FamiTrackerDoc.cpp @@ -406,7 +406,7 @@ void CFamiTrackerDoc::DeleteContents() // SetN163LevelOffset() // If we're closing the program, tries to initialize a dead sound engine. // If we're creating file, this gets called twice. - _N163LevelOffset = INT_MIN; + SetN163LevelOffset(0); // If we're switching files, setting to 0 will fail to reinitialize the sound engine. // If we set to INT_MIN, opening a file will reinitialize the sound engine unnecessarily. // Honestly it doesn't matter. @@ -531,11 +531,6 @@ void CFamiTrackerDoc::OnFileSaveAs() DoSave(newName); } -bool CFamiTrackerDoc::isMainDocument() { - CFrameWnd *pFrameWnd = dynamic_cast(theApp.m_pMainWnd); - return pFrameWnd && pFrameWnd->GetActiveDocument() == this; -} - // CFamiTrackerDoc serialization (never used) void CFamiTrackerDoc::Serialize(CArchive& ar) @@ -1355,9 +1350,7 @@ BOOL CFamiTrackerDoc::OpenDocument(LPCTSTR lpszPathName) m_bFileLoadFailed = false; m_bBackupDone = false; // // // - if (isMainDocument()) { - theApp.GetSoundGenerator()->DocumentPropertiesChanged(this); - } + theApp.GetSoundGenerator()->DocumentPropertiesChanged(this); return TRUE; } @@ -4306,17 +4299,11 @@ int CFamiTrackerDoc::GetN163LevelOffset() const { return _N163LevelOffset; } +// DocumentPropertiesChanged calls GetN163LevelOffset and updates synth if modified. void CFamiTrackerDoc::SetN163LevelOffset(int offset) { if (_N163LevelOffset != offset) { ModifyIrreversible(); _N163LevelOffset = offset; - - if (isMainDocument()) { - theApp.LoadSoundConfig(); // CSoundGen::ResetAudioDevice looks at GetN163LevelOffset() - // TODO I should move N163 volume loading logic to DocumentPropertiesChanged? I'm not sure. - // TODO: theApp.GetSoundGenerator()->SetN163LevelOffset(offset)? - // Maybe I should pull out "primary FT doc connected to synth" and "imported FT doc" into separate classes. - } } } diff --git a/Source/FamiTrackerDoc.h b/Source/FamiTrackerDoc.h index 64595057..95709bc5 100644 --- a/Source/FamiTrackerDoc.h +++ b/Source/FamiTrackerDoc.h @@ -571,6 +571,5 @@ class CFamiTrackerDoc : public CDocument, public CFTMComponentInterface DECLARE_MESSAGE_MAP() public: afx_msg void OnFileSaveAs(); - bool isMainDocument(); afx_msg void OnFileSave(); }; diff --git a/Source/SoundGen.cpp b/Source/SoundGen.cpp index 15654a56..84575f14 100644 --- a/Source/SoundGen.cpp +++ b/Source/SoundGen.cpp @@ -139,7 +139,8 @@ CSoundGen::CSoundGen() : m_pSequencePlayPos(NULL), m_iSequencePlayPos(0), m_iSequenceTimeout(0), - m_iBPMCachePosition(0) // // // + m_iBPMCachePosition(0), // // // + currN163LevelOffset(0) { TRACE("SoundGen: Object created\n"); @@ -362,6 +363,16 @@ CChannelHandler *CSoundGen::GetChannel(int Index) const return m_pChannels[Index]; } +/* +INVARIANT: called whenever any document is created or changes. + CREATION: + CreateEmpty() calls DocumentPropertiesChanged. + OpenDocument() calls DocumentPropertiesChanged. + +PRECONDITION: pDocument is not null. +PROPERTY: if pDocument is main document, linear pitch is synced. +RESULT: linear pitch is correct. +*/ void CSoundGen::DocumentPropertiesChanged(CFamiTrackerDoc *pDocument) { if (pDocument != m_pDocument) @@ -531,6 +542,12 @@ void CSoundGen::DocumentPropertiesChanged(CFamiTrackerDoc *pDocument) } m_iSpeedSplitPoint = pDocument->GetSpeedSplitPoint(); + + if (currN163LevelOffset != pDocument->GetN163LevelOffset()) { + // Player thread calls OnLoadSettings() which calls ResetAudioDevice() + // Why are GetCurrentThreadId and GetCurrentThread used interchangably? + LoadSettings(); + } } // @@ -740,6 +757,8 @@ bool CSoundGen::ResetAudioDevice() if (!m_pAPU->SetupSound(SampleRate, 1, (m_iMachineType == NTSC) ? MACHINE_NTSC : MACHINE_PAL)) return false; + currN163LevelOffset = m_pDocument->GetN163LevelOffset(); + m_pAPU->SetChipLevel(CHIP_LEVEL_APU1, float(pSettings->ChipLevels.iLevelAPU1 / 10.0f)); m_pAPU->SetChipLevel(CHIP_LEVEL_APU2, float(pSettings->ChipLevels.iLevelAPU2 / 10.0f)); m_pAPU->SetChipLevel(CHIP_LEVEL_VRC6, float(pSettings->ChipLevels.iLevelVRC6 / 10.0f)); @@ -747,7 +766,7 @@ bool CSoundGen::ResetAudioDevice() m_pAPU->SetChipLevel(CHIP_LEVEL_MMC5, float(pSettings->ChipLevels.iLevelMMC5 / 10.0f)); m_pAPU->SetChipLevel(CHIP_LEVEL_FDS, float(pSettings->ChipLevels.iLevelFDS / 10.0f)); m_pAPU->SetChipLevel(CHIP_LEVEL_N163, float( - (pSettings->ChipLevels.iLevelN163 + m_pDocument->GetN163LevelOffset()) / 10.0f)); + (pSettings->ChipLevels.iLevelN163 + currN163LevelOffset) / 10.0f)); m_pAPU->SetChipLevel(CHIP_LEVEL_S5B, float(pSettings->ChipLevels.iLevelS5B / 10.0f)); /* m_pAPU->SetChipLevel(SNDCHIP_NONE, 0);//pSettings->ChipLevels.iLevel2A03); diff --git a/Source/SoundGen.h b/Source/SoundGen.h index 0230132c..0c9d9352 100644 --- a/Source/SoundGen.h +++ b/Source/SoundGen.h @@ -298,6 +298,7 @@ class CSoundGen : public CWinThread, IAudioCallback CDSoundChannel *m_pDSoundChannel; CVisualizerWnd *m_pVisualizerWnd; CAPU *m_pAPU; + int currN163LevelOffset; const CDSample *m_pPreviewSample; From 8871b61f72e7e16a3d66f11bad26870c8e696faf Mon Sep 17 00:00:00 2001 From: nyanpasu64 Date: Sun, 22 Apr 2018 08:06:19 -0700 Subject: [PATCH 7/7] Cleanup comments. --- Source/FamiTrackerDoc.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Source/FamiTrackerDoc.cpp b/Source/FamiTrackerDoc.cpp index af53c846..1ae66824 100644 --- a/Source/FamiTrackerDoc.cpp +++ b/Source/FamiTrackerDoc.cpp @@ -402,15 +402,7 @@ void CFamiTrackerDoc::DeleteContents() m_iExpansionChip = SNDCHIP_NONE; m_iVibratoStyle = VIBRATO_OLD; m_bLinearPitch = DEFAULT_LINEAR_PITCH; - - // SetN163LevelOffset() - // If we're closing the program, tries to initialize a dead sound engine. - // If we're creating file, this gets called twice. SetN163LevelOffset(0); - // If we're switching files, setting to 0 will fail to reinitialize the sound engine. - // If we set to INT_MIN, opening a file will reinitialize the sound engine unnecessarily. - // Honestly it doesn't matter. - // So leave it stale. m_iChannelsAvailable = CHANNELS_DEFAULT; m_iSpeedSplitPoint = DEFAULT_SPEED_SPLIT_POINT;