コード例 #1
0
void CMidiFile::WriteHeader(short Tracks, short PPQ, double Tempo, const TIME_SIGNATURE* TimeSig, const KEY_SIGNATURE* KeySig)
{
	// write file header
	UINT	ChunkID = MAKEFOURCC('M', 'T', 'h', 'd');	// header chunk ID
	Write(&ChunkID, sizeof(ChunkID));	// write chunk ID
	WriteInt(FILE_HEADER_LEN);	// write chunk size
	WriteShort(MF_MULTI);	// write MIDI file format
	WriteShort(Tracks + 1);	// write track count; one extra for song track
	WriteShort(PPQ);	// write pulses per quarter note
	// write song track
	FILE_POS	StartPos = BeginTrack();	// write track header
	if (Tempo > 0) {	// if tempo specified
		WriteMeta(ME_SET_TEMPO, TEMPO_LEN);	// write meta header
		int	mspq = round(60000000 / Tempo);	 // microseconds per quarter note
		BYTE	TempoBuf[TEMPO_LEN];
		Reverse(TempoBuf, &mspq, TEMPO_LEN);	// convert tempo to big endian
		Write(TempoBuf, TEMPO_LEN);	// write tempo
	}
	if (TimeSig != NULL) {	// if time signature specified
		WriteMeta(ME_TIME_SIGNATURE, TIME_SIG_LEN);	// write meta header
		Write(TimeSig, TIME_SIG_LEN);	// write time signature
	}
	if (KeySig != NULL) {	// if key signature specified
		WriteMeta(ME_KEY_SIGNATURE, KEY_SIG_LEN);	// write meta header
		Write(KeySig, KEY_SIG_LEN);	// write key signature
	}
	EndTrack(StartPos);	// finish track and fix header
}
コード例 #2
0
void CMidiFile::WriteTrack(const CMidiEventArray& Event, LPCTSTR Name)
{
	static bool	HasP2[8] = {1, 1, 1, 1, 0, 0, 1, 1};
	FILE_POS	StartPos = BeginTrack();	// write track header
	USES_CONVERSION;
	if (Name != NULL) {	// if track name specified
		int	len = UINT64TO32(_tcslen(Name));
		if (len) {	// if track name has non-zero length
			WriteMeta(ME_TRACK_NAME, len);	// write meta header
			Write(T2CA(Name), len);	// write track name
		}
	}
	BYTE	RunningStatus = 0;	// init running status
	int	nEvents = Event.GetSize();
	for (int iEvent = 0; iEvent < nEvents; iEvent++) {	// for each event
		const MIDI_EVENT&	ev = Event[iEvent];
		WriteVarLen(ev.DeltaT);	// write variable-length delta time
		BYTE	status = MIDI_STAT(ev.Msg);	// get message status
		if (status != RunningStatus) {	// if status changed
			WriteByte(status);
			RunningStatus = status;
		}
		WriteByte(MIDI_P1(ev.Msg));	// write message 1st parameter
		if (HasP2[(status >> 4) - 8])	// if message has 2nd parameter
			WriteByte(MIDI_P2(ev.Msg));	// write message 2nd parameter
	}
	EndTrack(StartPos);	// finish track and fix header
}
コード例 #3
0
void
RemoteSourceStreamInfo::DetachMedia_m()
{
  for (auto& webrtcIdAndTrack : mTracks) {
    EndTrack(mMediaStream->GetInputStream(), webrtcIdAndTrack.second);
  }
  SourceStreamInfo::DetachMedia_m();
}
コード例 #4
0
void
RemoteSourceStreamInfo::RemoveTrack(const std::string& trackId)
{
  auto it = mTracks.find(trackId);
  if (it != mTracks.end()) {
    EndTrack(mMediaStream->GetInputStream(), it->second);
  }

  SourceStreamInfo::RemoveTrack(trackId);
}
コード例 #5
0
 void TrackUnionStream::RemoveInput(MediaInputPort* aPort)
 {
   for (int32_t i = mTrackMap.Length() - 1; i >= 0; --i) {
     if (mTrackMap[i].mInputPort == aPort) {
       EndTrack(i);
       mTrackMap.RemoveElementAt(i);
     }
   }
   ProcessedMediaStream::RemoveInput(aPort);
 }
