Example #1
0
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;
}
Example #2
0
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;
    }
Example #3
0
    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;
    }
Example #4
0
    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();
    }
Example #5
0
// 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);
}
Example #6
0
// 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);
}
Example #7
0
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;
}
Example #8
0
    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;
    }
Example #9
0
void 
LispThreadQueue::insert(ThreadRecord* rec)
{
	TQCriticalSection.Enter();
	rec->next = list;
	list = rec;
	TQCriticalSection.Leave();
}
Example #10
0
static void StartTyping(MCONTACT hContact, const TalkBot::MessageInfo*)
{
	CallService(MS_PROTO_SELFISTYPING, hContact, 
		(LPARAM)PROTOTYPE_SELFTYPING_ON);
	typingContactsLock.Enter();
	typingContacts.insert(hContact);
	typingContactsLock.Leave();
}
Example #11
0
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);
}
Example #12
0
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;
};
Example #14
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();
      }
    }
Example #15
0
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();
}
Example #16
0
//
//	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;
}
Example #17
0
//---------------------------------------------------------------------------
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();
}
Example #18
0
//---------------------------------------------------------------------------
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();
}
Example #19
0
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;
}
Example #20
0
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;
}
Example #21
0
    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();
    }
Example #22
0
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();
}
Example #23
0
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();
}
Example #24
0
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();
}
Example #25
0
    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;
    }
Example #26
0
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();
}
Example #27
0
    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;
    }
Example #28
0
// 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;
}
Example #29
0
// 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();
}
Example #30
0
void LispThreadQueue::Unlock()
{
	TQCriticalSection.Leave();
}