DWORD WINAPI CommMonitor( LPSTR lpData) { CommData SYSTEMTIME SystemTime; int i, nItemCount, nPackType, nTranType, nDataOff,nResultLen; BYTE btCalCheckSum, btRxCheckSum; WORD wSampleNo; WORD wRSampleNo; BYTE btResultType; LPSTR lpPointer; Init() nItemCount =0; ResetOpPointer() FillDevName() PurgeComm( hComm, PURGE_RXCLEAR ); SetCommWaitMask(EV_RXFLAG) while (TRUE) { ResetRxPointer() do { GetInQueueLength(dwReadLength) if(dwReadLength==0 &&dwRxBufferLength==0) { WaitEvent(EV_RXFLAG) GetInQueueLength(dwReadLength) } ReadCommBlock(dwReadLength) if ( dwRxBufferLength>=2) { if( (*(lpRxPointer-2)== ETX) ) break; } }while(TRUE); nPackType = lpOpPointer[c_PackTypeOff]; btResultType =0xff; nItemCount =0; switch (nPackType) { case 'R': break; case 'D': nTranType =lpOpPointer[c_TranTypeOff]; switch (nTranType) { case 'B': break; case 'E': if (lpOpPointer[c_TranTypeOff+1]==ETX) break; default: GetLocalTime(&SystemTime); switch (*(lpOpPointer+c_SampleIdOff)) { case '0': wSampleNo =StrToInt(lpOpPointer+c_SampleIdOff, c_SampleIDLen+1); btResultType =c_TypeSample; break; case '1': wSampleNo =StrToInt(lpOpPointer+c_SampleIdOff, c_SampleIDLen+1); btResultType =c_TypeSample; break; case '2': wSampleNo =StrToInt(lpOpPointer+c_SampleIdOff, c_SampleIDLen+1); btResultType =c_TypeSample; break; case '3': wSampleNo =StrToInt(lpOpPointer+c_SampleIdOff, c_SampleIDLen+1); btResultType =c_TypeSample; break; case 'Q': wRSampleNo =StrToInt(lpOpPointer+c_SampleNoOff, c_SampleIDLen); wSampleNo = wRSampleNo+8100; btResultType =c_TypeQC; break; case 'P': wRSampleNo =StrToInt(lpOpPointer+c_SampleNoOff, c_SampleIDLen); wSampleNo = wRSampleNo+6000; btResultType =c_TypeStat; break; case 'E': wRSampleNo =StrToInt(lpOpPointer+c_SampleNoOff, c_SampleIDLen); wSampleNo = wRSampleNo+4000; btResultType =c_TypeEmergency; break; case 'U': wRSampleNo =StrToInt(lpOpPointer+c_SampleNoOff, c_SampleIDLen); wSampleNo = wRSampleNo+5000; btResultType =c_TypeUrine; break; } } if(btResultType != 0xff) for(nDataOff =c_DataOff; *(lpOpPointer+nDataOff)!=ETX ;) { FillSampleID(nItemCount, wSampleNo) FillItemName(nItemCount, lpOpPointer+nDataOff+c_ItemIDOff, c_ItemIDLen) DeleZero(lpOpPointer, c_ResultLen) FillResult(nItemCount, lpPointer ,nResultLen ) FillDate(nItemCount, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour) FillResultType(nItemCount, btResultType) FillComment(nItemCount, lpOpPointer+nDataOff+c_ErrorCodeOff, c_ErrorCodeLen) //填状态注解 FillErrorCode(nItemCount, c_Reliable) nItemCount++; nDataOff+=c_OneDataLen; } break; } if (nItemCount>0) { (*lpResultProcessRoutine)(lpDevice->nDevNO, OutResult, nItemCount); lpDevice->dwRecordCount+=nItemCount; } ResetRxPointer() PurgeComm( hComm, PURGE_RXCLEAR ); WriteCommChar(ACK) } return TRUE; }
int ExportOGG::Export(AudacityProject *project, int numChannels, const wxString &fName, bool selectionOnly, double t0, double t1, MixerSpec *mixerSpec, const Tags *metadata, int WXUNUSED(subformat)) { double rate = project->GetRate(); const TrackList *tracks = project->GetTracks(); double quality = (gPrefs->Read(wxT("/FileFormats/OggExportQuality"), 50)/(float)100.0); wxLogNull logNo; // temporarily disable wxWidgets error messages int updateResult = eProgressSuccess; int eos = 0; FileIO outFile(fName, FileIO::Output); if (!outFile.IsOpened()) { wxMessageBox(_("Unable to open target file for writing")); return false; } // All the Ogg and Vorbis encoding data ogg_stream_state stream; ogg_page page; ogg_packet packet; vorbis_info info; vorbis_comment comment; vorbis_dsp_state dsp; vorbis_block block; // Encoding setup vorbis_info_init(&info); vorbis_encode_init_vbr(&info, numChannels, int(rate + 0.5), quality); // Retrieve tags if (!FillComment(project, &comment, metadata)) { return false; } // Set up analysis state and auxiliary encoding storage vorbis_analysis_init(&dsp, &info); vorbis_block_init(&dsp, &block); // Set up packet->stream encoder. According to encoder example, // a random serial number makes it more likely that you can make // chained streams with concatenation. srand(time(NULL)); ogg_stream_init(&stream, rand()); // First we need to write the required headers: // 1. The Ogg bitstream header, which contains codec setup params // 2. The Vorbis comment header // 3. The bitstream codebook. // // After we create those our responsibility is complete, libvorbis will // take care of any other ogg bistream constraints (again, according // to the example encoder source) ogg_packet bitstream_header; ogg_packet comment_header; ogg_packet codebook_header; vorbis_analysis_headerout(&dsp, &comment, &bitstream_header, &comment_header, &codebook_header); // Place these headers into the stream ogg_stream_packetin(&stream, &bitstream_header); ogg_stream_packetin(&stream, &comment_header); ogg_stream_packetin(&stream, &codebook_header); // Flushing these headers now guarentees that audio data will // start on a NEW page, which apparently makes streaming easier while (ogg_stream_flush(&stream, &page)) { outFile.Write(page.header, page.header_len); outFile.Write(page.body, page.body_len); } const WaveTrackConstArray waveTracks = tracks->GetWaveTrackConstArray(selectionOnly, false); { auto mixer = CreateMixer(waveTracks, tracks->GetTimeTrack(), t0, t1, numChannels, SAMPLES_PER_RUN, false, rate, floatSample, true, mixerSpec); ProgressDialog progress(wxFileName(fName).GetName(), selectionOnly ? _("Exporting the selected audio as Ogg Vorbis") : _("Exporting the entire project as Ogg Vorbis")); while (updateResult == eProgressSuccess && !eos) { float **vorbis_buffer = vorbis_analysis_buffer(&dsp, SAMPLES_PER_RUN); sampleCount samplesThisRun = mixer->Process(SAMPLES_PER_RUN); if (samplesThisRun == 0) { // Tell the library that we wrote 0 bytes - signalling the end. vorbis_analysis_wrote(&dsp, 0); } else { for (int i = 0; i < numChannels; i++) { float *temp = (float *)mixer->GetBuffer(i); memcpy(vorbis_buffer[i], temp, sizeof(float)*SAMPLES_PER_RUN); } // tell the encoder how many samples we have vorbis_analysis_wrote(&dsp, samplesThisRun); } // I don't understand what this call does, so here is the comment // from the example, verbatim: // // vorbis does some data preanalysis, then divvies up blocks // for more involved (potentially parallel) processing. Get // a single block for encoding now while (vorbis_analysis_blockout(&dsp, &block) == 1) { // analysis, assume we want to use bitrate management vorbis_analysis(&block, NULL); vorbis_bitrate_addblock(&block); while (vorbis_bitrate_flushpacket(&dsp, &packet)) { // add the packet to the bitstream ogg_stream_packetin(&stream, &packet); // From vorbis-tools-1.0/oggenc/encode.c: // If we've gone over a page boundary, we can do actual output, // so do so (for however many pages are available). while (!eos) { int result = ogg_stream_pageout(&stream, &page); if (!result) { break; } outFile.Write(page.header, page.header_len); outFile.Write(page.body, page.body_len); if (ogg_page_eos(&page)) { eos = 1; } } } } updateResult = progress.Update(mixer->MixGetCurrentTime() - t0, t1 - t0); } } ogg_stream_clear(&stream); vorbis_block_clear(&block); vorbis_dsp_clear(&dsp); vorbis_info_clear(&info); vorbis_comment_clear(&comment); outFile.Close(); return updateResult; }