コード例 #6
0
void TrackUnionStream::RemoveInput(MediaInputPort* aPort)
{
    STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p removing input %p", this, aPort));
    for (int32_t i = mTrackMap.Length() - 1; i >= 0; --i) {
        if (mTrackMap[i].mInputPort == aPort) {
            STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p removing trackmap entry %d", this, i));
            EndTrack(i);
            mTrackMap.RemoveElementAt(i);
        }
    }
    ProcessedMediaStream::RemoveInput(aPort);
}
コード例 #7
0
 void TrackUnionStream::RemoveInput(MediaInputPort* aPort)
 {
   STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p removing input %p", this, aPort));
   for (int32_t i = mTrackMap.Length() - 1; i >= 0; --i) {
     if (mTrackMap[i].mInputPort == aPort) {
       STREAM_LOG(LogLevel::Debug, ("TrackUnionStream %p removing trackmap entry %d", this, i));
       EndTrack(i);
       for (auto listener : mTrackMap[i].mOwnedDirectListeners) {
         // Remove listeners while the entry still exists.
         RemoveDirectTrackListenerImpl(listener, mTrackMap[i].mOutputTrackID);
       }
       mTrackMap.RemoveElementAt(i);
     }
   }
   ProcessedMediaStream::RemoveInput(aPort);
 }
コード例 #8
0
 void TrackUnionStream::ProcessInput(GraphTime aFrom, GraphTime aTo, uint32_t aFlags)
 {
   if (IsFinishedOnGraphThread()) {
     return;
   }
   nsAutoTArray<bool,8> mappedTracksFinished;
   nsAutoTArray<bool,8> mappedTracksWithMatchingInputTracks;
   for (uint32_t i = 0; i < mTrackMap.Length(); ++i) {
     mappedTracksFinished.AppendElement(true);
     mappedTracksWithMatchingInputTracks.AppendElement(false);
   }
   bool allFinished = !mInputs.IsEmpty();
   bool allHaveCurrentData = !mInputs.IsEmpty();
   for (uint32_t i = 0; i < mInputs.Length(); ++i) {
     MediaStream* stream = mInputs[i]->GetSource();
     if (!stream->IsFinishedOnGraphThread()) {
       // XXX we really should check whether 'stream' has finished within time aTo,
       // not just that it's finishing when all its queued data eventually runs
       // out.
       allFinished = false;
     }
     if (!stream->HasCurrentData()) {
       allHaveCurrentData = false;
     }
     bool trackAdded = false;
     for (StreamBuffer::TrackIter tracks(stream->GetStreamBuffer());
          !tracks.IsEnded(); tracks.Next()) {
       bool found = false;
       for (uint32_t j = 0; j < mTrackMap.Length(); ++j) {
         TrackMapEntry* map = &mTrackMap[j];
         if (map->mInputPort == mInputs[i] && map->mInputTrackID == tracks->GetID()) {
           bool trackFinished;
           StreamBuffer::Track* outputTrack = mBuffer.FindTrack(map->mOutputTrackID);
           if (!outputTrack || outputTrack->IsEnded()) {
             trackFinished = true;
           } else {
             CopyTrackData(tracks.get(), j, aFrom, aTo, &trackFinished);
           }
           mappedTracksFinished[j] = trackFinished;
           mappedTracksWithMatchingInputTracks[j] = true;
           found = true;
           break;
         }
       }
       if (!found && (!mFilterCallback || mFilterCallback(tracks.get()))) {
         bool trackFinished = false;
         trackAdded = true;
         uint32_t mapIndex = AddTrack(mInputs[i], tracks.get(), aFrom);
         CopyTrackData(tracks.get(), mapIndex, aFrom, aTo, &trackFinished);
         mappedTracksFinished.AppendElement(trackFinished);
         mappedTracksWithMatchingInputTracks.AppendElement(true);
       }
     }
     if (trackAdded) {
       for (MediaStreamListener* l : mListeners) {
         l->NotifyFinishedTrackCreation(Graph());
       }
     }
   }
   for (int32_t i = mTrackMap.Length() - 1; i >= 0; --i) {
     if (mappedTracksFinished[i]) {
       EndTrack(i);
     } else {
       allFinished = false;
     }
     if (!mappedTracksWithMatchingInputTracks[i]) {
       mTrackMap.RemoveElementAt(i);
     }
   }
   if (allFinished && mAutofinish && (aFlags & ALLOW_FINISH)) {
     // All streams have finished and won't add any more tracks, and
     // all our tracks have actually finished and been removed from our map,
     // so we're finished now.
     FinishOnGraphThread();
   } else {
     mBuffer.AdvanceKnownTracksTime(GraphTimeToStreamTime(aTo));
   }
   if (allHaveCurrentData) {
     // We can make progress if we're not blocked
     mHasCurrentData = true;
   }
 }
