// Given the date in the form of days since 2000 return the date in the ISO format long ISODate::DateSince2000(long daysSince2000) { long yearCount; long yearDayCount = 0; // True if the year is a leap year bool isLeapYear = false; // Extract the year part for(yearCount=0; yearCount<MAX_YEARS; yearCount++) { // If this year is a leap year isLeapYear = IsLeapYear(yearCount+2000); // If this year is a leap year if(isLeapYear) { if(yearDayCount + DAYS_PER_LEAP_YEAR > daysSince2000) break; else yearDayCount += (long)DAYS_PER_LEAP_YEAR; } else { if(yearDayCount + DAYS_PER_YEAR > daysSince2000) break; else yearDayCount += (long)DAYS_PER_YEAR; } } // Extract the month part // The number of days since the start of this year long monthDays = daysSince2000 - yearDayCount+1; // The number of months we are looking at long monthCount = 0; // The day of month long monthDayCount = 1; // Loop up through the months till we find the first day greater than the day part for(monthCount = 1; monthCount < 12; monthCount++) { // If the year we are dealing with is a leap year if(isLeapYear) { // If we are going to cross the boundary if(monthDayCount+LEAP_YEAR_MONTH_LENGTH[monthCount] > monthDays) break; else monthDayCount+=LEAP_YEAR_MONTH_LENGTH[monthCount]; } // This isn't a leap year else { // If we are going to cross the boundary if(monthDayCount+NON_LEAP_YEAR_MONTH_LENGTH[monthCount] > monthDays) break; else monthDayCount+=NON_LEAP_YEAR_MONTH_LENGTH[monthCount]; } } // Now extract the day part long dayOfMonth = 0; if(isLeapYear) { dayOfMonth = monthDays - LEAP_YEAR_MONTH_DAYS[monthCount-1]; } else { dayOfMonth = monthDays - NON_LEAP_YEAR_MONTH_DAYS[monthCount-1]; } return ConvertToISO(dayOfMonth,monthCount,yearCount+2000); }
void VorbisLMC::DecodeWork() { void *pOutBuffer; Error Err; int32 iValue; int32 section, ret; OutputInfo *info; vorbis_info *vi; uint32 bytesCopied, bytesPerFrame; int bitrateLoops = 0; assert(m_pPmi); assert(m_pPmo); m_pSleepSem->Wait(); m_pPmi->Wake(); Err = CanDecode(); if (Err == kError_Interrupt) return; if (Err != kError_NoErr) { m_pContext->log->Error("CanDecode returned false.\n"); if (m_decodeInfo.sendInfo) { ReportStatus(szCannotDecode); m_pTarget->AcceptEvent(new Event(INFO_DoneOutputtingDueToError)); } else ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOErrorEvent()); return; } Err = ExtractMediaInfo(); if (Err == kError_Interrupt) return; if (IsError(Err)) { m_pContext->log->Error("ExtractMediaInfo failed: %d\n", Err); if (m_decodeInfo.sendInfo) { ReportStatus(szCannotDecode); m_pTarget->AcceptEvent(new Event(INFO_DoneOutputtingDueToError)); } else ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOErrorEvent()); return; } if (!m_bInit) { Err = InitDecoder(); if (Err == kError_Interrupt) return; if (IsError(Err)) { m_pContext->log->Error("Initializing the decoder failed: %d\n", Err); ReportError("Initializing the decoder failed."); return; } } m_pContext->prefs->GetPrefInt32(kDecoderThreadPriorityPref, &iValue); m_decoderThread->SetPriority(iValue); bytesCopied = 0; bytesPerFrame = 1; for (m_frameCounter = 0; !m_bExit;) { if (m_bPause) { m_pPauseSem->Wait(); if (m_bExit) break; } if (m_newPos >= 0) { ov_time_seek(&m_vf, (double)(m_newPos / iFramesPerSecond)); m_frameCounter = m_newPos - 1; m_newPos = -1; bytesCopied = bytesPerFrame; } if (bytesCopied >= bytesPerFrame) { m_frameCounter += bytesCopied / bytesPerFrame; bytesCopied %= bytesPerFrame; ((EventBuffer *)m_pOutputBuffer)->AcceptEvent( new PMOTimeInfoEvent(m_frameCounter)); bitrateLoops++; if (bitrateLoops == iBitrateLoopsPerUpdate && m_decodeInfo.sendInfo) { int b; b = ov_bitrate_instant(&m_vf), vi = ov_info(&m_vf, -1); VorbisInfoEvent *mie = new VorbisInfoEvent(b, vi->channels, vi->rate, 1. / (float)iFramesPerSecond); m_pTarget->AcceptEvent(mie); bitrateLoops = 0; } } Err = m_pOutputBuffer->BeginWrite(pOutBuffer, iDecodeBlockSize); if (Err == kError_Interrupt) { break; } if (Err == kError_BufferTooSmall) { if (Sleep()) break; continue; } if (Err != kError_NoErr) { ReportError(szFailWrite); m_pContext->log->Error("LMC: Cannot write to eventbuffer: %s (%d)\n", m_szError, Err); break; } section = -1; ret = ov_read(&m_vf, (char *)pOutBuffer, iDecodeBlockSize, 0, 2, 1, §ion); if (ret == 0) { m_pOutputBuffer->EndWrite(0); break; } if (section != m_section) { vi = ov_info(&m_vf, -1); info = new OutputInfo; info->bits_per_sample = 16; info->number_of_channels = m_channels = vi->channels; info->samples_per_second = m_rate = vi->rate; info->samples_per_frame = vi->rate / iFramesPerSecond; info->max_buffer_size = 16384; m_frameCounter = 0; bytesCopied = 0; bytesPerFrame = (vi->rate / iFramesPerSecond) * sizeof(ogg_int16_t) * vi->channels; m_section = section; m_pOutputBuffer->EndWrite(0); ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOInitEvent(info)); ((EventBuffer *)m_pOutputBuffer)->AcceptEvent( new PMOTimeInfoEvent(m_frameCounter)); Err = m_pOutputBuffer->BeginWrite(pOutBuffer, iDecodeBlockSize); if (Err != kError_NoErr) { assert(0); } vorbis_comment *comment; comment = ov_comment(&m_vf, -1); if (comment) { PlaylistItem *plItem = m_pContext->plm->GetCurrentItem(); if (plItem) { MetaData mdata = plItem->GetMetaData(); string iso; char *temp; temp = vorbis_comment_query(comment, "title", 0); if (temp) { iso = ConvertToISO(temp); mdata.SetTitle(iso); } temp = vorbis_comment_query(comment, "artist", 0); if (temp) { iso = ConvertToISO(temp); mdata.SetArtist(iso); } temp = vorbis_comment_query(comment, "album", 0); if (temp) { iso = ConvertToISO(temp); mdata.SetAlbum(iso); } temp = vorbis_comment_query(comment, "tracknumber", 0); if (temp) mdata.SetTrack(atoi(temp)); plItem->SetMetaData(&mdata); m_pContext->target->AcceptEvent( new PlaylistCurrentItemInfoEvent(plItem, m_pContext->plm)); } } } if(ret <0) ret=0; // hole/error in data - we can safely ignore this m_pOutputBuffer->EndWrite(ret); bytesCopied += ret; } ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOQuitEvent()); ov_clear(&m_vf); return; }