/** Peek into the parentInput's input stream and if the next item * is a NIFF stem, return a new Stem. Otherwise, * return null and leave the input stream unchanged. * * @param parentInput the parent RIFF object being used to read the input stream */ public static Stem maybeNew(Riff parentInput) { if (!parentInput.peekFOURCC().Equals(RIFF_ID)) return null; return newInstance(parentInput); }
/** Peek into the parentInput's input stream and if the next item * is a NIFF String Table, then decode it and store it in the * root RIFFForNIFF object. * If the next item is not a NIFF String Table, do nothing * and leave the input stream unchanged. * * @param parentInput the parent RIFF object being used to read the input stream. * If parentInput.getParent() is not of type RIFFForNIFF, then this * moves the input past the String Table but does not store it. * @return true if the String Table was processed, false if this is * not a String Table. */ static public bool maybeDecode(Riff parentInput) { if (!parentInput.peekFOURCC().Equals(RIFF_ID)) { return(false); } Riff riffInput = new Riff(parentInput, RIFF_ID); if (!(parentInput.getParent() is RiffForNiff)) { // There is no place to store the data riffInput.skipRemaining(); return(true); } RiffForNiff riffForNiff = (RiffForNiff)parentInput.getParent(); // Read the entire string table into a byte array byte[] stringTable = new byte[riffInput.getBytesRemaining()]; for (int i = 0; i < stringTable.Length; ++i) { stringTable[i] = (byte)riffInput.readBYTE(); } riffForNiff.setStringTable(stringTable); // This skips possible pad byte riffInput.skipRemaining(); return(true); }
/** Peek into the parentInput's input stream and if the next item * is a NIFF rest, return a new Rest. Otherwise, * return null and leave the input stream unchanged. * * @param parentInput the parent RIFF object being used to read the input stream */ static public Rest maybeNew(Riff parentInput) { if (!parentInput.peekFOURCC().Equals(RIFF_ID)) { return(null); } return(newInstance(parentInput)); }
/** Peek into the parentInput's input stream and if the next item * is a NIFF time slice with any type other than MEASURE_START (presumably * type EVENT), return a new TimeSlice. Otherwise, * return null and leave the input stream unchanged. * * @param parentInput the parent RIFF object being used to read the input stream */ public static TimeSlice maybeNew(Riff parentInput) { if (!parentInput.peekFOURCC().Equals(RIFF_ID)) return null; // We must also ensure that this is not a MEASURE_START time slice if (parentInput.peekFirstChunkBYTE() == MEASURE_START) return null; return newInstance(parentInput); }
/** Peek into the parentInput's input stream and if the next item * is a NIFF time slice with type MEASURE_START, return a new * MeasureStartTimeSlice. Otherwise, * return null and leave the input stream unchanged. * * @param parentInput the parent RIFF object being used to read the input stream */ static public MeasureStartTimeSlice maybeNew(Riff parentInput) { if (!parentInput.peekFOURCC().Equals(RIFF_ID)) { return(null); } // We must also ensure that this is a MEASURE_START time slice if (parentInput.peekFirstChunkBYTE() != MEASURE_START) { return(null); } return(newInstance(parentInput)); }
/** This reads event TimeSlice chunks from parentInput's input stream until the next * measure start time slice or no more bytesRemaining in the parentInput, * adding the TimeSlice objects to the measureStart's time slice list. * When this reads the TimeSlice, it also adds the subsequent music * symbols to it. * * @param parentInput the parent RIFF object being used to read the input stream * @param measureStart the MeasureStartTimeSlice to which TimeSlice * objects are added. * @see TimeSlice */ public static void addTimeSlices(Riff parentInput, MeasureStartTimeSlice measureStart) { if (parentInput.getBytesRemaining() <= 0) // This is a measure start time slice with nothing after it in the staff return; if (parentInput.peekFOURCC().Equals(RIFF_ID) && parentInput.peekFirstChunkBYTE() == MEASURE_START) // The next chunk is already the start of a new measure return; TimeSlice timeSlice = RiffTimeSlice.maybeNew(parentInput); if (timeSlice == null) // For some reason, the first chunk after the measure start // time slice is not an event time slice. Create a fake one with // start time of 0/1. // DEBUG: should mock up an input file and test this. timeSlice = new TimeSlice(new Rational(0, 1), null); while (true) { if (measureStart.getTimeSliceCount() > 0 && measureStart.getTimeSlice (measureStart.getTimeSliceCount() - 1).getStartTime().Equals (timeSlice.getStartTime())) // This new time slice start time is the same as the last one, // so just continue using the last one. // DEBUG: this still doesn't ensure increasing order // DEBUG: This discards the tags in the newly read time slice timeSlice = measureStart.getTimeSlice(measureStart.getTimeSliceCount() - 1); else measureStart.addTimeSlice(timeSlice); // Read music symbols until the next time slice or // end of the staff. RiffTimeSlice.addMusicSymbols(parentInput, timeSlice); if (parentInput.getBytesRemaining() <= 0) // reached the end of the staff break; // We know the next chunk is a time slice. Check whether it is // a measure start. if (parentInput.peekFirstChunkBYTE() == MEASURE_START) // The next chunk is the start of a new measure break; // We have now ensured that the next chunk is an event time slice. timeSlice = RiffTimeSlice.newInstance(parentInput); } }
/** This reads chunks from parentInput's input stream until the next * NIFF time slice or no more bytesRemaining in the input, * adding the chunks to the timeSlice's music symbol list. If a music * symbol is not recognized, this skips it. * This stops at either a measure start or an event time slice. * * @param parentInput the parent RIFF object being used to read the input stream * @param timeSlice the TimeSlice to which MusicSymbol objects are added. * @see MusicSymbol */ public static void addMusicSymbols(Riff parentInput, TimeSlice timeSlice) { while (parentInput.getBytesRemaining() > 0) { if (parentInput.peekFOURCC().Equals(RIFF_ID)) // encoutered the next time slice, so quit // Note that this stops at either a measure start or an event time slice. return; MusicSymbol musicSymbol = maybeNewAnyMusicSymbol(parentInput); if (musicSymbol != null) timeSlice.addMusicSymbol(musicSymbol); else // Did not recognize the music symbol, so skip parentInput.skipChunk(); } }
/** This reads chunks from parentInput's input stream until the next * NIFF time slice or no more bytesRemaining in the input, * adding the chunks to the timeSlice's music symbol list. If a music * symbol is not recognized, this skips it. * This stops at either a measure start or an event time slice. * * @param parentInput the parent RIFF object being used to read the input stream * @param timeSlice the TimeSlice to which MusicSymbol objects are added. * @see MusicSymbol */ static public void addMusicSymbols(Riff parentInput, TimeSlice timeSlice) { while (parentInput.getBytesRemaining() > 0) { if (parentInput.peekFOURCC().Equals(RIFF_ID)) { // encoutered the next time slice, so quit // Note that this stops at either a measure start or an event time slice. return; } MusicSymbol musicSymbol = maybeNewAnyMusicSymbol(parentInput); if (musicSymbol != null) { timeSlice.addMusicSymbol(musicSymbol); } else { // Did not recognize the music symbol, so skip parentInput.skipChunk(); } } }
/** This reads event TimeSlice chunks from parentInput's input stream until the next * measure start time slice or no more bytesRemaining in the parentInput, * adding the TimeSlice objects to the measureStart's time slice list. * When this reads the TimeSlice, it also adds the subsequent music * symbols to it. * * @param parentInput the parent RIFF object being used to read the input stream * @param measureStart the MeasureStartTimeSlice to which TimeSlice * objects are added. * @see TimeSlice */ static public void addTimeSlices (Riff parentInput, MeasureStartTimeSlice measureStart) { if (parentInput.getBytesRemaining() <= 0) { // This is a measure start time slice with nothing after it in the staff return; } if (parentInput.peekFOURCC().Equals(RIFF_ID) && parentInput.peekFirstChunkBYTE() == MEASURE_START) { // The next chunk is already the start of a new measure return; } TimeSlice timeSlice = RiffTimeSlice.maybeNew(parentInput); if (timeSlice == null) { // For some reason, the first chunk after the measure start // time slice is not an event time slice. Create a fake one with // start time of 0/1. // DEBUG: should mock up an input file and test this. timeSlice = new TimeSlice(new Rational(0, 1), null); } while (true) { if (measureStart.getTimeSliceCount() > 0 && measureStart.getTimeSlice (measureStart.getTimeSliceCount() - 1).getStartTime().Equals (timeSlice.getStartTime())) { // This new time slice start time is the same as the last one, // so just continue using the last one. // DEBUG: this still doesn't ensure increasing order // DEBUG: This discards the tags in the newly read time slice timeSlice = measureStart.getTimeSlice(measureStart.getTimeSliceCount() - 1); } else { measureStart.addTimeSlice(timeSlice); } // Read music symbols until the next time slice or // end of the staff. RiffTimeSlice.addMusicSymbols(parentInput, timeSlice); if (parentInput.getBytesRemaining() <= 0) { // reached the end of the staff break; } // We know the next chunk is a time slice. Check whether it is // a measure start. if (parentInput.peekFirstChunkBYTE() == MEASURE_START) { // The next chunk is the start of a new measure break; } // We have now ensured that the next chunk is an event time slice. timeSlice = RiffTimeSlice.newInstance(parentInput); } }
/** Peek into the parentInput's input stream and if the next item * is a NIFF String Table, then decode it and store it in the * root RIFFForNIFF object. * If the next item is not a NIFF String Table, do nothing * and leave the input stream unchanged. * * @param parentInput the parent RIFF object being used to read the input stream. * If parentInput.getParent() is not of type RIFFForNIFF, then this * moves the input past the String Table but does not store it. * @return true if the String Table was processed, false if this is * not a String Table. */ public static bool maybeDecode(Riff parentInput) { if (!parentInput.peekFOURCC().Equals(RIFF_ID)) return false; Riff riffInput = new Riff(parentInput, RIFF_ID); if (!(parentInput.getParent() is RiffForNiff)) { // There is no place to store the data riffInput.skipRemaining(); return true; } RiffForNiff riffForNiff = (RiffForNiff)parentInput.getParent(); // Read the entire string table into a byte array byte[] stringTable = new byte[riffInput.getBytesRemaining()]; for (int i = 0; i < stringTable.Length; ++i) stringTable[i] = (byte)riffInput.readBYTE(); riffForNiff.setStringTable(stringTable); // This skips possible pad byte riffInput.skipRemaining(); return true; }