コード例 #9
0
ファイル: TrackUnionStream.cpp プロジェクト: Noctem/gecko-dev
void TrackUnionStream::ProcessInput(GraphTime aFrom, GraphTime aTo,
                                    uint32_t aFlags) {
  TRACE_AUDIO_CALLBACK_COMMENT("TrackUnionStream %p", this);
  if (IsFinishedOnGraphThread()) {
    return;
  }
  AutoTArray<bool, 8> mappedTracksFinished;
  AutoTArray<bool, 8> mappedTracksWithMatchingInputTracks;
  for (uint32_t i = 0; i < mTrackMap.Length(); ++i) {
    mappedTracksFinished.AppendElement(true);
    mappedTracksWithMatchingInputTracks.AppendElement(false);
  }

  AutoTArray<MediaInputPort*, 32> inputs(mInputs);
  inputs.AppendElements(mSuspendedInputs);

  bool allFinished = !inputs.IsEmpty();
  bool allHaveCurrentData = !inputs.IsEmpty();
  for (uint32_t i = 0; i < inputs.Length(); ++i) {
    MediaStream* stream = inputs[i]->GetSource();
    if (!stream->IsFinishedOnGraphThread()) {
      // XXX we really should check whether 'stream' has finished within time
      // aTo, not just that it's finishing when all its queued data eventually
      // runs out.
      allFinished = false;
    }
    if (!stream->HasCurrentData()) {
      allHaveCurrentData = false;
    }
    for (StreamTracks::TrackIter tracks(stream->GetStreamTracks());
         !tracks.IsEnded(); tracks.Next()) {
      bool found = false;
      for (uint32_t j = 0; j < mTrackMap.Length(); ++j) {
        TrackMapEntry* map = &mTrackMap[j];
        if (map->mInputPort == inputs[i] &&
            map->mInputTrackID == tracks->GetID()) {
          bool trackFinished = false;
          StreamTracks::Track* outputTrack =
              mTracks.FindTrack(map->mOutputTrackID);
          found = true;
          if (!outputTrack || outputTrack->IsEnded() ||
              !inputs[i]->PassTrackThrough(tracks->GetID())) {
            trackFinished = true;
          } else {
            CopyTrackData(tracks.get(), j, aFrom, aTo, &trackFinished);
          }
          mappedTracksFinished[j] = trackFinished;
          mappedTracksWithMatchingInputTracks[j] = true;
          break;
        }
      }
      if (!found && inputs[i]->AllowCreationOf(tracks->GetID())) {
        bool trackFinished = false;
        uint32_t mapIndex = AddTrack(inputs[i], tracks.get(), aFrom);
        CopyTrackData(tracks.get(), mapIndex, aFrom, aTo, &trackFinished);
        mappedTracksFinished.AppendElement(trackFinished);
        mappedTracksWithMatchingInputTracks.AppendElement(true);
      }
    }
  }
  for (int32_t i = mTrackMap.Length() - 1; i >= 0; --i) {
    if (mappedTracksFinished[i]) {
      EndTrack(i);
    } else {
      allFinished = false;
    }
    if (!mappedTracksWithMatchingInputTracks[i]) {
      for (auto listener : mTrackMap[i].mOwnedDirectListeners) {
        // Remove listeners while the entry still exists.
        RemoveDirectTrackListenerImpl(listener, mTrackMap[i].mOutputTrackID);
      }
      mTrackMap.RemoveElementAt(i);
    }
  }
  if (allFinished && mAutofinish && (aFlags & ALLOW_FINISH)) {
    // All streams have finished and won't add any more tracks, and
    // all our tracks have actually finished and been removed from our map,
    // so we're finished now.
    FinishOnGraphThread();
  }
  if (allHaveCurrentData) {
    // We can make progress if we're not blocked
    mHasCurrentData = true;
  }
}