001 package com.croftsoft.apps.midi; 002 003 import java.applet.*; 004 import java.awt.*; 005 import java.awt.event.*; 006 import java.awt.geom.*; 007 import java.io.*; 008 import java.net.URL; 009 import java.util.*; 010 import javax.sound.midi.*; 011 import javax.swing.*; 012 import javax.swing.event.*; 013 014 import com.croftsoft.core.animation.*; 015 import com.croftsoft.core.animation.animator.*; 016 import com.croftsoft.core.animation.painter.*; 017 import com.croftsoft.core.io.SerializableLib; 018 import com.croftsoft.core.jnlp.JnlpLib; 019 import com.croftsoft.core.lang.lifecycle.*; 020 021 /********************************************************************* 022 * MIDI demo. 023 * 024 * @version 025 * 2003-04-12 026 * @since 027 * 2003-04-12 028 * @author 029 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 030 *********************************************************************/ 031 032 public final class Main 033 extends AnimatedApplet 034 ////////////////////////////////////////////////////////////////////// 035 ////////////////////////////////////////////////////////////////////// 036 { 037 038 private static final String VERSION 039 = "2003-04-12"; 040 041 private static final String TITLE 042 = "CroftSoft MIDI"; 043 044 private static final String APPLET_INFO 045 = "\n" + TITLE + "\n" 046 + "Copyright 2003 CroftSoft Inc\n" 047 + "https://www.croftsoft.com/\n" 048 + "Version " + VERSION + "\n" 049 + "Licensed under the Academic Free License version 1.2\n"; 050 051 ////////////////////////////////////////////////////////////////////// 052 // frame constants 053 ////////////////////////////////////////////////////////////////////// 054 055 private static final String FRAME_TITLE 056 = TITLE; 057 058 private static final String FRAME_ICON_FILENAME 059 = "/images/croftsoft.png"; 060 061 private static final Dimension FRAME_SIZE 062 = null; 063 064 private static final String SHUTDOWN_CONFIRMATION_PROMPT 065 = "Close " + TITLE + "?"; 066 067 ////////////////////////////////////////////////////////////////////// 068 // animation constants 069 ////////////////////////////////////////////////////////////////////// 070 071 /** frames per second */ 072 private static final double FRAME_RATE = 30.0; 073 074 private static final Color BACKGROUND_COLOR 075 = Color.BLACK; 076 077 private static final Color FOREGROUND_COLOR 078 = Color.BLUE; 079 080 private static final Font FONT 081 = new Font ( "Arioso", Font.BOLD, 20 ); 082 083 private static final Cursor CURSOR 084 = new Cursor ( Cursor.CROSSHAIR_CURSOR ); 085 086 private static final long DELAY = 2000; 087 088 private static int DELTA_X = 1; 089 090 private static int DELTA_Y = 1; 091 092 private static String SOUNDBANK_URL_NAME 093 = "http://java.sun.com/products/java-media/sound/soundbanks.html"; 094 095 ////////////////////////////////////////////////////////////////////// 096 // persistence constants 097 ////////////////////////////////////////////////////////////////////// 098 099 100 ////////////////////////////////////////////////////////////////////// 101 // instance variables 102 ////////////////////////////////////////////////////////////////////// 103 104 private Sequencer sequencer; 105 106 private Synthesizer synthesizer; 107 108 private Instrument [ ] instruments; 109 110 private MidiChannel [ ] midiChannels; 111 112 private int noteNumber; 113 114 private long previousTime; 115 116 private boolean noteOn; 117 118 private TextAnimator textAnimator; 119 120 private Random random; 121 122 private boolean started; 123 124 ////////////////////////////////////////////////////////////////////// 125 ////////////////////////////////////////////////////////////////////// 126 127 public static void main ( String [ ] args ) 128 ////////////////////////////////////////////////////////////////////// 129 { 130 if ( args.length < 1 ) 131 { 132 launch ( new Main ( ) ); 133 134 return; 135 } 136 137 // Test of playing a MIDI file using AudioClip 138 139 AudioClip audioClip = Applet.newAudioClip ( 140 Main.class.getClassLoader ( ).getResource ( args [ 0 ] ) ); 141 142 audioClip.loop ( ); 143 } 144 145 private static AnimationInit createAnimationInit ( ) 146 ////////////////////////////////////////////////////////////////////// 147 { 148 AnimationInit animationInit = new AnimationInit ( ); 149 150 animationInit.setAppletInfo ( APPLET_INFO ); 151 152 animationInit.setForegroundColor ( BACKGROUND_COLOR ); 153 154 animationInit.setCursor ( CURSOR ); 155 156 animationInit.setFont ( FONT ); 157 158 animationInit.setForegroundColor ( FOREGROUND_COLOR ); 159 160 animationInit.setFrameIconFilename ( FRAME_ICON_FILENAME ); 161 162 animationInit.setFrameSize ( FRAME_SIZE ); 163 164 animationInit.setFrameTitle ( FRAME_TITLE ); 165 166 animationInit.setShutdownConfirmationPrompt ( 167 SHUTDOWN_CONFIRMATION_PROMPT ); 168 169 return animationInit; 170 } 171 172 ////////////////////////////////////////////////////////////////////// 173 ////////////////////////////////////////////////////////////////////// 174 175 public Main ( ) 176 ////////////////////////////////////////////////////////////////////// 177 { 178 super ( createAnimationInit ( ) ); 179 } 180 181 ////////////////////////////////////////////////////////////////////// 182 // interface Lifecycle methods 183 ////////////////////////////////////////////////////////////////////// 184 185 public void init ( ) 186 ////////////////////////////////////////////////////////////////////// 187 { 188 super.init ( ); 189 190 // persistent data 191 192 /* 193 try 194 { 195 userData = ( UserData ) SerializableLib.load ( 196 LATEST_FILENAME, 197 BACKUP_FILENAME, 198 FILE_CONTENTS_SPEC, 199 ( Applet ) this, 200 PERSISTENCE_KEY, 201 getClass ( ).getClassLoader ( ), 202 RESOURCE_PATH_FILENAME ); 203 } 204 catch ( Exception ex ) 205 { 206 ex.printStackTrace ( ); 207 } 208 209 if ( userData == null ) 210 { 211 userData = new UserData ( ); 212 } 213 */ 214 addComponentPainter ( new ColorPainter ( BACKGROUND_COLOR ) ); 215 216 textAnimator = new TextAnimator ( ); 217 218 textAnimator.setText ( TITLE ); 219 220 textAnimator.setDeltaX ( DELTA_X ); 221 222 textAnimator.setDeltaY ( DELTA_Y ); 223 224 addComponentAnimator ( textAnimator ); 225 226 random = new Random ( ); 227 228 try 229 { 230 sequencer = MidiSystem.getSequencer ( ); 231 232 synthesizer = MidiSystem.getSynthesizer ( ); 233 234 synthesizer.open ( ); 235 236 Soundbank soundbank = synthesizer.getDefaultSoundbank ( ); 237 238 if ( soundbank != null ) 239 { 240 System.out.println ( "Using soundbank instruments..." ); 241 242 instruments = soundbank.getInstruments ( ); 243 } 244 else 245 { 246 System.out.println ( "Using synthesizer instruments..." ); 247 248 instruments = synthesizer.getAvailableInstruments ( ); 249 } 250 251 midiChannels = synthesizer.getChannels ( ); 252 253 if ( instruments.length < 1 ) 254 { 255 textAnimator.setText ( SOUNDBANK_URL_NAME ); 256 257 URL soundbankURL = new URL ( SOUNDBANK_URL_NAME ); 258 259 try 260 { 261 getAppletContext ( ).showDocument ( soundbankURL, "_blank" ); 262 } 263 catch ( Exception ex ) 264 { 265 try 266 { 267 JnlpLib.showDocument ( soundbankURL ); 268 } 269 catch ( Exception ex2 ) 270 { 271 } 272 } 273 } 274 } 275 catch ( Exception ex ) 276 { 277 ex.printStackTrace ( ); 278 279 throw new InitializationException ( ex ); 280 } 281 } 282 283 public void update ( JComponent component ) 284 ////////////////////////////////////////////////////////////////////// 285 { 286 super.update ( component ); 287 288 if ( !started 289 || instruments.length < 1 ) 290 { 291 return; 292 } 293 294 if ( noteOn ) 295 { 296 long currentTime = System.currentTimeMillis ( ); 297 298 if ( previousTime + DELAY >= currentTime ) 299 { 300 return; 301 } 302 303 previousTime = currentTime; 304 305 midiChannels [ 0 ].noteOff ( noteNumber ); 306 307 noteOn = false; 308 } 309 else 310 { 311 noteNumber = random.nextInt ( 128 ); 312 313 int instrumentIndex = random.nextInt ( instruments.length ); 314 315 Instrument instrument = instruments [ instrumentIndex ]; 316 317 textAnimator.setText ( 318 instrument.getName ( ) + " " + noteNumber ); 319 320 synthesizer.loadInstrument ( instrument ); 321 322 midiChannels [ 0 ].programChange ( instrumentIndex ); 323 324 int velocity = 64; 325 326 midiChannels [ 0 ].noteOn ( noteNumber, velocity ); 327 328 noteOn = true; 329 } 330 } 331 332 public void start ( ) 333 ////////////////////////////////////////////////////////////////////// 334 { 335 started = true; 336 337 super.start ( ); 338 } 339 340 public void stop ( ) 341 ////////////////////////////////////////////////////////////////////// 342 { 343 started = false; 344 345 if ( noteOn ) 346 { 347 midiChannels [ 0 ].noteOff ( noteNumber ); 348 349 noteOn = false; 350 } 351 352 super.stop ( ); 353 } 354 355 public void destroy ( ) 356 ////////////////////////////////////////////////////////////////////// 357 { 358 synthesizer.close ( ); 359 360 sequencer.close ( ); 361 362 /* 363 try 364 { 365 SerializableLib.save ( 366 userData, 367 LATEST_FILENAME, 368 BACKUP_FILENAME, 369 FILE_CONTENTS_SPEC, 370 ( Applet ) this, 371 PERSISTENCE_KEY ); 372 } 373 catch ( Exception ex ) 374 { 375 ex.printStackTrace ( ); 376 } 377 */ 378 379 super.destroy ( ); 380 } 381 382 ////////////////////////////////////////////////////////////////////// 383 ////////////////////////////////////////////////////////////////////// 384 }