Source Code Cross Referenced for SimplePlayerGUI.java in  » IDE-Netbeans » mobility » example » mmademo » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » mobility » example.mmademo 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 2007, Sun Microsystems, Inc.
0003:         * 
0004:         * All rights reserved.
0005:         * 
0006:         * Redistribution and use in source and binary forms, with or without
0007:         * modification, are permitted provided that the following conditions
0008:         * are met:
0009:         * 
0010:         *     * Redistributions of source code must retain the above copyright
0011:         *       notice, this list of conditions and the following disclaimer.
0012:         *     * Redistributions in binary form must reproduce the above copyright
0013:         *       notice, this list of conditions and the following disclaimer in
0014:         *       the documentation and/or other materials provided with the
0015:         *       distribution.
0016:         *     * Neither the name of Sun Microsystems, Inc. nor the names of its
0017:         *       contributors may be used to endorse or promote products derived
0018:         *       from this software without specific prior written permission.
0019:         * 
0020:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0021:         * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0022:         * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
0023:         * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
0024:         * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0025:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0026:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0027:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
0028:         * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
0029:         * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0030:         * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0031:         */
0032:
0033:        package example.mmademo;
0034:
0035:        import java.util.*;
0036:        import java.io.*;
0037:        import javax.microedition.midlet.*;
0038:        import javax.microedition.lcdui.*;
0039:        import javax.microedition.media.*;
0040:        import javax.microedition.media.control.*;
0041:
0042:        /**
0043:         * GUI functionality for SimplePlayer.
0044:         * This class is used by SimplePlayerCanvas and SimplePlayerForm and
0045:         * provides the actual logic.
0046:         * SimplePlayerCanvas and SimplePlayerForm provide the interaction of
0047:         * the main window with the user.
0048:         *
0049:         * @version 1.10
0050:         */
0051:        public class SimplePlayerGUI implements  CommandListener,
0052:                PlayerListener, ItemStateListener {
0053:            // IMPL NOTE: used for the form-based player for video
0054:            // if you set this to false, the currently active player is used
0055:            private final static boolean USE_FORM_PLAYER_FOR_VIDEO = false;
0056:
0057:            // maximum rate to support, in percent
0058:            private final static int LIMIT_RATE = 300;
0059:
0060:            // loop
0061:            private static final int LOOP_ONCE = 0;
0062:            private static final int LOOP_3 = 1;
0063:            private static final int LOOP_INF = 2;
0064:            private int loopmode = LOOP_ONCE;
0065:
0066:            // timer (for time display and karaoke asynchronous event)
0067:            private static final int DEFAULT_TIMER_INTERVAL = 50;
0068:            private int timerInterval = DEFAULT_TIMER_INTERVAL;
0069:
0070:            // gauge
0071:            private static final int GAUGE_NONE = -1;
0072:            private static final int GAUGE_VOLUME = 0; // gauge is used as volume slider
0073:            private static final int GAUGE_RATE = 1; // gauge is used as rate slider
0074:            private static final int GAUGE_TEMPO = 2; // gauge is used as tempo slider
0075:            private static final int GAUGE_PITCH = 3; // gauge is used as pitch slider
0076:            private int gaugeMode = GAUGE_NONE;
0077:            private Gauge gauge = null;
0078:            private StringItem gaugeLabel = null;
0079:            private Form gaugeForm = null;
0080:
0081:            // display timer
0082:            private Timer guiTimer = null;
0083:            private TimerTask timeDisplayTask = null;
0084:
0085:            // Commands
0086:            Command backCommand = new Command("Back", Command.BACK, 1); // is used in SimplePlayerCanvas
0087:            private Command playCommand = new Command("Play", Command.ITEM, 1);
0088:            private Command stopCommand = new Command("Stop", Command.ITEM, 1);
0089:            private Command metaCommand = new Command("META data",
0090:                    Command.ITEM, 3);
0091:            private Command volCommand = new Command("Volume", Command.ITEM, 2);
0092:            private Command muteCommand = new Command("Mute", Command.ITEM, 1);
0093:            private Command unmuteCommand = new Command("Unmute", Command.ITEM,
0094:                    1);
0095:            private Command loopCommand = new Command("Loopmode", Command.ITEM,
0096:                    4);
0097:            private Command stcCommand = new Command("Stop in 5 sec",
0098:                    Command.ITEM, 4);
0099:            private Command selectCommand = new Command("Select", Command.ITEM,
0100:                    1);
0101:            private Command skipFwCommand = new Command("Skip Forward",
0102:                    Command.ITEM, 5);
0103:            private Command skipBwCommand = new Command("Skip Backward",
0104:                    Command.ITEM, 5);
0105:            private Command rewindCommand = new Command("Rewind", Command.ITEM,
0106:                    5);
0107:            private Command rateCommand = new Command("Rate", Command.ITEM, 5);
0108:            private Command tempoCommand = new Command("Tempo", Command.ITEM, 5);
0109:            private Command pitchCommand = new Command("Pitch", Command.ITEM, 5);
0110:            private Command fullScreenCommand = new Command("Full Screen: ON",
0111:                    Command.ITEM, 5);
0112:            private Command normalScreenCommand = new Command(
0113:                    "Full Screen: OFF", Command.ITEM, 5);
0114:            private Command startRecordCommand = new Command("Start Recording",
0115:                    Command.ITEM, 5);
0116:            private Command stopRecordCommand = new Command("Stop Recording",
0117:                    Command.ITEM, 5);
0118:            private Command helpCommand = new Command("Quick Help",
0119:                    Command.ITEM, 10);
0120:
0121:            // display
0122:            private Parent parent;
0123:            private Displayable display;
0124:            private static Image logo = null;
0125:
0126:            // full screen
0127:            private boolean fullScreen = false;
0128:
0129:            // recording
0130:            private boolean isRecording = false;
0131:            private String recordLocator = "file:///root1/recording.wav";
0132:
0133:            // the player instance
0134:            private Player player = null;
0135:
0136:            // song descriptors
0137:            private String title;
0138:            private InputStream songInputStream;
0139:            private String durationStr;
0140:            private String songContentType = "";
0141:            private String songLocator = "";
0142:            private String songName = "";
0143:            private String[] songDisplayNames = new String[0];
0144:            private int currSongDisplay = 0;
0145:            private int changeSongDisplayCounter = 0;
0146:            private static final int SONG_DISPLAY_COUNTER = 2000 / DEFAULT_TIMER_INTERVAL; // 2 seconds
0147:
0148:            // karaoke support
0149:            private final static int LYRICS_EVENT = 0x60; // not an official event
0150:            private final static String LYRICS_KEY = "lyrics"; // not an official key for MetaDataControl
0151:            // indexes in params array returned by getKaraokeStr()
0152:            public final static int KARAOKE_LINE_COUNT = 0;
0153:            public final static int KARAOKE_LINE = 1;
0154:            public final static int KARAOKE_LINE_INDEX = 2;
0155:            public final static int KARAOKE_SYLLABLE_LENGTH = 3;
0156:
0157:            private boolean karaokeMode = false;
0158:            private String karaokeLyrics = "";
0159:            private int currKaraokeLine = 0;
0160:            private int currKaraokeLinePos = 0;
0161:            private int currKaraokeLength = 0;
0162:            private String[] karaokeLines = null;
0163:            private int[] karaokeLinePos = null; // start position in karaokeLyrics for each line
0164:            private int karaokeLineCount = 0;
0165:            private int redisplayKaraokeCounter = 0; // asynchronous switch to next Karaoke page
0166:            private int nextKaraokePos = 0; // for asynchronous display of next line/phrase
0167:
0168:            // pause/resume support
0169:            private boolean restartOnResume = false;
0170:
0171:            private static void debugOut(String s) {
0172:                Utils.debugOut("SimplePlayerGUI: " + s);
0173:            }
0174:
0175:            // /////////////////////////// INITIALIZATION /////////////////////////////
0176:
0177:            /** Note: parent MUST be Displayable */
0178:            public SimplePlayerGUI() {
0179:                // initialize(String title, Parent parent) must be called after this
0180:            }
0181:
0182:            public void initialize(String title, Parent parent) {
0183:                this .title = title;
0184:                setParent(parent);
0185:                initialize();
0186:            }
0187:
0188:            public void setParent(Parent parent) {
0189:                this .parent = parent;
0190:                if (!(parent instanceof  Displayable)) {
0191:                    throw new RuntimeException(
0192:                            "parent must be instanceof Displayable!");
0193:                }
0194:                display = (Displayable) parent;
0195:                display.addCommand(backCommand);
0196:                display.setCommandListener(this );
0197:                updateTime();
0198:                updateRate(null);
0199:                updateTempo(null);
0200:                durationUpdated();
0201:                parent.updateKaraoke();
0202:                parent.updateDisplay();
0203:            }
0204:
0205:            private void initialize() {
0206:                karaokeMode = false;
0207:                karaokeLyrics = "";
0208:                currKaraokeLine = 0;
0209:                currKaraokeLinePos = 0;
0210:                currKaraokeLength = 0;
0211:                karaokeLines = null;
0212:                karaokeLinePos = null;
0213:                karaokeLineCount = 0;
0214:                redisplayKaraokeCounter = 0;
0215:                removeCommands();
0216:                setStatus("");
0217:                durationStr = "";
0218:                setSong("No song loaded", "");
0219:                guiTimer = new Timer();
0220:            }
0221:
0222:            public void setSong(String name, String locator) {
0223:                songLocator = locator;
0224:                songInputStream = null;
0225:                songContentType = "";
0226:                doSetSong(name);
0227:            }
0228:
0229:            public void setSong(String name, InputStream is, String contentType) {
0230:                songLocator = "";
0231:                songInputStream = is;
0232:                songContentType = contentType;
0233:                doSetSong(name);
0234:            }
0235:
0236:            public void setSong(String name, Player player) {
0237:                songLocator = "";
0238:                songInputStream = null;
0239:                songContentType = "";
0240:                doSetSong(name);
0241:                this .player = player;
0242:            }
0243:
0244:            private void doSetSong(String name) {
0245:                songName = name;
0246:                songDisplayNames = new String[1];
0247:                songDisplayNames[0] = name;
0248:                currSongDisplay = 0;
0249:                closePlayer();
0250:                setStatus("");
0251:                setFeedback("");
0252:                clearKaraoke();
0253:                updateTempo(null);
0254:                updateTime();
0255:                updateSongDisplay();
0256:            }
0257:
0258:            public void setTimerInterval(int millis) {
0259:                timerInterval = millis;
0260:            }
0261:
0262:            // /////////////////////////// VISUAL FEEDBACK ////////////////////////////
0263:
0264:            private void error(Throwable e) {
0265:                error(Utils.friendlyException(e));
0266:                if (Utils.DEBUG)
0267:                    e.printStackTrace();
0268:            }
0269:
0270:            private void error(String s) {
0271:                setFeedback(s);
0272:            }
0273:
0274:            private void setStatus(String s) {
0275:                parent.setStatus(s);
0276:                if (Utils.DEBUG)
0277:                    System.out.println("Status: " + s);
0278:            }
0279:
0280:            private void setFeedback(String s) {
0281:                parent.setFeedback(s);
0282:                if (Utils.DEBUG)
0283:                    System.out.println("Feedback: " + s);
0284:            }
0285:
0286:            private void updateKaraoke() {
0287:                parent.updateKaraoke();
0288:            }
0289:
0290:            private void updateTime() {
0291:                parent.updateTime();
0292:            }
0293:
0294:            private void updateRate(RateControl c) {
0295:                parent.updateRate();
0296:                // if the rate gauge is activated, update it
0297:                if (gauge != null && gaugeMode == GAUGE_RATE) {
0298:                    if (c == null) {
0299:                        c = getRateControl();
0300:                    }
0301:                    if (c != null) {
0302:                        String disp = getRateStr();
0303:                        // or
0304:                        // gauge.setValue((c.getRate() - c.getMinRate() + 1)/1000);
0305:                        gauge.setValue((c.getRate() - c.getMinRate()) / 1000);
0306:                        gaugeLabel.setLabel(disp);
0307:                    }
0308:                }
0309:            }
0310:
0311:            private void updateTempo(TempoControl c) {
0312:                parent.updateRate();
0313:                // if the tempo gauge is activated, update it
0314:                if (gauge != null && gaugeMode == GAUGE_TEMPO) {
0315:                    if (c == null) {
0316:                        c = getTempoControl();
0317:                    }
0318:                    if (c != null) {
0319:                        String disp = getTempoStr();
0320:                        gauge.setValue((c.getTempo() / 1000) - 1);
0321:                        gaugeLabel.setLabel(disp);
0322:                    }
0323:                }
0324:            }
0325:
0326:            private void updateVolume(VolumeControl c) {
0327:                if (c == null) {
0328:                    c = getVolumeControl();
0329:                }
0330:                if (c != null) {
0331:                    int l = c.getLevel();
0332:                    String disp = "Volume: " + String.valueOf(l);
0333:                    if (c.isMuted()) {
0334:                        disp += " (muted)";
0335:                    }
0336:                    if (gauge != null && gaugeMode == GAUGE_VOLUME) {
0337:                        gauge.setValue(l);
0338:                        gaugeLabel.setLabel(disp);
0339:                    }
0340:                    setFeedback(disp);
0341:                }
0342:            }
0343:
0344:            private void updatePitch(PitchControl c) {
0345:                if (c == null) {
0346:                    c = getPitchControl();
0347:                }
0348:                if (c != null) {
0349:                    String disp = "Transpose: "
0350:                            + toFloatString(c.getPitch(), 3) + " semi tones";
0351:                    // if the pitch gauge is activated, update it
0352:                    if (gauge != null && gaugeMode == GAUGE_PITCH) {
0353:                        // WTK removed the next line
0354:                        gauge.setValue((c.getPitch() - c.getMinPitch()) / 1000);
0355:                        gaugeLabel.setLabel(disp);
0356:                    }
0357:                    setFeedback(disp);
0358:                }
0359:            }
0360:
0361:            private void updateLoop() {
0362:                if (player != null) {
0363:                    try {
0364:                        int loop = 1;
0365:                        switch (loopmode) {
0366:                        case LOOP_ONCE:
0367:                            loop = 1;
0368:                            break;
0369:                        case LOOP_3:
0370:                            loop = 3;
0371:                            break;
0372:                        case LOOP_INF:
0373:                            loop = -1;
0374:                            break;
0375:                        }
0376:                        boolean restart = false;
0377:                        if (player.getState() == player.STARTED) {
0378:                            player.stop();
0379:                            restart = true;
0380:                        }
0381:                        player.setLoopCount(loop);
0382:                        if (restart) {
0383:                            player.start();
0384:                        }
0385:
0386:                    } catch (Exception e) {
0387:                        error(e);
0388:                    }
0389:                }
0390:            }
0391:
0392:            private void updateSongDisplay() {
0393:                String add = "";
0394:                if (currSongDisplay == 0) {
0395:                    add = durationStr;
0396:                }
0397:                parent.setFileTitle(songDisplayNames[currSongDisplay] + add);
0398:            }
0399:
0400:            private void durationUpdated() {
0401:                if (player != null) {
0402:                    // include duration in song name
0403:                    try {
0404:                        long duration = player.getDuration();
0405:                        if (duration >= 0) {
0406:                            durationStr = " (" + timeDisplay(duration) + ")";
0407:                        } else {
0408:                            durationStr = "";
0409:                        }
0410:                    } catch (IllegalStateException ise) {
0411:                        // thrown in CLOSED state
0412:                        durationStr = "";
0413:                    }
0414:                    updateSongDisplay();
0415:                }
0416:            }
0417:
0418:            private void clearKaraoke() {
0419:                karaokeLineCount = 0;
0420:                nextKaraokePos = -1;
0421:                redisplayKaraokeCounter = 0;
0422:                updateKaraoke();
0423:            }
0424:
0425:            // /////////////////////////// DISPLAY UTILITIES //////////////////////////
0426:
0427:            public Image getLogo() {
0428:                if (logo == null) {
0429:                    try {
0430:                        logo = Image.createImage("/icons/logo.png");
0431:                    } catch (Exception ex) {
0432:                        logo = null;
0433:                    }
0434:                    if (logo == null) {
0435:                        debugOut("can not load logo.png");
0436:                    }
0437:                }
0438:                return logo;
0439:            }
0440:
0441:            private String toFloatString(int number, int digitsAfterDot) {
0442:                StringBuffer ret = new StringBuffer(String.valueOf(number));
0443:                while (ret.length() < (digitsAfterDot + 1)) {
0444:                    ret.insert(0, '0');
0445:                }
0446:                ret.insert(ret.length() - digitsAfterDot, '.');
0447:                return ret.toString();
0448:            }
0449:
0450:            private String formatNumber(long num, int len, boolean leadingZeros) {
0451:                StringBuffer ret = new StringBuffer(String.valueOf(num));
0452:                if (leadingZeros) {
0453:                    while (ret.length() < len) {
0454:                        ret.insert(0, '0');
0455:                    }
0456:                } else {
0457:                    while (ret.length() < len) {
0458:                        ret.append('0');
0459:                    }
0460:                }
0461:                return ret.toString();
0462:            }
0463:
0464:            private String timeDisplay(long us) {
0465:                long ts = us / 100000;
0466:                return formatNumber(ts / 600l, 2, true) + ":"
0467:                        + formatNumber(((ts % 600) / 10), 2, true) + "."
0468:                        + String.valueOf(ts % 10);
0469:            }
0470:
0471:            public String getMediaTimeStr() {
0472:                try {
0473:                    if (player != null) {
0474:                        return timeDisplay(player.getMediaTime());
0475:                    }
0476:                } catch (IllegalStateException ise) {
0477:                    // thrown when player is closed
0478:                }
0479:                return "--:--:-";
0480:            }
0481:
0482:            public String getTempoStr() {
0483:                if (player != null) {
0484:                    TempoControl tc = getTempoControl();
0485:                    if (tc != null) {
0486:                        int tempo = tc.getTempo();
0487:                        return toFloatString((tempo + 50) / 100, 1)
0488:                                + "bpm (eff: "
0489:                                + toFloatString(
0490:                                        (int) (((((long) tc.getRate())
0491:                                                * ((long) tempo) / 100000) + 50) / 100l),
0492:                                        1) + ")";
0493:                    }
0494:                }
0495:                return "";
0496:            }
0497:
0498:            public String getRateStr() {
0499:                if (player != null) {
0500:                    RateControl rc = getRateControl();
0501:                    if (rc != null) {
0502:                        return "Rate: " + toFloatString(rc.getRate() / 100, 1)
0503:                                + "%";
0504:                    }
0505:                }
0506:                return "";
0507:            }
0508:
0509:            /**
0510:             * switch to next karaoke screen
0511:             */
0512:            private void displayNextKaraokePhrase() {
0513:                if (karaokeLyrics != null && karaokeLineCount > 0
0514:                        && karaokeLines != null && nextKaraokePos >= 0) {
0515:                    if (nextKaraokePos < karaokeLyrics.length()
0516:                            && nextKaraokePos > karaokeLinePos[currKaraokeLine]) {
0517:                        setupKaraokeLines(nextKaraokePos, 0);
0518:                        updateKaraoke();
0519:                    }
0520:                }
0521:            }
0522:
0523:            private void addKaraokeLine(int start, int end) {
0524:                if (karaokeLines == null
0525:                        || karaokeLines.length <= karaokeLineCount) {
0526:                    String[] newKL = new String[karaokeLineCount + 4];
0527:                    if (karaokeLines != null) {
0528:                        System.arraycopy(karaokeLines, 0, newKL, 0,
0529:                                karaokeLineCount);
0530:                    }
0531:                    karaokeLines = newKL;
0532:                    int[] newKLP = new int[karaokeLineCount + 5]; // one more than karaokeLines.length
0533:                    if (karaokeLinePos != null) {
0534:                        System.arraycopy(karaokeLinePos, 0, newKLP, 0,
0535:                                karaokeLineCount + 1);
0536:                    }
0537:                    karaokeLinePos = newKLP;
0538:                }
0539:                karaokeLines[karaokeLineCount] = karaokeLyrics.substring(start,
0540:                        end);
0541:                karaokeLinePos[karaokeLineCount++] = start;
0542:            }
0543:
0544:            private void setupKaraokeLines(int pos, int syllableLen) {
0545:                int len = (karaokeLyrics == null) ? 0 : karaokeLyrics.length();
0546:                if (len == 0) {
0547:                    debugOut("no karaoke lyrics");
0548:                    return;
0549:                }
0550:                // cancel automatic display of next line if it is already displayed
0551:                nextKaraokePos = -1;
0552:                if (pos < 0 || pos >= len) {
0553:                    karaokeLineCount = 0;
0554:                    debugOut("setupKaraokeLines: pos out of bounds!");
0555:                    return;
0556:                }
0557:                // the strings in karaokeLines never start with a control character
0558:                while (karaokeLyrics.charAt(pos) == '\\'
0559:                        || karaokeLyrics.charAt(pos) == '/') {
0560:                    pos++;
0561:                    syllableLen--;
0562:                }
0563:                if (syllableLen < 0) {
0564:                    syllableLen = 0;
0565:                }
0566:                if (karaokeLinePos == null || karaokeLineCount == 0
0567:                        || pos < karaokeLinePos[0]
0568:                        || pos >= karaokeLinePos[karaokeLineCount]) {
0569:                    // need to re-setup karaoke lines
0570:                    // first find the start of this phrase
0571:                    int startPos = pos;
0572:                    while (karaokeLyrics.charAt(startPos) != '\\'
0573:                            && startPos > 0) {
0574:                        startPos--;
0575:                    }
0576:                    if (karaokeLyrics.charAt(startPos) == '\\') {
0577:                        startPos++;
0578:                    }
0579:                    // now go through the lines and add them to karaokeLines array
0580:                    karaokeLineCount = 0;
0581:                    int endPos = startPos;
0582:                    while (endPos < len) {
0583:                        char c = karaokeLyrics.charAt(endPos);
0584:                        if (c == '/') {
0585:                            // new line
0586:                            addKaraokeLine(startPos, endPos);
0587:                            startPos = endPos + 1;
0588:                        } else if (c == '\\') {
0589:                            // end of phrase
0590:                            break;
0591:                        }
0592:                        endPos++;
0593:                    }
0594:                    addKaraokeLine(startPos, endPos);
0595:                    if (endPos < len) {
0596:                        endPos--;
0597:                    }
0598:                    karaokeLinePos[karaokeLineCount] = endPos;
0599:                }
0600:                // search the current line and position in the current line
0601:                currKaraokeLength = 0;
0602:                for (int i = 0; i < karaokeLineCount; i++) {
0603:                    if (pos >= karaokeLinePos[i] && pos < karaokeLinePos[i + 1]) {
0604:                        currKaraokeLine = i;
0605:                        currKaraokeLinePos = pos - karaokeLinePos[i];
0606:                        currKaraokeLength = syllableLen;
0607:                        //debugOut("For pos="+pos+" and syllLen="+syllableLen+", found line "+i+" . Set currKaraokeLinePos="+currKaraokeLinePos);
0608:                        if ((currKaraokeLinePos + syllableLen >= karaokeLines[i]
0609:                                .length())) {
0610:                            nextKaraokePos = karaokeLinePos[i + 1] + 1;
0611:                            redisplayKaraokeCounter = 100 / DEFAULT_TIMER_INTERVAL + 1; // approx. 100ms
0612:                        }
0613:                        break;
0614:                    }
0615:                }
0616:            }
0617:
0618:            /**
0619:             * OUT: params:
0620:             * 0: number of valid strings in return array
0621:             * 1: index in return array of currently sung line
0622:             * 2: index in current line which is currently sung. if -1: nothing currently sung
0623:             * 3: length of syllable currently sung.
0624:             */
0625:            public String[] getKaraokeStr(int[] params) {
0626:                params[0] = karaokeLineCount;
0627:                params[1] = currKaraokeLine;
0628:                params[2] = currKaraokeLinePos;
0629:                params[3] = currKaraokeLength;
0630:                return karaokeLines;
0631:            }
0632:
0633:            // /////////////////////////// USER FLOW //////////////////////////////////
0634:
0635:            private void goBack() {
0636:                if (parent.getCurrentDisplayable() == display) {
0637:                    closePlayer();
0638:                }
0639:                Displayable now = parent.goBack();
0640:                if (now == display) {
0641:                    // if main player window is showing
0642:                    setPlayerCommands();
0643:                }
0644:            }
0645:
0646:            private void setPlayerCommands() {
0647:                removeCommands();
0648:                display.addCommand(backCommand);
0649:                if (player != null) {
0650:                    if (getMetaDataControl() != null) {
0651:                        display.addCommand(metaCommand);
0652:                    }
0653:                    if (getStopTimeControl() != null) {
0654:                        display.addCommand(stcCommand);
0655:                    }
0656:                    VolumeControl vc = getVolumeControl();
0657:                    if (vc != null) {
0658:                        display.addCommand(volCommand);
0659:                        if (vc.isMuted()) {
0660:                            display.addCommand(unmuteCommand);
0661:                        } else {
0662:                            display.addCommand(muteCommand);
0663:                        }
0664:                    }
0665:                    if (getRateControl() != null) {
0666:                        display.addCommand(rateCommand);
0667:                    }
0668:                    if (getTempoControl() != null) {
0669:                        display.addCommand(tempoCommand);
0670:                    }
0671:                    if (getPitchControl() != null) {
0672:                        display.addCommand(pitchCommand);
0673:                    }
0674:                    if (getVideoControl() != null) {
0675:                        display.addCommand(normalScreenCommand);
0676:                        display.addCommand(fullScreenCommand);
0677:                    }
0678:                    if (getRecordControl() != null) {
0679:                        if (isRecording) {
0680:                            display.addCommand(stopRecordCommand);
0681:                        } else {
0682:                            display.addCommand(startRecordCommand);
0683:                        }
0684:                    }
0685:                    display.addCommand(loopCommand);
0686:                    if (player.getState() >= Player.STARTED) {
0687:                        display.addCommand(stopCommand);
0688:                    } else {
0689:                        display.addCommand(playCommand);
0690:                    }
0691:                    display.addCommand(skipFwCommand);
0692:                    display.addCommand(skipBwCommand);
0693:                    display.addCommand(rewindCommand);
0694:                    if (parent instanceof  SimplePlayerCanvas) {
0695:                        // Canvas player uses the keys for control,
0696:                        // enable a simple help
0697:                        display.addCommand(helpCommand);
0698:                    }
0699:                }
0700:            }
0701:
0702:            private void removeCommands() {
0703:                display.removeCommand(muteCommand);
0704:                display.removeCommand(unmuteCommand);
0705:                display.removeCommand(metaCommand);
0706:                display.removeCommand(volCommand);
0707:                display.removeCommand(stcCommand);
0708:                display.removeCommand(loopCommand);
0709:                display.removeCommand(backCommand);
0710:                display.removeCommand(playCommand);
0711:                display.removeCommand(stopCommand);
0712:                display.removeCommand(skipFwCommand);
0713:                display.removeCommand(skipBwCommand);
0714:                display.removeCommand(rewindCommand);
0715:                display.removeCommand(rateCommand);
0716:                display.removeCommand(tempoCommand);
0717:                display.removeCommand(pitchCommand);
0718:                display.removeCommand(fullScreenCommand);
0719:                display.removeCommand(normalScreenCommand);
0720:                display.removeCommand(startRecordCommand);
0721:                display.removeCommand(stopRecordCommand);
0722:                display.removeCommand(helpCommand);
0723:            }
0724:
0725:            // /////////////////////////// MENU ITEM HANDLERS /////////////////////////
0726:
0727:            private void mutePressed() {
0728:                VolumeControl c = getVolumeControl();
0729:                if (c != null) {
0730:                    if (c.isMuted()) {
0731:                        //muteCommand.setLabel("Mute"); MIDP_NG only ?
0732:                        display.removeCommand(unmuteCommand);
0733:                        display.addCommand(muteCommand);
0734:                        c.setMute(false);
0735:                    } else {
0736:                        //muteCommand.setLabel("Unmute"); MIDP_NG only ?
0737:                        display.removeCommand(muteCommand);
0738:                        display.addCommand(unmuteCommand);
0739:                        c.setMute(true);
0740:                    }
0741:                    updateVolume(c);
0742:                } else {
0743:                    setFeedback("No VolumeControl!");
0744:                }
0745:            }
0746:
0747:            private void displayGauge(String title) {
0748:                if (gaugeForm == null) {
0749:                    gaugeForm = new Form(title);
0750:                    gaugeForm.append(gauge);
0751:                    gaugeForm.append(gaugeLabel);
0752:                    gaugeForm.setItemStateListener(this );
0753:                    gaugeForm.addCommand(backCommand);
0754:                    gaugeForm.setCommandListener(this );
0755:                }
0756:                parent.go(gaugeForm);
0757:            }
0758:
0759:            private void volPressed() {
0760:                VolumeControl c = getVolumeControl();
0761:                if (c != null) {
0762:                    if (gauge == null || gaugeMode != GAUGE_VOLUME) {
0763:                        gauge = new Gauge("Volume", true, 100, c.getLevel());
0764:                        gaugeLabel = new StringItem("Volume", "");
0765:                        gaugeMode = GAUGE_VOLUME;
0766:                        gaugeForm = null;
0767:                    }
0768:                    displayGauge("Set Volume");
0769:                    updateVolume(c);
0770:                } else {
0771:                    setFeedback("No VolumeControl!");
0772:                }
0773:            }
0774:
0775:            private void ratePressed() {
0776:                RateControl c = getRateControl();
0777:                if (c != null) {
0778:                    if (gauge == null || gaugeMode != GAUGE_RATE) {
0779:                        int minRate = c.getMinRate() / 1000;
0780:                        int maxRate = c.getMaxRate() / 1000;
0781:                        // limit to LIMIT_RATE to improve usability
0782:                        if (maxRate > LIMIT_RATE) {
0783:                            maxRate = LIMIT_RATE;
0784:                        }
0785:                        int currRate = c.getRate() / 1000;
0786:                        gauge = new Gauge("Rate", true, maxRate - minRate,
0787:                                currRate - minRate);
0788:                        gaugeLabel = new StringItem("Rate", "");
0789:                        gaugeMode = GAUGE_RATE;
0790:                        gaugeForm = null;
0791:                    }
0792:                    displayGauge("Set Rate");
0793:                    updateRate(c);
0794:                } else {
0795:                    setFeedback("No RateControl!");
0796:                }
0797:            }
0798:
0799:            private void pitchPressed() {
0800:                PitchControl c = getPitchControl();
0801:                if (c != null) {
0802:                    if (gauge == null || gaugeMode != GAUGE_PITCH) {
0803:                        gauge = new Gauge("Pitch", true, (c.getMaxPitch() - c
0804:                                .getMinPitch()) / 1000, (c.getPitch() - c
0805:                                .getMinPitch()) / 1000);
0806:                        gaugeLabel = new StringItem("Pitch", "");
0807:                        gaugeMode = GAUGE_PITCH;
0808:                        gaugeForm = null;
0809:                    }
0810:                    displayGauge("Set Pitch");
0811:                    updatePitch(c);
0812:                } else {
0813:                    setFeedback("No PitchControl!");
0814:                }
0815:            }
0816:
0817:            private void tempoPressed() {
0818:                TempoControl c = getTempoControl();
0819:                if (c != null) {
0820:                    if (gauge == null || gaugeMode != GAUGE_TEMPO) {
0821:                        gauge = new Gauge("Tempo", true, 399,
0822:                                (c.getTempo() / 1000) - 1);
0823:                        gaugeLabel = new StringItem("Tempo", "");
0824:                        gaugeMode = GAUGE_TEMPO;
0825:                        gaugeForm = null;
0826:                    }
0827:                    displayGauge("Set Tempo");
0828:                    updateTempo(c);
0829:                } else {
0830:                    setFeedback("No TempoControl!");
0831:                }
0832:            }
0833:
0834:            private void metaPressed() {
0835:                MetaDataControl c = getMetaDataControl();
0836:                if (c != null) {
0837:                    List list = new List("Meta Data", Choice.IMPLICIT);
0838:                    String[] allkeys = c.getKeys();
0839:                    Utils.sort(allkeys);
0840:                    for (int i = 0; i < allkeys.length; i++) {
0841:                        try {
0842:                            if (!allkeys[i].equals(LYRICS_KEY)) {
0843:                                list.append(allkeys[i] + " = "
0844:                                        + c.getKeyValue(allkeys[i]), null);
0845:                            }
0846:                        } catch (IllegalArgumentException t) {
0847:                            list.append(allkeys[i] + ": "
0848:                                    + Utils.friendlyException(t), null);
0849:                        }
0850:                    }
0851:                    if (allkeys.length == 0) {
0852:                        list.append("No meta data", null);
0853:                    }
0854:                    list.addCommand(backCommand);
0855:                    list.setCommandListener(this );
0856:                    parent.go(list);
0857:                } else {
0858:                    setFeedback("No MetaDataControl!");
0859:                }
0860:            }
0861:
0862:            private void loopPressed() {
0863:                loopmode = (loopmode + 1) % 3;
0864:                String fb = "";
0865:                switch (loopmode) {
0866:                case LOOP_ONCE:
0867:                    fb = "one time";
0868:                    break;
0869:                case LOOP_3:
0870:                    fb = "3 times";
0871:                    break;
0872:                case LOOP_INF:
0873:                    fb = "infinite";
0874:                    break;
0875:                }
0876:                setFeedback("Set loop mode to " + fb);
0877:                updateLoop();
0878:            }
0879:
0880:            public boolean isFullScreen() {
0881:                // this may not be accurate - the user can modify that with the keys
0882:                return fullScreen;
0883:            }
0884:
0885:            public boolean toggleFullScreen() {
0886:                VideoControl vc = getVideoControl();
0887:                Utils.debugOut("toggleFullScreen");
0888:                if (vc != null) {
0889:                    try {
0890:                        vc.setDisplayFullScreen(!fullScreen);
0891:                        fullScreen = !fullScreen;
0892:                        parent.fullScreen(fullScreen);
0893:                        Utils
0894:                                .debugOut("Successfully set to "
0895:                                        + (fullScreen ? "full screen"
0896:                                                : "normal screen"));
0897:                    } catch (Exception e) {
0898:                        fullScreen = false;
0899:                        display.removeCommand(fullScreenCommand);
0900:                        display.removeCommand(normalScreenCommand);
0901:                        error(e);
0902:                    }
0903:                } else {
0904:                    setFeedback("No VideoControl!");
0905:                }
0906:                return fullScreen;
0907:            }
0908:
0909:            private void fullScreenPressed() {
0910:                fullScreen = false;
0911:                toggleFullScreen();
0912:            }
0913:
0914:            private void normalScreenPressed() {
0915:                fullScreen = true;
0916:                toggleFullScreen();
0917:            }
0918:
0919:            public void stepFrame(int frames) {
0920:                FramePositioningControl fpc = getFramePositioningControl();
0921:                if (fpc != null) {
0922:                    fpc.skip(frames);
0923:                } else {
0924:                    setFeedback("No FramePositioningControl!");
0925:                }
0926:            }
0927:
0928:            // /////////////////////////// CONTROLS ///////////////////////////////////
0929:
0930:            public boolean hasRateControl() {
0931:                return getRateControl() != null;
0932:            }
0933:
0934:            public boolean hasTempoControl() {
0935:                return getTempoControl() != null;
0936:            }
0937:
0938:            public boolean hasGUIControls() {
0939:                // a player which provides VideoControl should also
0940:                // always return GUIControl. Just to be sure...
0941:                try {
0942:                    if (player != null) {
0943:                        return ((player.getControl("GUIControl") != null) || (player
0944:                                .getControl("VideoControl") != null));
0945:                    }
0946:                } catch (IllegalStateException ise) {
0947:                    // thrown when player is closed
0948:                }
0949:                return false;
0950:            }
0951:
0952:            public Control[] getControls() {
0953:                try {
0954:                    if (player != null) {
0955:                        return player.getControls();
0956:                    }
0957:                } catch (IllegalStateException ise) {
0958:                    // thrown when player is closed
0959:                }
0960:                return null;
0961:            }
0962:
0963:            private VolumeControl getVolumeControl() {
0964:                try {
0965:                    if (player != null) {
0966:                        return (VolumeControl) player
0967:                                .getControl("VolumeControl");
0968:                    }
0969:                } catch (IllegalStateException ise) {
0970:                    // thrown when player is closed
0971:                }
0972:                return null;
0973:            }
0974:
0975:            private TempoControl getTempoControl() {
0976:                try {
0977:                    if (player != null) {
0978:                        return (TempoControl) player.getControl("TempoControl");
0979:                    }
0980:                } catch (IllegalStateException ise) {
0981:                    // thrown when player is closed
0982:                }
0983:                return null;
0984:            }
0985:
0986:            private RateControl getRateControl() {
0987:                try {
0988:                    if (player != null) {
0989:                        return (RateControl) player.getControl("RateControl");
0990:                    }
0991:                } catch (IllegalStateException ise) {
0992:                    // thrown when player is closed
0993:                }
0994:                return null;
0995:            }
0996:
0997:            private PitchControl getPitchControl() {
0998:                try {
0999:                    if (player != null) {
1000:                        return (PitchControl) player.getControl("PitchControl");
1001:                    }
1002:                } catch (IllegalStateException ise) {
1003:                    // thrown when player is closed
1004:                }
1005:                return null;
1006:            }
1007:
1008:            private MetaDataControl getMetaDataControl() {
1009:                try {
1010:                    if (player != null) {
1011:                        return (MetaDataControl) player
1012:                                .getControl("MetaDataControl");
1013:                    }
1014:                } catch (IllegalStateException ise) {
1015:                    // thrown when player is closed
1016:                }
1017:                return null;
1018:            }
1019:
1020:            private FramePositioningControl getFramePositioningControl() {
1021:                try {
1022:                    if (player != null) {
1023:                        return (FramePositioningControl) player
1024:                                .getControl("FramePositioningControl");
1025:                    }
1026:                } catch (IllegalStateException ise) {
1027:                    // thrown when player is closed
1028:                }
1029:                return null;
1030:            }
1031:
1032:            private StopTimeControl getStopTimeControl() {
1033:                try {
1034:                    if (player != null) {
1035:                        return (StopTimeControl) player
1036:                                .getControl("StopTimeControl");
1037:                    }
1038:                } catch (IllegalStateException ise) {
1039:                    // thrown when player is closed
1040:                }
1041:                return null;
1042:            }
1043:
1044:            public VideoControl getVideoControl() {
1045:                try {
1046:                    if (player != null) {
1047:                        return (VideoControl) player.getControl("VideoControl");
1048:                    }
1049:                } catch (IllegalStateException ise) {
1050:                    // thrown when player is closed
1051:                }
1052:                return null;
1053:            }
1054:
1055:            public RecordControl getRecordControl() {
1056:                try {
1057:                    if (player != null) {
1058:                        return (RecordControl) player
1059:                                .getControl("RecordControl");
1060:                    }
1061:                } catch (IllegalStateException ise) {
1062:                    // thrown when player is closed
1063:                }
1064:                return null;
1065:            }
1066:
1067:            // /////////////////////////// PLAYBACK CONTROL ///////////////////////////
1068:
1069:            private void assertPlayer() throws Throwable {
1070:                String state = "";
1071:                try {
1072:                    debugOut("assertPlayer");
1073:                    fullScreen = false;
1074:                    // make sure we can go back, even if failed
1075:                    display.removeCommand(backCommand);
1076:                    display.addCommand(backCommand);
1077:                    if (player == null) {
1078:                        if (songInputStream == null) {
1079:                            state = "Opening " + songLocator;
1080:                            setStatus(state + "...");
1081:                            player = Manager.createPlayer(songLocator);
1082:                        } else {
1083:                            state = "Opening " + songName;
1084:                            setStatus(state + "...");
1085:                            player = Manager.createPlayer(songInputStream,
1086:                                    songContentType);
1087:                        }
1088:                    }
1089:                    player.addPlayerListener(this );
1090:                    //System.out.println("player = " + player);
1091:                    state = "Realizing";
1092:                    setStatus(state + "...");
1093:                    player.realize();
1094:                    state = "Prefetching";
1095:                    setStatus(state + "...");
1096:                    player.prefetch();
1097:                    state = "Prefetched";
1098:                    setStatus(state);
1099:                    if (USE_FORM_PLAYER_FOR_VIDEO) {
1100:                        // MAGIC: if there are any GUI controls, switch to Form mode
1101:                        // this is not nice design...
1102:                        if (hasGUIControls()
1103:                                && !(parent instanceof  SimplePlayerForm)) {
1104:                            System.gc();
1105:                            state = "Setting up GUI";
1106:                            setStatus(state + "...");
1107:                            Parent newParent = new SimplePlayerForm(parent
1108:                                    .getTitle(), this , parent.getParent());
1109:                            debugOut("created");
1110:                            setParent(newParent);
1111:                            parent.replaceCurrent(display);
1112:                            state = "GUI is set up.";
1113:                            setStatus(state);
1114:                            debugOut("Changed to form-based player.");
1115:                        }
1116:                    }
1117:                    setPlayerCommands();
1118:                    // notify the display class
1119:                    parent.setupDisplay();
1120:
1121:                    // use TITLE meta data if existant for display
1122:                    MetaDataControl mc = getMetaDataControl();
1123:                    if (mc != null) {
1124:                        int titleCount = 0;
1125:                        String title = "";
1126:                        try {
1127:                            title = mc.getKeyValue(MetaDataControl.TITLE_KEY);
1128:                            if (title != null && title != "") {
1129:                                titleCount++;
1130:                                while (true) {
1131:                                    String n = mc
1132:                                            .getKeyValue(MetaDataControl.TITLE_KEY
1133:                                                    + (titleCount + 1));
1134:                                    if (n == null || n == "") {
1135:                                        break;
1136:                                    }
1137:                                    titleCount++;
1138:                                }
1139:                            }
1140:                        } catch (IllegalArgumentException me) {
1141:                            // title key doesn't exist
1142:                        }
1143:                        // now number of titles is known
1144:                        if (titleCount > 0) {
1145:                            songDisplayNames = new String[titleCount];
1146:                            songDisplayNames[0] = title;
1147:                            try {
1148:                                for (int i = 1; i < titleCount; i++) {
1149:                                    songDisplayNames[i] = mc
1150:                                            .getKeyValue(MetaDataControl.TITLE_KEY
1151:                                                    + (i + 1));
1152:                                }
1153:                            } catch (IllegalArgumentException me) {
1154:                            }
1155:                            currSongDisplay = 0;
1156:                        }
1157:                        try {
1158:                            String l = mc.getKeyValue(LYRICS_KEY);
1159:                            if (l != null && l != "") {
1160:                                karaokeMode = true;
1161:                                karaokeLyrics = l;
1162:                            }
1163:                        } catch (IllegalArgumentException me) {
1164:                            // lyrics key doesn't exist
1165:                        }
1166:                    }
1167:                    durationUpdated();
1168:                } catch (Throwable t) {
1169:                    player = null;
1170:                    setStatus("");
1171:                    throw new MediaException(Utils.friendlyException(t)
1172:                            + " at " + state);
1173:                }
1174:            }
1175:
1176:            public void startPlayer() {
1177:                try {
1178:                    debugOut("startPlayer");
1179:                    if (player == null || player.getState() < Player.PREFETCHED) {
1180:                        assertPlayer();
1181:                    }
1182:                    if (player == null || player.getState() >= Player.STARTED) {
1183:                        return;
1184:                    }
1185:                    updateLoop();
1186:                    // auto-rewind
1187:                    try {
1188:                        long duration = player.getDuration();
1189:                        if (duration != Player.TIME_UNKNOWN
1190:                                && player.getMediaTime() >= duration) {
1191:                            player.setMediaTime(0);
1192:                        }
1193:                    } catch (MediaException e) {
1194:                        // nothing to do
1195:                    }
1196:                    if (player.getMediaTime() == 0) {
1197:                        setupKaraokeLines(0, 0);
1198:                        updateKaraoke();
1199:                    } else {
1200:                        clearKaraoke();
1201:                    }
1202:                    setStatus("Starting...");
1203:                    player.start();
1204:                    setStatus("Playing");
1205:                    setFeedback("");
1206:                    // tempo may have changed due to new position
1207:                    updateTempo(null);
1208:                } catch (Throwable t) {
1209:                    error(t);
1210:                }
1211:            }
1212:
1213:            public void closePlayer() {
1214:                if (player != null) {
1215:                    setStatus("Stopping...");
1216:                    try {
1217:                        player.stop();
1218:                    } catch (Exception e) {
1219:                    }
1220:                    setStatus("Closing...");
1221:                    player.close();
1222:                    setStatus("Closed");
1223:                    player = null;
1224:                    initialize();
1225:                }
1226:            }
1227:
1228:            public void pausePlayer() {
1229:                if (player != null) {
1230:                    setStatus("Stopping...");
1231:                    try {
1232:                        player.stop();
1233:                    } catch (Exception e) {
1234:                    }
1235:                    setStatus("Stopped");
1236:                    setFeedback("");
1237:                }
1238:            }
1239:
1240:            public void togglePlayer() {
1241:                if (player != null) {
1242:                    if (player.getState() == Player.STARTED) {
1243:                        pausePlayer();
1244:                    } else {
1245:                        startPlayer();
1246:                    }
1247:                }
1248:            }
1249:
1250:            /** fast forward or fast backward */
1251:            public void skip(boolean backwards) {
1252:                if (player != null) {
1253:                    try {
1254:                        long mTime = player.getMediaTime();
1255:                        // default 10 sec
1256:                        long jump = 10000000;
1257:                        long duration = player.getDuration();
1258:                        if (duration >= 0) {
1259:                            // skip 5%
1260:                            jump = duration / 20;
1261:                            if (jump < 2000000)
1262:                                jump = 2000000; // Skip at least 2 seconds
1263:                        }
1264:                        if (backwards) {
1265:                            // Jump backward
1266:                            setMediaTime(mTime - jump);
1267:                        } else {
1268:                            // Jump forward
1269:                            setMediaTime(mTime + jump);
1270:                        }
1271:                    } catch (IllegalStateException ise) {
1272:                        // thrown when player is closed
1273:                        error(ise);
1274:                    }
1275:                }
1276:            }
1277:
1278:            public void stopAfterTime() {
1279:                int delay = 5000000; // 5 seconds
1280:                StopTimeControl stc = getStopTimeControl();
1281:                if (stc != null) {
1282:                    try {
1283:                        stc.setStopTime(StopTimeControl.RESET);
1284:                        stc.setStopTime(player.getMediaTime() + delay);
1285:                        setFeedback("Stop in " + (delay / 1000000)
1286:                                + " seconds.");
1287:                    } catch (IllegalStateException ise) {
1288:                        error(ise);
1289:                    }
1290:                } else {
1291:                    setFeedback("No StopTimeControl!");
1292:                }
1293:            }
1294:
1295:            public void changeRate(boolean slowdown) {
1296:                int diff = 10000; // 10%
1297:                if (slowdown) {
1298:                    diff = -diff;
1299:                }
1300:                RateControl rc = getRateControl();
1301:                if (rc != null) {
1302:                    int ocr = rc.getRate();
1303:                    int ncr = ocr + diff;
1304:                    int maxRate = rc.getMaxRate();
1305:                    if (maxRate > LIMIT_RATE * 1000) {
1306:                        maxRate = LIMIT_RATE * 1000;
1307:                    }
1308:                    if (ncr >= rc.getMinRate() && ncr <= maxRate) {
1309:                        int ecr = rc.setRate(ncr);
1310:                        setFeedback("New rate: " + toFloatString(ecr, 3) + "%");
1311:                        updateRate(rc);
1312:                        // rate changes effective tempo.
1313:                        updateTempo(null);
1314:                    }
1315:                } else {
1316:                    setFeedback("No RateControl!");
1317:                }
1318:            }
1319:
1320:            public void setMediaTime(long time) {
1321:                if (player == null) {
1322:                    return;
1323:                }
1324:                try {
1325:                    setFeedback("Set MediaTime to " + timeDisplay(time));
1326:                    player.setMediaTime(time);
1327:                    updateTime();
1328:                    clearKaraoke();
1329:                    updateTempo(null);
1330:                } catch (Exception e) {
1331:                    error(e);
1332:                }
1333:            }
1334:
1335:            public void changeVolume(boolean decrease) {
1336:                int diff = 10;
1337:                if (decrease) {
1338:                    diff = -diff;
1339:                }
1340:                VolumeControl vc = getVolumeControl();
1341:                if (vc != null) {
1342:                    int cv = vc.getLevel();
1343:                    cv += diff;
1344:                    vc.setLevel(cv);
1345:                    updateVolume(vc);
1346:                } else {
1347:                    setFeedback("No VolumeControl!");
1348:                }
1349:            }
1350:
1351:            public void toggleMute() {
1352:                VolumeControl vc = getVolumeControl();
1353:                if (vc != null) {
1354:                    vc.setMute(!vc.isMuted());
1355:                    updateVolume(vc);
1356:                } else {
1357:                    setFeedback("No VolumeControl!");
1358:                }
1359:            }
1360:
1361:            public void transpose(boolean down) {
1362:                int diff = 1000; // 1 semitone
1363:                if (down) {
1364:                    diff = -diff;
1365:                }
1366:                PitchControl pc = getPitchControl();
1367:                if (pc != null) {
1368:                    pc.setPitch(pc.getPitch() + diff);
1369:                    updatePitch(pc);
1370:                } else {
1371:                    // if no PitchControl, use FramePositioningControl
1372:                    if (getFramePositioningControl() != null) {
1373:                        skipFrame(down);
1374:                    } else {
1375:                        setFeedback("No PitchControl!");
1376:                    }
1377:                }
1378:            }
1379:
1380:            public void skipFrame(boolean back) {
1381:                int diff = 1; // 1 frame
1382:                if (back) {
1383:                    diff = -diff;
1384:                }
1385:                FramePositioningControl fpc = getFramePositioningControl();
1386:                if (fpc != null) {
1387:                    int res = fpc.skip(diff);
1388:                    updateTime();
1389:                    setFeedback("Skipped: " + res + " frames to "
1390:                            + fpc.mapTimeToFrame(player.getMediaTime()));
1391:                } else {
1392:                    setFeedback("No FramePositioningControl!");
1393:                }
1394:            }
1395:
1396:            private void queryRecording() {
1397:                try {
1398:                    // display the screen to enter the locator
1399:                    Utils.query("Enter a record locator", recordLocator, 200,
1400:                            TextField.URL, new RecordTask(), parent);
1401:                } catch (Exception e) {
1402:                    Utils.error(e, parent);
1403:                }
1404:            }
1405:
1406:            private void startRecording(String locator) {
1407:                try {
1408:                    if (locator == null || locator == "") {
1409:                        Utils.error("No locator set!", parent);
1410:                    } else {
1411:                        // user entered the locator.
1412:                        recordLocator = locator;
1413:                        //Start recording
1414:                        RecordControl rc = getRecordControl();
1415:                        if (rc != null) {
1416:                            rc.stopRecord();
1417:                            rc.reset();
1418:                            rc.setRecordLocation(locator);
1419:                            rc.startRecord();
1420:                        } else {
1421:                            throw new MediaException(
1422:                                    "Could not get RecordControl!");
1423:                        }
1424:                    }
1425:                } catch (Exception e) {
1426:                    Utils.error(e, parent);
1427:                }
1428:            }
1429:
1430:            private void stopRecording() {
1431:                try {
1432:                    // Stop recording
1433:                    final RecordControl rc = getRecordControl();
1434:                    if (rc != null) {
1435:                        rc.stopRecord();
1436:                        // The commit() must be performed in a thread that is not this one:
1437:                        // we are running on the event dispatcher thread.
1438:                        // rc.commit() MIGHT display a security dialog (depending on the URL
1439:                        // that the audio is being recorded to) and the MIDP spec recommends 
1440:                        // performing actions that could bring up a security dialog
1441:                        // on a thread that is NOT the event dispatcher thread.
1442:                        new Thread(new Runnable() {
1443:                            public void run() {
1444:                                try {
1445:                                    rc.commit();
1446:                                    Utils.FYI("Recorded " + recordLocator
1447:                                            + " successfully.", parent);
1448:                                } catch (Exception e) {
1449:                                    Utils.error(e, parent);
1450:                                }
1451:                            }
1452:                        }).start();
1453:                    } else {
1454:                        throw new MediaException("Could not get RecordControl!");
1455:                    }
1456:                } catch (Exception e) {
1457:                    Utils.error(e, parent);
1458:                }
1459:            }
1460:
1461:            private void showHelp() {
1462:                // only available for canvas player
1463:                if (parent instanceof  SimplePlayerCanvas) {
1464:                    ((SimplePlayerCanvas) parent).showHelp();
1465:                }
1466:            }
1467:
1468:            // /////////////////////////// EVENT HANDLERS /////////////////////////////
1469:
1470:            public void commandAction(Command c, Displayable s) {
1471:                if (c == backCommand) {
1472:                    goBack();
1473:                } else if (c == muteCommand || c == unmuteCommand) {
1474:                    mutePressed();
1475:                } else if (c == volCommand) {
1476:                    volPressed();
1477:                } else if (c == metaCommand) {
1478:                    metaPressed();
1479:                } else if (c == loopCommand) {
1480:                    loopPressed();
1481:                } else if (c == stcCommand) {
1482:                    stopAfterTime();
1483:                } else if (c == playCommand || c == stopCommand) {
1484:                    togglePlayer();
1485:                } else if (c == skipFwCommand) {
1486:                    skip(false);
1487:                } else if (c == skipBwCommand) {
1488:                    skip(true);
1489:                } else if (c == rewindCommand) {
1490:                    setMediaTime(0);
1491:                } else if (c == rateCommand) {
1492:                    ratePressed();
1493:                } else if (c == tempoCommand) {
1494:                    tempoPressed();
1495:                } else if (c == pitchCommand) {
1496:                    pitchPressed();
1497:                } else if (c == fullScreenCommand) {
1498:                    fullScreenPressed();
1499:                } else if (c == normalScreenCommand) {
1500:                    normalScreenPressed();
1501:                } else if (c == startRecordCommand) {
1502:                    queryRecording();
1503:                } else if (c == stopRecordCommand) {
1504:                    stopRecording();
1505:                } else if (c == helpCommand) {
1506:                    showHelp();
1507:                } else if (s != display) {
1508:                    // e.g. when list item in MetaData display list is pressed
1509:                    goBack();
1510:                }
1511:            }
1512:
1513:            private synchronized void startDisplayTimer() {
1514:                if (timeDisplayTask == null) {
1515:                    timeDisplayTask = new SPTimerTask();
1516:                    guiTimer.scheduleAtFixedRate(timeDisplayTask, 0,
1517:                            timerInterval);
1518:                }
1519:            }
1520:
1521:            private synchronized void stopDisplayTimer() {
1522:                if (timeDisplayTask != null) {
1523:                    timeDisplayTask.cancel();
1524:                    timeDisplayTask = null;
1525:                    updateTime();
1526:                }
1527:            }
1528:
1529:            public void playerUpdate(Player plyr, String evt, Object evtData) {
1530:                try {
1531:                    // special case: end-of-media, but loop count>1 !
1532:                    if (evt == END_OF_MEDIA
1533:                            && plyr.getState() == Player.STARTED) {
1534:                        setFeedback("Looping");
1535:                        return;
1536:                    }
1537:                    if (evt == CLOSED || evt == ERROR || evt == END_OF_MEDIA
1538:                            || evt == STOPPED_AT_TIME || evt == STOPPED) {
1539:                        stopDisplayTimer();
1540:                    }
1541:                    if (evt == END_OF_MEDIA || evt == STOPPED_AT_TIME
1542:                            || evt == STOPPED || evt == ERROR) {
1543:                        display.removeCommand(stopCommand);
1544:                        display.addCommand(playCommand);
1545:                        changeSongDisplayCounter = 0;
1546:                        currSongDisplay = 0;
1547:                        updateSongDisplay();
1548:                    }
1549:                    // Sun-specific event for karaoke lyrics
1550:                    if (evt.equals("com.sun.midi.lyrics")) {
1551:                        // META data
1552:                        byte[] data = (byte[]) evtData;
1553:                        if (data != null && (evtData instanceof  byte[])
1554:                                && data.length > 0) {
1555:                            if (Utils.DEBUG)
1556:                                System.out.println("META event 0x"
1557:                                        + Integer.toHexString(data[0] & 0xFF));
1558:                            switch (data[0]) {
1559:                            case 0x01: // Text (commonly used for Karaoke, but not sent if Player is in Karaoke mode)
1560:                                // fall through
1561:                            case 0x05: // Lyrics (isn't this meant for Karaoke ??)
1562:                                if (karaokeMode) {
1563:                                    break;
1564:                                }
1565:                                // fall through if not Karaoke
1566:                            case 0x06: // marker
1567:                                // fall through
1568:                            case 0x07: // Cue point
1569:                                String text = new String(data, 1,
1570:                                        data.length - 1);
1571:                                setFeedback(text);
1572:                                if (Utils.DEBUG)
1573:                                    System.out
1574:                                            .println("META event 0x"
1575:                                                    + Integer
1576:                                                            .toHexString(data[0] & 0xFF)
1577:                                                    + ": " + text);
1578:                                break;
1579:                            case 0x51: // Tempo
1580:                                updateTempo(null);
1581:                                break;
1582:                            case LYRICS_EVENT: // inofficial lyrics event: data 1-3 pos, 4-6 length
1583:                                int kPos = (data[1] << 16) | (data[2] << 8)
1584:                                        | (data[3] & 0xFF);
1585:                                int kLen = (data[4] << 16) | (data[5] << 8)
1586:                                        | (data[6] & 0xFF);
1587:                                setupKaraokeLines(kPos, kLen);
1588:                                updateKaraoke();
1589:                                break;
1590:                            //case 0x58: // Time Signature
1591:                            //case 0x59: // Key Signature
1592:                            //case 0x7F: // Proprietary
1593:                            }
1594:                        }
1595:                    }
1596:
1597:                    if (evt == STARTED) {
1598:                        if (songDisplayNames.length > 1) {
1599:                            changeSongDisplayCounter = SONG_DISPLAY_COUNTER * 2;
1600:                        }
1601:                        startDisplayTimer();
1602:                        display.addCommand(stopCommand);
1603:                        display.removeCommand(playCommand);
1604:                    } else if (evt == DEVICE_UNAVAILABLE) {
1605:                        setFeedback("Audio device not available!");
1606:                    } else if (evt == BUFFERING_STARTED) {
1607:                        setFeedback("Buffering started");
1608:                    } else if (evt == BUFFERING_STOPPED) {
1609:                        setFeedback("Buffering stopped");
1610:                    } else if (evt == CLOSED) {
1611:                        setFeedback("Closed");
1612:                    } else if (evt == DURATION_UPDATED) {
1613:                        setFeedback("Duration updated");
1614:                        durationUpdated();
1615:                    } else if (evt == END_OF_MEDIA) {
1616:                        setStatus("End of media.");
1617:                        setFeedback("");
1618:                    } else if (evt == ERROR) {
1619:                        setFeedback("Error: " + ((String) evtData));
1620:                    } else if (evt == RECORD_STARTED) {
1621:                        isRecording = true;
1622:                        display.addCommand(stopRecordCommand);
1623:                        display.removeCommand(startRecordCommand);
1624:                        setFeedback("Recording Started");
1625:                    } else if (evt == RECORD_STOPPED) {
1626:                        isRecording = false;
1627:                        display.addCommand(startRecordCommand);
1628:                        display.removeCommand(stopRecordCommand);
1629:                        setFeedback("Recording Stopped");
1630:                    } else if (evt == SIZE_CHANGED) {
1631:                        VideoControl vc = (VideoControl) evtData;
1632:                        setFeedback("Resize to " + vc.getDisplayWidth() + "x"
1633:                                + vc.getDisplayHeight());
1634:                    } else if (evt == STOPPED_AT_TIME) {
1635:                        setStatus("Stopped at time.");
1636:                        setFeedback("");
1637:                    } else if (evt == VOLUME_CHANGED) {
1638:                        VolumeControl vc = (VolumeControl) evtData;
1639:                        setFeedback("New volume: " + vc.getLevel());
1640:                        updateVolume(vc);
1641:                    }
1642:                } catch (Throwable t) {
1643:                    if (Utils.DEBUG)
1644:                        System.out
1645:                                .println("Uncaught Exception in SimplePlayerGUI.playerUpdate()");
1646:                    error(t);
1647:                }
1648:            }
1649:
1650:            public void itemStateChanged(Item item) {
1651:                if (item != null) {
1652:                    if (item == gauge) {
1653:                        switch (gaugeMode) {
1654:                        case GAUGE_VOLUME:
1655:                            VolumeControl vc = getVolumeControl();
1656:                            if (vc != null) {
1657:                                vc.setLevel(gauge.getValue());
1658:                                updateVolume(vc);
1659:                            }
1660:                            break;
1661:                        case GAUGE_RATE:
1662:                            RateControl rc = getRateControl();
1663:                            if (rc != null) {
1664:                                rc.setRate((gauge.getValue() * 1000)
1665:                                        + rc.getMinRate());
1666:                                updateRate(rc);
1667:                            }
1668:                            break;
1669:                        case GAUGE_TEMPO:
1670:                            TempoControl tc = getTempoControl();
1671:                            if (tc != null) {
1672:                                tc.setTempo((gauge.getValue() + 1) * 1000);
1673:                                updateTempo(tc);
1674:                            }
1675:                            break;
1676:                        case GAUGE_PITCH:
1677:                            PitchControl pc = getPitchControl();
1678:                            if (pc != null) {
1679:                                pc.setPitch((gauge.getValue() * 1000)
1680:                                        + pc.getMinPitch());
1681:                                updatePitch(pc);
1682:                            }
1683:                            break;
1684:                        } // switch
1685:                    }
1686:                }
1687:            }
1688:
1689:            // ///////////////// PAUSE / RESUME ///////////////////////// //
1690:
1691:            /**
1692:             * Stop the player and the display thread.
1693:             * Some VM's may stop players and threads
1694:             * on their own, but for consistent user
1695:             * experience, it's a good idea to explicitly
1696:             * stop and start resources such as player
1697:             * and threads.
1698:             */
1699:            public synchronized void pauseApp() {
1700:                if (player != null && player.getState() >= Player.STARTED) {
1701:                    // player was playing, so stop it.
1702:                    try {
1703:                        player.stop();
1704:                    } catch (MediaException e) {
1705:                        // nothing we can do here
1706:                    }
1707:                    // make sure that the timer does not keep on
1708:                    // displaying (we're not sure that the STOPPED
1709:                    // event will reach us before the VM becomes
1710:                    // suspended)
1711:                    stopDisplayTimer();
1712:                    // make sure to restart upon resume
1713:                    restartOnResume = true;
1714:                } else {
1715:                    restartOnResume = false;
1716:                }
1717:            }
1718:
1719:            /**
1720:             * If the player was playing when the MIDlet was paused,
1721:             * then the player will be restarted here.
1722:             */
1723:            public synchronized void resumeApp() {
1724:                if (player != null && restartOnResume) {
1725:                    try {
1726:                        player.start();
1727:                    } catch (MediaException me) {
1728:                        error(me);
1729:                    }
1730:                    // player.start() will trigger the display timer
1731:                    // to be started, so we don't need to explicitely
1732:                    // call startDisplayTimer().
1733:                }
1734:                restartOnResume = false;
1735:            }
1736:
1737:            // ///////////////// INNER CLASSES /////////////////// //
1738:
1739:            /**
1740:             * Inner class for handling the query listener
1741:             * when entering the recording URL
1742:             */
1743:            private class RecordTask implements  Utils.QueryListener {
1744:                private RecordTask() {
1745:                }
1746:
1747:                public void start(String location) {
1748:                    startRecording(location);
1749:                }
1750:
1751:                // interface Utils.QueryListener
1752:                // used for entering the filename of a recording
1753:                public void queryOK(String text) {
1754:                    start(text);
1755:                }
1756:
1757:                public void queryCancelled() {
1758:                    // don't do anything if query is cancelled.
1759:                    // the previous visible Displayable will be
1760:                    // displayed automatically
1761:                }
1762:
1763:            }
1764:
1765:            /**
1766:             * The timer task that will be called every timerInterval
1767:             * milliseconds
1768:             */
1769:            private class SPTimerTask extends TimerTask {
1770:                public void run() {
1771:                    updateTime();
1772:                    if (redisplayKaraokeCounter > 0) {
1773:                        redisplayKaraokeCounter--;
1774:                        if (redisplayKaraokeCounter == 0) {
1775:                            displayNextKaraokePhrase();
1776:                        }
1777:                    }
1778:                    if (changeSongDisplayCounter > 0
1779:                            && songDisplayNames.length > 0) {
1780:                        changeSongDisplayCounter--;
1781:                        if (changeSongDisplayCounter == 0) {
1782:                            currSongDisplay = (currSongDisplay + 1)
1783:                                    % songDisplayNames.length;
1784:                            updateSongDisplay();
1785:                            changeSongDisplayCounter = SONG_DISPLAY_COUNTER;
1786:                            if (currSongDisplay == 0) {
1787:                                changeSongDisplayCounter *= 2;
1788:                            }
1789:                        }
1790:                    }
1791:                }
1792:            }
1793:
1794:            // ////////////////// INNER INTERFACES ///////////////////// //
1795:
1796:            /**
1797:             * This interface is implemented by the Displayable
1798:             * which uses this class. It provides the main screen.
1799:             */
1800:            interface Parent extends Utils.BreadCrumbTrail {
1801:                public Utils.BreadCrumbTrail getParent();
1802:
1803:                public String getTitle();
1804:
1805:                // callbacks for display matters of the main player screen
1806:                public void setupDisplay(); // called after the media is prefetched
1807:
1808:                public void setStatus(String s);
1809:
1810:                public void setFeedback(String s);
1811:
1812:                public void setFileTitle(String s);
1813:
1814:                public void updateKaraoke();
1815:
1816:                public void updateTime();
1817:
1818:                public void updateRate(); // and tempo
1819:
1820:                public void updateDisplay();
1821:
1822:                public void fullScreen(boolean value);
1823:            }
1824:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.