BOOL CModDoc::ExpandPattern(PATTERNINDEX nPattern) //------------------------------------------------ { ROWINDEX numRows; if(!m_SndFile.Patterns.IsValidPat(nPattern) || (numRows = m_SndFile.Patterns[nPattern].GetNumRows()) > m_SndFile.GetModSpecifications().patternRowsMax / 2) { return false; } BeginWaitCursor(); CriticalSection cs; GetPatternUndo().PrepareUndo(nPattern, 0, 0, GetNumChannels(), numRows, "Expand Pattern"); bool success = m_SndFile.Patterns[nPattern].Expand(); cs.Leave(); EndWaitCursor(); if(success) { SetModified(); UpdateAllViews(NULL, PatternHint(nPattern).Data(), NULL); } else { GetPatternUndo().RemoveLastUndoStep(); } return success; }
void* __stdcall MediaInfo_New () { #ifdef MEDIAINFO_DEBUG Debug_Open(false); Debug+=", New, Build="; Debug+=__DATE__; Debug+=' '; Debug+=__TIME__; Debug_Close(); #endif //MEDIAINFO_DEBUG //First init Critical.Enter(); if (MI_Outputs.find(NULL)==MI_Outputs.end()) { MI_Outputs[NULL]=new mi_output; //Generic Handle } Critical.Leave(); //New MediaInfo* Handle=NULL; try { Handle=new MediaInfo; } catch(...) { MEDIAINFO_DEBUG2( "New", Debug+="!!!Exception thrown!!!";) delete Handle; return NULL; }
PLUGIN_FUNCTION_ARG4(RingLine, unsigned,line, unsigned,nCadence, const unsigned *,pattern, unsigned,frequency) { if (m_eProductID == TJIP_NONE) return PluginLID_DeviceNotOpen; if (line >= 1) return PluginLID_NoSuchLine; if (m_hRingThread != NULL) { SetEvent(m_hRingStopEvent); if (WaitForSingleObject(m_hRingThread, 5000) == WAIT_TIMEOUT) TerminateThread(m_hRingThread, -1); CloseHandle(m_hRingStopEvent); m_hRingStopEvent = NULL; m_hRingThread = NULL; } m_KeyMutex.Enter(); m_ringCadence.assign(pattern, &pattern[nCadence]); m_ringFrequency = nCadence == 0 ? 0 : frequency; Beep(m_ringFrequency); if (nCadence > 1) { m_hRingStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL); m_hRingThread = (HANDLE)_beginthread(CadenceThreadMain, 0, this); } m_KeyMutex.Leave(); return PluginLID_NoError; }
void KeyCallback(UINT message, WPARAM wParam, LPARAM lParam) { m_KeyMutex.Enter(); switch (message) { case WM_TJIP_HID_KEY_RELEASED: Beep(m_ringFrequency); break; case WM_TJIP_HID_NEW_KEY: static struct { WPARAM code; char ascii; int frequency; int hook; // 1 is off hook, -1 if on hook, 0 is no change } KeyInfo[] = { { 0xb0, '0', (941+1336)/2 }, // Average the DTMF frequencies { 0xb1, '1', (697+1209)/2 }, { 0xb2, '2', (697+1336)/2 }, { 0xb3, '3', (697+1477)/2 }, { 0xb4, '4', (770+1209)/2 }, { 0xb5, '5', (770+1336)/2 }, { 0xb6, '6', (770+1477)/2 }, { 0xb7, '7', (852+1209)/2 }, { 0xb8, '8', (852+1336)/2 }, { 0xb9, '9', (852+1477)/2 }, { 0xba, '*', (941+1209)/2 }, { 0xbb, '#', (941+1477)/2 }, { 0x51, 'd', 900 }, // down { 0x52, 'u', 1400 }, // up { 0x2f, 'm', 500 }, // Mute { 0x2a, '\b', 2500 }, // Clear/Backspace key { 0x31, '\r', 1800, 1 }, // Enter (dial) key { 0x26, '\033', 700, -1 } // Escape (hangup) key }; for (int i = 0; i < sizeof(KeyInfo)/sizeof(KeyInfo[0]); i++) { if (wParam == KeyInfo[i].code) { Beep(KeyInfo[i].frequency); switch (KeyInfo[i].hook) { case 1 : if (!m_isOffHook) { m_isOffHook = true; while (!m_Keys.empty()) m_Keys.pop(); } break; case -1 : m_isOffHook = false; break; default : m_Keys.push(KeyInfo[i].ascii); } break; } } } m_KeyMutex.Leave(); }
// vldnew - Local helper function that actually allocates memory from VLD's // private heap. Prepends a header, which is used for bookkeeping information // that allows VLD to detect and report internal memory leaks, to the returned // block, but the header is transparent to the caller because the returned // pointer points to the usable section of memory requested by the caller, it // does not point to the block header. // // - size (IN): Size of the memory block to be allocated. // // - file (IN): Name of the file that called the new operator. // // - line (IN): Line, in the above file, at which the new operator was called. // // Return Value: // // If the memory allocation succeeds, a pointer to the allocated memory // block is returned. If the allocation fails, NULL is returned. // void* vldnew (size_t size, const char *file, int line) { vldblockheader_t *header = (vldblockheader_t*)RtlAllocateHeap(g_vldHeap, 0x0, size + sizeof(vldblockheader_t)); static SIZE_T serialnumber = 0; if (header == NULL) { // Out of memory. return NULL; } // Fill in the block's header information. header->file = file; header->line = line; header->serialNumber = serialnumber++; header->size = size; // Link the block into the block list. g_vldHeapLock.Enter(); header->next = g_vldBlockList; if (header->next != NULL) { header->next->prev = header; } header->prev = NULL; g_vldBlockList = header; g_vldHeapLock.Leave(); // Return a pointer to the beginning of the data section of the block. return (void*)VLDBLOCKDATA(header); }
// vlddelete - Local helper function that actually frees memory back to VLD's // private heap. // // - block (IN): Pointer to a memory block being freed. // // Return Value: // // None. // void vlddelete (void *block) { if (block == NULL) return; BOOL freed; vldblockheader_t *header = VLDBLOCKHEADER((LPVOID)block); // Unlink the block from the block list. g_vldHeapLock.Enter(); if (header->prev) { header->prev->next = header->next; } else { g_vldBlockList = header->next; } if (header->next) { header->next->prev = header->prev; } g_vldHeapLock.Leave(); // Free the block. freed = RtlFreeHeap(g_vldHeap, 0x0, header); assert(freed != FALSE); }
HANDLE LispThreadQueue::remove(DWORD threadID) { TQCriticalSection.Enter(); HANDLE threadHandle = 0; ThreadRecord* rec = 0; ThreadRecord** prec = &list; while (*prec) { if ((*prec)->threadID == threadID) break; prec = &((*prec)->next); } if ((*prec)->threadID == threadID) { rec = *prec; threadHandle = rec->thread; *prec = (*prec)->next; delete [] rec->QV_rec; delete rec; } // else error TQCriticalSection.Leave(); return threadHandle; }
bool Ignition::Stop(const char* name, const bool cancel, IgniteError* err) { bool res = false; factoryLock.Enter(); if (started) { JniErrorInfo jniErr; SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr)); IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err); if (err->GetCode() == IgniteError::IGNITE_SUCCESS) { char* name0 = CopyChars(name); bool res0 = ctx.Get()->IgnitionStop(name0, cancel, &jniErr); ReleaseChars(name0); IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err); if (err->GetCode() == IgniteError::IGNITE_SUCCESS) res = res0; } } factoryLock.Leave(); return res; }
void LispThreadQueue::insert(ThreadRecord* rec) { TQCriticalSection.Enter(); rec->next = list; list = rec; TQCriticalSection.Leave(); }
static void StartTyping(MCONTACT hContact, const TalkBot::MessageInfo*) { CallService(MS_PROTO_SELFISTYPING, hContact, (LPARAM)PROTOTYPE_SELFTYPING_ON); typingContactsLock.Enter(); typingContacts.insert(hContact); typingContactsLock.Leave(); }
VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) { cs.Enter(); QueueElement q = actionQueue.front(); actionQueue.pop_front(); UpdateTimer(); cs.Leave(); q.Handler(q.hContact, q.inf); }
ThreadRecord* LispThreadQueue::getPrimaryThread() { ThreadRecord* tr = 0; TQCriticalSection.Enter(); for (tr = list; tr != 0; tr = tr->next) if (tr->type == ThreadRecord::PrimaryThread) break; TQCriticalSection.Leave(); return tr; }
unsigned long CriticalSectionThreadFunc(void* pParam) { for (int i = 0; i < 10; ++i) { section.Enter(); nCounter++; cout << "Critical Section Thread ID: " << reinterpret_cast<int>(pParam) << ", \t Counter: " << nCounter << endl; section.Leave(); } return 0; };
void CadenceThread() { size_t cadenceIndex = 0; while (m_ringCadence.size() > 0 && WaitForSingleObject(m_hRingStopEvent, m_ringCadence[cadenceIndex]) == WAIT_TIMEOUT) { m_KeyMutex.Enter(); if (++cadenceIndex >= m_ringCadence.size()) cadenceIndex = 0; Beep((cadenceIndex&1) != 0 ? 0 : m_ringFrequency); m_KeyMutex.Leave(); } }
void LispThreadQueue::resumeAllOtherThreads() { TQCriticalSection.Enter(); ThreadRecord* tr = list; ThreadRecord* currThread = (ThreadRecord*)TlsGetValue(Thread_Index); while (tr) { if (tr != currThread) ResumeThread(tr->thread); tr = tr->next; } TQCriticalSection.Leave(); }
// // Given a buffer of size DWORDs, populates the buffer with // the thread IDs of all currently active lisp threads. // Returns the number of thread IDs actually stored in the buffer. // DWORD LispThreadQueue::GetLispThreadIDs(DWORD* buf, int size) { TQCriticalSection.Enter(); ThreadRecord* tr = list; int i = 0; while (tr && i < size) { buf[i++] = tr->threadID; tr = tr->next; } TQCriticalSection.Leave(); return i; }
//--------------------------------------------------------------------------- const wchar_t* MB2WC(void* Handle, size_t Pos, const char* Text) { //Coherancy Critical.Enter(); mi_inputs::iterator MI_Input=MI_Inputs.find(Handle); if (MI_Input==MI_Inputs.end()) { MI_Inputs[Handle]=new mi_input; //Generic Handle MI_Input=MI_Inputs.find(Handle); } Critical.Leave(); //Adaptation if (utf8) return MI_Input->second->Unicode[Pos].From_UTF8(Text).c_str(); else return MI_Input->second->Unicode[Pos].From_Local(Text).c_str(); }
//--------------------------------------------------------------------------- const char* WC2MB(void* Handle, const wchar_t* Text) { //Coherancy Critical.Enter(); mi_outputs::iterator MI_Output=MI_Outputs.find(Handle); if (MI_Outputs.find(Handle)==MI_Outputs.end()) { MI_Outputs[Handle]=new mi_output; //Generic Handle MI_Output=MI_Outputs.find(Handle); } Critical.Leave(); //Adaptation if (utf8) MI_Output->second->Ansi=Ztring(Text).To_UTF8(); else MI_Output->second->Ansi=Ztring(Text).To_Local(); return MI_Output->second->Ansi.c_str(); }
HANDLE LispThreadQueue::GetLispThreadHandle(DWORD id) { TQCriticalSection.Enter(); ThreadRecord* tr = list; int i = 0; HANDLE ret = 0; while (tr) { if (id == tr->threadID) { ret = tr->thread; break; } tr = tr->next; } if (!tr) ret = 0; TQCriticalSection.Leave(); return ret; }
STDMETHODIMP DynamicDisplayItem::RetrieveIconDataAsync( IconExtractParams * theParams, void * theAsyncArg ) { HRESULT aRes = E_FAIL; CComQIPtr<IIconAcceptor> aExtr(myItem); if (aExtr == 0) return aRes; aRes = aExtr->RetrieveIconDataAsync(theParams, theAsyncArg); if ( FAILED(aRes) ) return aRes; gDisplayItemCS.Enter(); aRes = UpdateIconData(HRESULT_CODE(aRes), theParams); gDisplayItemCS.Leave(); return aRes; }
void Ignition::StopAll(const bool cancel, IgniteError* err) { factoryLock.Enter(); if (started) { JniErrorInfo jniErr; SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr)); IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err); if (err->GetCode() == IgniteError::IGNITE_SUCCESS) { ctx.Get()->IgnitionStopAll(cancel, &jniErr); IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err); } } factoryLock.Leave(); }
void OutputFile(LPCTSTR content) { static BOOL bOpened = FALSE; g_fileSection.Enter(); { do { HANDLE hFile = CreateFile(_T("C:\\ods.log"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); if (hFile != INVALID_HANDLE_VALUE) ::SetFilePointer(hFile, 0, NULL, FILE_END); else break; std::string ansiContent = t2a(content); ansiContent += "\r\n"; DWORD dwWritten = 0 ; WriteFile(hFile,(LPBYTE)ansiContent.c_str(), ansiContent.size(),&dwWritten,0); CloseHandle(hFile); } while (FALSE); } g_fileSection.Leave(); }
static void TimerAnswer(MCONTACT hContact, const TalkBot::MessageInfo* info) { DBEVENTINFO ldbei; int size = (int)info->Answer.length() + 1; int bufsize = size; char* msg; bufsize *= sizeof(TCHAR) + 1; msg = new char[bufsize]; if (!WideCharToMultiByte(CP_ACP, 0, info->Answer.c_str(), -1, msg, size, NULL, NULL)) FillMemory(msg, size - 1, '-'); //In case of fault return "----" in ANSI part CopyMemory(msg + size, info->Answer.c_str(), size * 2); CallContactService(hContact, PSS_MESSAGE, PREF_TCHAR, (LPARAM)msg); ZeroMemory(&ldbei, sizeof(ldbei)); ldbei.cbSize = sizeof(ldbei); //FIXME: Error may happen ldbei.cbBlob = bufsize; ldbei.pBlob = (PBYTE)(void*)msg; ldbei.eventType = EVENTTYPE_MESSAGE; ldbei.flags = DBEF_SENT; ldbei.szModule = BOLTUN_NAME; ldbei.timestamp = (DWORD)time(NULL); db_event_add(hContact, &ldbei); bot->AnswerGiven(hContact, *info); delete info; delete [] msg; typingContactsLock.Enter(); typingContacts.erase(hContact); typingContactsLock.Leave(); }
void DynamicDisplayItem::DrawIcon(HDC theDC, bool theSelected, const RECT & theContainer, const Theme * theTheme) { gDisplayItemCS.Enter(); int aIconSite = theTheme->GetMetric(WIDTH_ICONSITE); int aLeftIndent = theTheme->GetMetric(WIDTH_INDENT_LEFT); RECT aRect; aRect.left = theContainer.left + aLeftIndent; aRect.top = theContainer.top + (theContainer.bottom - theContainer.top - aIconSite) / 2; aRect.right = aRect.left + aIconSite; aRect.bottom = aRect.top + aIconSite; DWORD aPrevLayout = GetLayout(theDC); DWORD aNewLayout = aPrevLayout | LAYOUT_BITMAPORIENTATIONPRESERVED; SetLayout(theDC, aNewLayout); int aDrawItemFlags = theSelected ? DIIF_NORMAL : DIIF_SELECTED; if (myIconData.IsIconDimmed) aDrawItemFlags |= DIIF_DIMMED; theTheme->DrawItemIcon(theDC, aDrawItemFlags, aRect, myIconData.ImageList, myIconData.IconIndex); if (myIconData.OverlayIndex != -1) { HIMAGELIST aSmall, aLarge; BOOL aRet = Shell_GetImageLists(&aLarge, &aSmall); if (aRet && aSmall != 0) ImageList_Draw(aSmall, myIconData.OverlayIndex, theDC, aRect.left, aRect.top, ILD_TRANSPARENT); } SetLayout(theDC, aPrevLayout); gDisplayItemCS.Leave(); }
PLUGIN_FUNCTION_ARG2(ReadDTMF, unsigned,line, char *,digit) { if (digit == NULL) return PluginLID_InvalidParameter; if (m_eProductID == TJIP_NONE) return PluginLID_DeviceNotOpen; if (line >= 1) return PluginLID_NoSuchLine; m_KeyMutex.Enter(); if (m_Keys.size() == 0) *digit = '\0'; else { *digit = m_Keys.front(); m_Keys.pop(); } m_KeyMutex.Leave(); return PluginLID_NoError; }
void LispThreadQueue::suspendAllOtherThreads() { DWORD ret = 0; int wait = 1; TQCriticalSection.Enter(); ThreadRecord* tr = list; ThreadRecord* currThread = (ThreadRecord*)TlsGetValue(Thread_Index); while (tr) { if (tr != currThread) { retry_suspend: ret = SuspendThread(tr->thread); if (ret == (DWORD)-1) { Sleep(wait++); goto retry_suspend; } } tr = tr->next; } TQCriticalSection.Leave(); }
Ignite Ignition::Get(const char* name, IgniteError* err) { Ignite res; factoryLock.Enter(); if (started) { char* name0 = CopyChars(name); // 1. Create context for this operation. JniErrorInfo jniErr; SharedPointer<JniContext> ctx(JniContext::Create(NULL, 0, JniHandlers(), &jniErr)); IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err); if (err->GetCode() == IgniteError::IGNITE_SUCCESS) { // 2. Get environment pointer. long long ptr = ctx.Get()->IgnitionEnvironmentPointer(name0, &jniErr); IgniteError::SetError(jniErr.code, jniErr.errCls, jniErr.errMsg, err); if (err->GetCode() == IgniteError::IGNITE_SUCCESS) { if (ptr != 0) { // 3. Obtain real environment for this instance. JniHandlers* hnds = reinterpret_cast<JniHandlers*>(ptr); SharedPointer<IgniteEnvironment>* env = static_cast<SharedPointer<IgniteEnvironment>*>(hnds->target); // 4. Get fresh node reference. jobject ref = ctx.Get()->IgnitionInstance(name0, &jniErr); if (err->GetCode() == IgniteError::IGNITE_SUCCESS) { if (ref) { IgniteImpl* impl = new IgniteImpl(*env, ref); res = Ignite(impl); } else // Error: concurrent node stop. *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Failed to get Ignite instance because it was stopped concurrently."); } } else // Error: no node with the given name. *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Failed to get Ignite instance because it is either not started yet or already stopped."); } } ReleaseChars(name0); } else // Error: no node with the given name. *err = IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Failed to get Ignite instance because it is either not started yet or already stopped."); factoryLock.Leave(); return res; }
// Insert a new instrument assigned to sample nSample or duplicate instrument nDuplicate. // If nSample is invalid, an appropriate sample slot is selected. 0 means "no sample". INSTRUMENTINDEX CModDoc::InsertInstrument(SAMPLEINDEX nSample, INSTRUMENTINDEX nDuplicate) //---------------------------------------------------------------------------------------- { if (m_SndFile.GetModSpecifications().instrumentsMax == 0) return INSTRUMENTINDEX_INVALID; ModInstrument *pDup = nullptr; if ((nDuplicate > 0) && (nDuplicate <= m_SndFile.m_nInstruments)) { pDup = m_SndFile.Instruments[nDuplicate]; } if ((!m_SndFile.GetNumInstruments()) && ((m_SndFile.GetNumSamples() > 1) || (m_SndFile.GetSample(1).pSample))) { if (pDup) return INSTRUMENTINDEX_INVALID; ConfirmAnswer result = Reporting::Confirm("Convert existing samples to instruments first?", true); if (result == cnfCancel) { return INSTRUMENTINDEX_INVALID; } if (result == cnfYes) { if(!ConvertSamplesToInstruments()) { return INSTRUMENTINDEX_INVALID; } } } const INSTRUMENTINDEX newins = m_SndFile.GetNextFreeInstrument(); if(newins == INSTRUMENTINDEX_INVALID) { ErrorBox(IDS_ERR_TOOMANYINS, CMainFrame::GetMainFrame()); return INSTRUMENTINDEX_INVALID; } else if(newins > m_SndFile.GetNumInstruments()) { m_SndFile.m_nInstruments = newins; } // Determine which sample slot to use SAMPLEINDEX newsmp = 0; if (nSample < m_SndFile.GetModSpecifications().samplesMax) { // Use specified slot newsmp = nSample; } else if (!pDup) { newsmp = m_SndFile.GetNextFreeSample(newins); if (newsmp > m_SndFile.GetNumSamples()) { // Add a new sample const SAMPLEINDEX inssmp = InsertSample(); if (inssmp != SAMPLEINDEX_INVALID) newsmp = inssmp; } } CriticalSection cs; ModInstrument *pIns = m_SndFile.AllocateInstrument(newins, newsmp); if(pIns == nullptr) { cs.Leave(); ErrorBox(IDS_ERR_OUTOFMEMORY, CMainFrame::GetMainFrame()); return INSTRUMENTINDEX_INVALID; } InitializeInstrument(pIns); if (pDup) { *pIns = *pDup; } SetModified(); return newins; }
// Base code for adding, removing, moving and duplicating channels. Returns new number of channels on success, CHANNELINDEX_INVALID otherwise. // The new channel vector can contain CHANNELINDEX_INVALID for adding new (empty) channels. CHANNELINDEX CModDoc::ReArrangeChannels(const std::vector<CHANNELINDEX> &newOrder, const bool createUndoPoint) //------------------------------------------------------------------------------------------------------------ { //newOrder[i] tells which current channel should be placed to i:th position in //the new order, or if i is not an index of current channels, then new channel is //added to position i. If index of some current channel is missing from the //newOrder-vector, then the channel gets removed. const CHANNELINDEX nRemainingChannels = static_cast<CHANNELINDEX>(newOrder.size()); if(nRemainingChannels > m_SndFile.GetModSpecifications().channelsMax || nRemainingChannels < m_SndFile.GetModSpecifications().channelsMin) { CString str; str.Format(_T("Can't apply change: Number of channels should be between %u and %u."), m_SndFile.GetModSpecifications().channelsMin, m_SndFile.GetModSpecifications().channelsMax); Reporting::Error(str , "Rearrange Channels"); return CHANNELINDEX_INVALID; } if(m_SndFile.Patterns.Size() == 0) { // Nothing to do return GetNumChannels(); } CriticalSection cs; if(createUndoPoint) { PrepareUndoForAllPatterns(true, "Rearrange Channels"); } for(PATTERNINDEX nPat = 0; nPat < m_SndFile.Patterns.Size(); nPat++) { if(m_SndFile.Patterns.IsValidPat(nPat)) { ModCommand *oldPatData = m_SndFile.Patterns[nPat]; ModCommand *newPatData = CPattern::AllocatePattern(m_SndFile.Patterns[nPat].GetNumRows(), nRemainingChannels); if(!newPatData) { cs.Leave(); Reporting::Error("ERROR: Pattern allocation failed in ReArrangeChannels(...)"); return CHANNELINDEX_INVALID; } ModCommand *tmpdest = newPatData; for(ROWINDEX nRow = 0; nRow < m_SndFile.Patterns[nPat].GetNumRows(); nRow++) //Scrolling rows { for(CHANNELINDEX nChn = 0; nChn < nRemainingChannels; nChn++, tmpdest++) //Scrolling channels. { if(newOrder[nChn] < GetNumChannels()) //Case: getting old channel to the new channel order. *tmpdest = *m_SndFile.Patterns[nPat].GetpModCommand(nRow, newOrder[nChn]); else //Case: figure newOrder[k] is not the index of any current channel, so adding a new channel. *tmpdest = ModCommand::Empty(); } } m_SndFile.Patterns[nPat] = newPatData; CPattern::FreePattern(oldPatData); } } std::vector<ModChannel> chns(MAX_CHANNELS); std::vector<ModChannelSettings> settings(MAX_BASECHANNELS); std::vector<BYTE> recordStates(GetNumChannels(), 0); std::vector<bool> chnMutePendings(GetNumChannels(), false); for(CHANNELINDEX nChn = 0; nChn < GetNumChannels(); nChn++) { settings[nChn] = m_SndFile.ChnSettings[nChn]; chns[nChn] = m_SndFile.m_PlayState.Chn[nChn]; recordStates[nChn] = IsChannelRecord(nChn); chnMutePendings[nChn] = m_SndFile.m_bChannelMuteTogglePending[nChn]; } ReinitRecordState(); for(CHANNELINDEX nChn = 0; nChn < nRemainingChannels; nChn++) { if(newOrder[nChn] < GetNumChannels()) { m_SndFile.ChnSettings[nChn] = settings[newOrder[nChn]]; m_SndFile.m_PlayState.Chn[nChn] = chns[newOrder[nChn]]; if(chns[newOrder[nChn]].nMasterChn > 0 && chns[newOrder[nChn]].nMasterChn <= nRemainingChannels) { m_SndFile.m_PlayState.Chn[nChn].nMasterChn = newOrder[chns[newOrder[nChn]].nMasterChn - 1] + 1; } if(recordStates[newOrder[nChn]] == 1) Record1Channel(nChn, true); if(recordStates[newOrder[nChn]] == 2) Record2Channel(nChn, true); m_SndFile.m_bChannelMuteTogglePending[nChn] = chnMutePendings[newOrder[nChn]]; } else { m_SndFile.InitChannel(nChn); } } // Reset MOD panning (won't affect other module formats) m_SndFile.SetupMODPanning(); m_SndFile.m_nChannels = nRemainingChannels; // Reset removed channels. Most notably, clear the channel name. for(CHANNELINDEX nChn = GetNumChannels(); nChn < MAX_BASECHANNELS; nChn++) { m_SndFile.InitChannel(nChn); } return GetNumChannels(); }
void LispThreadQueue::Unlock() { TQCriticalSection.Leave(); }