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(); } }
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; }