001/* 002 * Software License Agreement 003 * 004 * Copyright (C) Cross The Road Electronics. All rights 005 * reserved. 006 * 007 * Cross The Road Electronics (CTRE) licenses to you the right to 008 * use, publish, and distribute copies of CRF (Cross The Road) firmware files (*.crf) and Software 009 * API Libraries ONLY when in use with Cross The Road Electronics hardware products. 010 * 011 * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT 012 * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT 013 * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A 014 * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL 015 * CROSS THE ROAD ELECTRONICS BE LIABLE FOR ANY INCIDENTAL, SPECIAL, 016 * INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF 017 * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS 018 * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE 019 * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER 020 * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT 021 * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE 022 */ 023package com.ctre.phoenix.music; 024 025import com.ctre.phoenix.ErrorCode; 026import com.ctre.phoenix.motorcontrol.can.TalonFX; 027import java.util.Collection; 028 029/** 030 * An Orchestra is used to play music through Talon FX motor controllers. 031 * It uses a "Chirp" (.chrp) music file that can be generated using Phoenix Tuner. 032 * 033 * Chirp files are generated from standard MIDI files. 034 * Each Talon FX can only play a single track within the music file. 035 * For multi-track files, multiple Talon FXs are needed. 036 * ie, The first track will be played through the first Talon FX added, 037 * the second track will be played through the second Talon FX added, etc. 038 * 039 * Any Chirp file located in the src/main/deploy directory of your FRC project 040 * will automatically be copied to the roboRIO on code deploy. 041 * 042 * To use the Orchestra: 043 * - Add the Talon FXs to be used as instruments 044 * - Load the Chirp file to be played using the loadMusic routine. 045 * Both of these can also be done in the Orchestra constructor. 046 * 047 * Once ready, the Orchestra can be controlled using standard 048 * play/pause/stop routines. 049 * 050 * New music files can be loaded at any time. 051 * 052 * The robot must be enabled to play music. 053 * 054 * Calling set on any of the TalonFX instruments while the orchestra is 055 * playing will pause the orchestra. 056 */ 057public class Orchestra { 058 private long m_handle; 059 060 /** 061 * Constructor for an Orchestra Object. 062 * Call AddInstrument after this to add the instruments. 063 */ 064 public Orchestra() { 065 m_handle = OrchestraJNI.JNI_new_Orchestra(); 066 } 067 /** 068 * Constructor for an Orchestra Object. 069 * @param instruments 070 * A collection of TalonFX's that will be used as instruments 071 * inside the orchestra. 072 */ 073 public Orchestra(Collection<TalonFX> instruments) { 074 this(); 075 076 for(TalonFX instrument : instruments) { 077 addInstrument(instrument); 078 } 079 } 080 /** 081 * Constructor for an Orchestra Object 082 * @param instruments 083 * A collection of TalonFX's that will be used as instruments 084 * inside the orchestra. 085 * @param filePath 086 * The path to the music file to immediately load into 087 * the orchestra. 088 */ 089 public Orchestra(Collection<TalonFX> instruments, String filePath) { 090 this(instruments); 091 092 loadMusic(filePath); 093 } 094 095 /** 096 * Loads a Chirp file at the specified file path. 097 * 098 * If the Chirp file is inside your "src/main/deploy" directory 099 * this file will be automatically deployed to a default directory in 100 * the RoboRIO when you deploy code. For these files, the name and file 101 * extension is sufficient. 102 * 103 * Use Tuner to create a Chirp file. 104 * @param filePath 105 * The path to the Chirp File. 106 * @return Error Code generated by function. 0 indicates no error. 107 */ 108 public ErrorCode loadMusic(String filePath) { 109 int retval = OrchestraJNI.JNI_LoadMusic(m_handle, filePath); 110 return ErrorCode.valueOf(retval); 111 } 112 113 /** 114 * Plays the music file that's loaded. 115 * If the player is paused, this will resume. 116 * This will also resume a song if the orchestra was interrupted. 117 * @return Error Code generated by function. 0 indicates no error. 118 */ 119 public ErrorCode play() { 120 int retval = OrchestraJNI.JNI_Play(m_handle); 121 return ErrorCode.valueOf(retval); 122 } 123 124 /** 125 * Stops the music file that's loaded. 126 * This resets the current position in the track to the start. 127 * @return Error Code generated by function. 0 indicates no error. 128 */ 129 public ErrorCode stop() { 130 int retval = OrchestraJNI.JNI_Stop(m_handle); 131 return ErrorCode.valueOf(retval); 132 } 133 134 /** 135 * Pauses the music file that's loaded. 136 * This saves the current position in the track, so it can be resumed later. 137 * Pausing while stopped is an invalid request. 138 * @return Error Code generated by function. 0 indicates no error. 139 */ 140 public ErrorCode pause() { 141 int retval = OrchestraJNI.JNI_Pause(m_handle); 142 return ErrorCode.valueOf(retval); 143 } 144 145 /** 146 * Returns whether the current track is actively playing or not 147 * @return True if playing, false otherwise 148 */ 149 public boolean isPlaying() { 150 return OrchestraJNI.JNI_IsPlaying(m_handle); 151 } 152 153 /** 154 * @return The current timestamp of the music file (playing or paused) in milliseconds. 155 * The timestamp will reset to zero whenever loadMusic() or stop() is called. 156 * If isPlaying() returns false, this routine can be used to determine if music is stopped or paused. 157 */ 158 public int getCurrentTime() { 159 return OrchestraJNI.JNI_GetCurrentTime(m_handle); 160 } 161 162 /** 163 * Clears all instruments in the orchestra. 164 * @return Error Code generated by function. 0 indicates no error. 165 */ 166 public ErrorCode clearInstruments() { 167 int retval = OrchestraJNI.JNI_ClearInstruments(m_handle); 168 return ErrorCode.valueOf(retval); 169 } 170 171 /** 172 * Adds another instrument to the orchestra. 173 * @param instrument 174 * TalonFX to add to orchestra 175 * @return Error Code generated by function. 0 indicates no error. 176 */ 177 public ErrorCode addInstrument(TalonFX instrument) { 178 int retval = OrchestraJNI.JNI_AddInstrument(m_handle, instrument.getHandle()); 179 return ErrorCode.valueOf(retval); 180 } 181}