Пример #1
0
void GOrgueMidiRecorder::WriteEvent(GOrgueMidiEvent& e)
{
	if (!IsRecording())
		return;
	std::vector<std::vector<unsigned char>> msg;
	e.ToMidi(msg, m_Map);
	for(unsigned i = 0; i < msg.size(); i++)
	{
		EncodeLength((e.GetTime() - m_Last).GetValue());
		if (msg[i][0] == 0xF0)
		{
			Write(&msg[i][0], 1);
			EncodeLength(msg[i].size() - 1);
			Write(&msg[i][1], msg[i].size() - 1);
		}
		else
			Write(&msg[i][0], msg[i].size());
		m_Last = e.GetTime();
	}
}
Пример #2
0
void GOrgueMidiRecorder::StartRecording(bool rename)
{
	MIDIHeaderChunk h = { { { 'M', 'T', 'h', 'd' }, 6 }, 0, 1, 0xE728 };
	MIDIFileHeader t = { { 'M', 'T', 'r', 'k' }, 0 };

	StopRecording();
	if (!m_organfile)
		return;

	m_Filename = m_organfile->GetSettings().MidiRecorderPath() + wxFileName::GetPathSeparator() + wxDateTime::UNow().Format(_("%Y-%m-%d-%H-%M-%S.%l.mid"));
	m_DoRename = rename;

        m_file.Create(m_Filename, true);
        if (!m_file.IsOpened())
	{
		wxLogError(_("Unable to open file %s for writing"), m_Filename.c_str());
		return;
	}
	
	m_FileLength = 0;
	m_BufferPos = 0;
	Write(&h, sizeof(h));
	Write(&t, sizeof(t));

	wxString s = m_organfile->GetChurchName();
	wxCharBuffer b = s.ToAscii();
	unsigned len = s.length();
	unsigned char th[] = { 0x00, 0xFF, 0x04 };
	Write(&th, sizeof(th));
	EncodeLength(len);
	Write(b.data(), len);

	m_Last = wxGetLocalTimeMillis();
	if (m_DoRename)
		m_button[ID_MIDI_RECORDER_RECORD_RENAME]->Display(true);
	else
		m_button[ID_MIDI_RECORDER_RECORD]->Display(true);
	m_organfile->PrepareRecording();

	m_RecordSeconds = 0;
	UpdateDisplay();
	m_organfile->SetRelativeTimer(1000, this, 1000);
}
/**********************************************************************

    caller:     owner of this object

    prototype:

        ANSC_STATUS
        AnscAsn1EnumerateEncodingData
            (
                ANSC_HANDLE                 hThisObject,
                PVOID*                      ppEncoding
            );

    description:

        This function is decoding data for ASN.1 object.

    argument:   ANSC_HANDLE                 hThisObject
                This handle is actually the pointer of this object
                itself.

                PVOID*                      ppEncoding
                The pointer of the output binary data

    return:     status of encoding operation

**********************************************************************/
ANSC_STATUS
AnscAsn1EnumerateEncodingData
    (
        ANSC_HANDLE                 hThisObject,
        PVOID*                      ppEncoding
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PANSC_ASN1_ENUMERATE            pMyObject    = (PANSC_ASN1_ENUMERATE)hThisObject;
    BOOLEAN                         bTagIncluded = TRUE;
    LONG                            uSizeOfEncoded;
    ULONG                           uLeftSize;

    /*
     * hold the computation value
     */
    LONG                            ulResult     = pMyObject->uValue;

    /*
     * shortcut pointer to a char array
     */
    PUCHAR                          pCharData    = (PUCHAR)*ppEncoding;
    PUCHAR                          pBackData    = pCharData;

    /*
     * If it's optional, don't need encode
     */
    if( pMyObject->bOptional)
    {
        return ANSC_STATUS_SUCCESS;
    }

    /*
     *  check before encoding;
     */
    if( pMyObject->BeforeEncoding != NULL)
    {
        returnStatus = pMyObject->BeforeEncoding(pMyObject, ppEncoding);

        if( ANSC_STATUS_SUCCESS != returnStatus)
        {
            return returnStatus;
        }
    }

    uSizeOfEncoded = pMyObject->GetSizeOfEncoded(pMyObject);

    if( uSizeOfEncoded < 0)
    {
        return ANSC_ASN1_NOT_READY_TO_ENCODE;
    }

    /*
     * Encode all attrlist first; 
     */
    returnStatus = 
        AttrListEncodingData
            (
                &pMyObject->sAttrList,
                (PVOID*)&pCharData,
                (ULONG)uSizeOfEncoded,
                pMyObject->IsConstructive(pMyObject),
                &bTagIncluded,
                &uLeftSize
            );

    if( ANSC_STATUS_SUCCESS != returnStatus)
    {
        return returnStatus;
    }

    /*
     *  Encode the tag first;
     */
    if ( bTagIncluded)
    {
        *pCharData              = pMyObject->GetFirstOctet(pMyObject);
        pCharData++;

        EncodeLength((PVOID*)&pCharData, pMyObject->uLength);
    }

    /*
     * we don't have problem if the current encoding is dynamic encoding; 
     * if the current encoding is static, we have to 
     * examine the long value and find out how many octets are needed
     */
    if( pMyObject->bFirstZero)
    {
        *pCharData               = 0x00;
        pCharData++;
    }

    if( ulResult <= 0xFF)
    {       
        *pCharData              = (UCHAR)(ulResult & 0xFF);
        pCharData++;
    }
    else
    {
        pCharData               += ASN1WriteUlong( pCharData, ulResult);
    }

    /*
     *  Set the buffer before exit;
     */
    if( ANSC_STATUS_SUCCESS == returnStatus)
    {
        if( pCharData - pBackData != uSizeOfEncoded)
        {
            /*
            AnscTrace
                (
                    "Warning in Encoding ENUMERATE, the size of encoding is expected to be %d, but it's %d.\n",
                    uSizeOfEncoded,
                    (pCharData - pBackData)
                );
            */
        }

        /*
         *  check after encoding;
         */
        if( pMyObject->AfterEncoding != NULL)
        {
            returnStatus = pMyObject->AfterEncoding(pMyObject, (PVOID*)&pCharData);

            if( ANSC_STATUS_SUCCESS != returnStatus)
            {
                return returnStatus;
            }
        }

        *ppEncoding                     =  (PVOID)pCharData;
    }

    return returnStatus;
}