Computerzeit beim Programieren einbeziehen

...komplette Frage anzeigen

2 Antworten

In C kann man Zeit ja über time.h einbinden. Das funktioniert in Java natürlich etwas anders, aber das wurde ja bereits in der anderen Antwort gelöst.

Was ich mir aber durchaus vorstellen könnte:

pritnf("\a");

Löst in C diesen charmanten Mainboard-Piepston aus. Da Java ziemlich viel von C übernommen hat, könnte ich mit gut vorstellen, dass das auch in Java geht. Nur musst du das selbst testen, ich hab schließlich kein Eclipse installiert.

servus1996 30.06.2013, 18:18

Nein, hat leider nicht funktioniert.

0
Infam0usLight 30.06.2013, 18:22
@servus1996

Equivalent wäre das in Java

System.out.println("\007");

Funktioniert aber nur, wenn der Standardausgabestream in ne Konsole führt.

0
servus1996 01.07.2013, 11:35
@servus1996

Dank deines Beispiels habe ich jetz das mit dem "verpackten" code (hoffentlich) verstanden...

Aber wie ich das wichtige in meinem code wieder einpacke ist mir nicht klar, daher kann ich ihn auch nicht verbessern:(

Aber ob ich deinen Code überhaupt verstanden habe:

Clip clip = AudioSystem.getClip();
AudioInputStream ais = AudioSystem.getAudioInputStream(new File(filename));

Das generiert einen Ton und speichert ihn sozusagen in ais?!

          **clip.open(ais);

            clip.start();

            Thread.sleep(1);
            clip.drain();
            clip.close();**

Dieser Teil öffnet den Clip, spielt ihn ab, und beendet ihn dann wieder?!

              return true;
        }
        catch (Exception ex)
        {
            Logger.getLogger(Beep.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }

Dieser Teil ist mir dann aber unklar... Warum wird da ein Boolean Wert zurückgegeben und wofür ist diese letzte Zeile zuständig?

mfg

0

Das sind aber zwei völlig verschiedene Dinge: Pip machen und Zeit messen, gelle?!

servus1996 29.06.2013, 22:31

Ja eig. schon. Aber ich will ja, das er die Zeit misst und wenn es die richtige ist piep macht^^ Hast du eine Idee wie ich das schreiben könnte?

0
WhiteGandalf 29.06.2013, 22:44
@servus1996

Mal sehn... Zeit messen ist einfach: http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#nanoTime()

Den Peep zu erzeugen habe ich jetzt relativ aufwendig über das Java-Sound-System in Erinnerung. Also ich habe mit dem Ding schon mal gebastelt, muß da aber erstmal wieder auffrischen... (Das geht dort relativ Low-Level-mäßig mit Mixer-Signalleitung und Audioformaten über die Bühne, wo man sich um alle möglichen Details kümmern muß...)

Gibt das nicht irgendwie eine einfachere Herangehensweise?? Wo das schon weggekapselt ist? Ich schau mich mal um...

0
servus1996 29.06.2013, 23:03
@WhiteGandalf

Wow, vielen dank für die Seite!!! Werde mich hier mal umschauen.

Sollte ich noch weitere fragen haben melde ich mich einfach?!

Danke nochmal.

0
WhiteGandalf 29.06.2013, 23:18
@servus1996

Klar. Eventuell nimm die Versionsnummer in der URL eins hoch: Die 6 ist schon recht alt; 7 ist aktuell.

0
servus1996 29.06.2013, 23:19
@servus1996

Die Seite die du mir gezeigt hast, schreibt:

beep

public abstract void beep()

Emits an audio beep. Since: JDK1.1

Dieser einfache code funktioniert bei mir aber nicht, ich bekomme da immer mehrer Fehlermeldungen. Hab jetzt nur mal zum Testen einen Button eingefügt -> Action performed und diesen Code reingeschrieben. Was habe ich hier falsch gemacht?

0
WhiteGandalf 30.06.2013, 03:40
@WhiteGandalf

OK: Es geht wohl doch nicht mit dem vereinfachten Zeug. Bei mir kommt jedenfalls auch kein Ton.

Mit dem AudioSystem kannst Du eine vereinfachte Variante der Soundwidergabe benutzen, die auf alle möglichen sophistischen Möglichkeiten der Einflußnahme verzichtet:

static boolean playsound(String filename)
{
    try
    {
        Clip                clip = AudioSystem.getClip();   // vereinfachte Soundausgabe eines vollständigen Soundclips (kein inkrementelles Nachschieben von Audiodaten)
        AudioInputStream    ais = AudioSystem.getAudioInputStream(new File(filename));

        clip.open(ais);
        clip.start();
        Thread.sleep(1);
        clip.drain();
        clip.close();
        return true;
    }
    catch (Exception ex)
    {
        Logger.getLogger(Beep.class.getName()).log(Level.SEVERE, null, ex);
    }
    return false;
}

Normalerweise mußt Du Dich um Formate und das Timing der Widergabe kümmern. Hier wird das alles aus der Audiodatei gezogen und automatisch angepaßt.

"Thread.sleep" ist notwendig, um die im Hintergrund laufende Soundwidergabe anlaufen zu lassen (es wird einmalig eine Prozeßumschaltung erzwungen, so daß der Startcode des Sound-Threads laufen kann). Erst danach kann "drain" benutzt werden, um den Clip von allein bis zu seinem Ende laufen zu lassen.

0
PerfectMuffin 30.06.2013, 07:06
@WhiteGandalf

Ich finde es nur etwas schade, dass man der Ton mittlerweile aus den Lautsprechern kommt und ´nicht mehr wie das schöne alte "Düüüt!" klingt, sondern eher wie ein dumpfes "Bup!"

0
WhiteGandalf 30.06.2013, 09:56
@PerfectMuffin

Das heißt: Bei DIR geht das mit dem "beep"? Kannst Du mal Deine Systemumgebung andeuten?

Fehlt bei mir etwas?

0
PerfectMuffin 30.06.2013, 10:19
@WhiteGandalf

Windows 7 HP 64bit.

Hattest du vielleicht deinen Ton ausgestellt?

In moderneren PCs wird das Geräusch statt vom Computer selbst von den Lautsprechern erzeugt.

Außerdem schent sich das Geräusch je nach Kontext zu unterscheiden, wenn es in normalem Kontext ausgegeben wird, macht es "bup!" und wenn es in der AWT Queue aufgerufen wird "dingggg!"

0
servus1996 30.06.2013, 10:24
@WhiteGandalf

So schaut mein Code derzeit jetzt mit dem was du geschrieben hast aus:

protected boolean btnTestActionPerformed(ActionEvent arg0) { static boolean playsound(String filename){

        try
        {
            clip                clip = AudioSystem.getClip();   // vereinfachte Soundausgabe eines vollständigen Soundclips (kein inkrementelles Nachschieben von Audiodaten)
            AudioInputStream    ais = AudioSystem.getAudioInputStream(new File(filename));

            clip.open(ais);
            clip.start();
            Thread.sleep(1);
            clip.drain();
            clip.close();
            return true;
        }
        catch (Exception ex)
        {
            Logger.getLogger(Beep.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }
}

Leider zeigt es bei mir einige Fehler an:

static boolean playsound(String filename){ Hier unterwellt er mir das Playsound

clip clip = AudioSystem.getClip(); // vereinfachte Soundausgabe eines vollständigen Soundclips (kein inkrementelles Nachschieben von Audiodaten) AudioInputStream ais = AudioSystem.getAudioInputStream(new File(filename)); -> Bei beiden: can not be resolved to a Type

Logger.getLogger(Beep.class.getName()).log(Level.SEVERE, null, ex); ->Beep can not be resolved to a Type

0
WhiteGandalf 30.06.2013, 15:25
@servus1996

Na, das stimmt noch nicht ganz.

Wenn Du das Codeschnipsel in eine anders definierte Funktion einsetzen willst, dann lasse einfach den Funktionsrahmen aus meinem Schnipsel weg!

Klar darfst Du nicht einfach so zwei Funktionsköpfe ineinander schachteln:

void f()
{
    void g()
    {
    }
}

...wird Dir natürlich das "g" bemeckern.

Wenn ich Dir also als Demo hinlege

void g()
{
    ...irgendwas...
}

...und Du möchtest das in einen Funktionsrahmen

void f()
{
    ...hierher...
}

...einsetzen, dann nimm halt nur den Inhalt (das "irgendwas") der Demo!

Da sind wir aber noch an den allergrundlegendsten Grundlagen der Programmierung! Nimm eventuell kleinere Schritte zum Einstieg! Copy & Paste sind zwar nicht schwer zu lernen, aber auch nicht völlig ohne Nachdenken zu haben.

0
WhiteGandalf 30.06.2013, 15:36
@servus1996

Den Logger passe einfach auf Deine Umgebung an! Klar war der bei mir zum Probieren in einer irgendwie benannten Rahmenklasse eingebettet, daher das "Beep.class". Es hätte auch "Schnurzdipups" heißen können.

================

Eventuell sollten wir noch einen Lehrgang für Copy & Paste von Codeschnipseln einfügen!

0
servus1996 30.06.2013, 18:20
@WhiteGandalf

Ich weiß das ist sicher noch etwas zu schwer für mich und das mir hierzu wahrscheinlich die nötigen Grundlagen Fehlen. Brauche das aber und möchte es unbedingt irgendwie schaffen.

Kannst du mir sagen wie genau ich das in meinem Programm schreiben müsste?

Hoffe du kannst mir helfen

mfg

0
WhiteGandalf 30.06.2013, 21:38
@servus1996

Hast Du schon verstanden, um was es bei einem Funktionsrahmen aus Funktionskopf und geschweiften Klammern geht?

Eventuell versuchst Du Dir mal ein Analogie-Beispiel aus dem Alltag vorzustellen:

  • Du kannst Milch in einem Milchpäckchen kaufen.
  • Zum Trinken füllst Du aber den Inhalt zum Beispiel in ein Glas. Nimm jedenfalls mal an, daß Du das so mögen tätest.
  • Dann wirst Du wohl kaum die Verkaufs-Verpackung mit ins Glas stopfen, oder?! Wäre irgendwie... komisch, der Geschmack von Verpackung im Mund...

Dasselbe bei den Funktionen und ihren Inhalten:

  • Du wirst Beispiel-Programmschnipsel immer irgendwie verpackt angeboten bekommen - in Beispiel-Klassen oder in Beispiel-Funktionsrümpfe eingebettet.
  • Zum selber anwenden wirst Du die Beispiele in DEIN EIGENES Programm, welches Deine eigenen Ideen verkörpert, übernehmen wollen. In Deine EIGENEN Klassen und/oder Funktionsrümpfe.
  • Auch da wirst Du die originalen Verpackungen nicht einfach so in Deine eigenen mit hineinquetschen! Das wäre nicht nur redundant, es geht schon allein von der Syntax der Sprache her nicht.

=================

Verständigen wir uns erstmal, wie weit Dein Verständnis da reicht:

  • Was würdest Du denn an dem Beispiel-Schnipsel mit dem Sound als "Inhalt" der Beispiel-Funktion ansehen?
  • Was würdest Du an der von Dir selbst eingerichteten und gewünschten Reaktionsfunktion als Funktionsrahmen ansehen?
  • Letztlich: Wie würdest Du den tatsächlich für Dich relevanten "Inhalt" in Deinen eigenen Funktionsrahmen übernehmen?

Zeig mal einen (korrigierten) Codevorschlag!

0
servus1996 01.07.2013, 16:03
@WhiteGandalf

Dank deines Beispiels habe ich jetz das mit dem "verpackten" code (hoffentlich) verstanden...

Aber wie ich das wichtige in meinem code wieder einpacke ist mir nicht klar, daher kann ich ihn auch nicht verbessern:(

Aber ob ich deinen Code überhaupt verstanden habe:

Clip clip = AudioSystem.getClip(); AudioInputStream ais = AudioSystem.getAudioInputStream(new File(filename));

Das generiert einen Ton und speichert ihn sozusagen in ais?!

      **clip.open(ais);

        clip.start();

        Thread.sleep(1);
        clip.drain();
        clip.close();**

Dieser Teil öffnet den Clip, spielt ihn ab, und beendet ihn dann wieder?!

          return true;
    }
    catch (Exception ex)
    {
        Logger.getLogger(Beep.class.getName()).log(Level.SEVERE, null, ex);
    }
    return false;
}

Dieser Teil ist mir dann aber unklar... Warum wird da ein Boolean Wert zurückgegeben und wofür ist diese letzte Zeile zuständig?

mfg

0
WhiteGandalf 01.07.2013, 22:00
@servus1996

Wir kommen der Lösung näher...

Den Inhalt hast Du also korrekt herausgelöst.

Deinen eigenen Funktionsrahmen hattest Du mit der "Reaktionsfunktion" eines Buttons erschaffen. Die hieß bei Dir...

protected boolean btnTestActionPerformed(ActionEvent arg0)
{
}

===============

Jetzt nochmal zu den einzelnen Elementen:

clip                clip = AudioSystem.getClip();

...erzeugt die gesamte Infrastruktur (das sind mehrere Teile) für die Widergabe eines Sound-Datensatzes. Dazu gehört (alles im "Clip" verpackt):

  • Ein Sound-Ausgabe-Kanal im übergeordneten Betriebssystem. Der beinhaltet in sich wieder eine ganze Reihe Dinge, die aber vom Betriebssystem weggekapselt werden und die wir vielleicht erstmal hinnehmen sollten. Dazu gehört mindestens ein Thread zur Übergabe der Daten aus einem vom Anwendungsprogramm gestellten Puffer an die Sound-Hardware.
  • Puffer für die Übergabe der Sounddaten an den Soundkanal des Betriebssystems.
  • Ein Thread, der die Sounddaten von dem Bereich, wo sie komplett geladen im RAM vorliegen, häppchenweise an den eben genannten Puffer übergibt.

Man kann sich um diese Dinge auch selbst kümmern. Der "Clip" vereinfacht die Verwaltung gewaltig.

AudioInputStream ais = AudioSystem.getAudioInputStream(new File(filename));

...Das legt fest, von wo die Audiodaten geladen werden sollen, sobald sie benötigt werden. In diesem Fall aus einer Audio-Datei.

clip.open(ais);

...Das lädt die Audiodaten (aus der vorher festgelegten Datei) in den RAM. Von wo sie dann häppchenweise weiter verfüttert werden können.

clip.start();

...Das gibt den Befehl, mit dem häppchenweisen Verfüttern an den Audio-Ausgabe-Kanal (also dem Dudeln) zu beginnen.

Allerdings ist dies nur ein indirekter Befehl zum Beginnen, denn das eigentliche Verfüttern erfolgt im Hintergrund-Thread, der im "Clip" versteckt ist. Damit DER überhaupt mal losläuft, bevor wir mit dem nächsten Befehl anweisen, daß er solange laufen soll, bis keine Audiodaten mehr da sind, müssen wir dafür sorgen, daß dieser Hintergrund-Thread überhaupt starten kann. Sonst wird mit den Folgebefehlen die Sound-Ausgabe SOFORT wieder gestoppt, ohne ein einziges Sample zur Soundkarte gebracht zu haben.

Thread.sleep(1);

...bewirkt eine Zwangs-CPU-Aktivitätsabgabe an jeden noch im Hintergrund wartenden Thread. Der vom Clip wartet aufs Loslaufen. Der läuft damit los.

clip.drain();

...Ordnet an, daß auf das Beenden dieses einmal losgelaufenen Hintergrund-Threads gewartet werden soll (wenn er gar nicht erst losgelaufen wäre, wäre er bereits vor dem Loslaufen als beendet angesehen worden). Der läuft nun solange, bis er keine Audio-Daten mehr findet und beendet sich dann selbst. Daraufhin wird die Funktion "drain" beendet.

clip.close();

...Räumt reservierte Ressourcen explizit ab.

=============

Der Rest ist rein persönlicher Beispielrahmen. Weil mir das so gefallen hat. Jeder andere Mensch dieser Welt kann das anders sehen. Du kannst das weglassen, ersetzen, übernehmen völlig nach Lust und Laune.

Wobei: Wenn Du den try-catch-Rahmen wegläßt, mußt Du eine eventuelle Exception durch eine übergeordnete Funktion verarbeiten lassen. Wozu Du das Schmeißen dieser Exceptions in der Funktion deklarieren mußt, die sich NICHT um deren Verarbeitung kümmern müssen soll. Das ist VOLLKOMMEN DEIN BIER.

Du kommst in Java von der Pflicht, Dich letztlich IRGENDWO um Deine Exceptions kümmern zu müssen, nicht weg. Und JE WEITER Du Exceptions über Funktionsgrenzen in die Ferne tragen läßt, DESTO WENIGER steht Dir an den Stellen, wo Du sie letztlich DOCH IRGENDWANN verarbeiten lassen mußt, an Informationen zum ursprünglichen Fehlerkontext zur Verfügung. Du mußt Dir dazu ein System ausdenken, was Dir HILFT, mit den möglichen Ausnahmen so gut es geht klarzukommen.

Das Prinzip, sie zum Probieren erstmal SOFORT bei Entstehung auf die Konsole zu schmeißen, ist für Experimente recht gut zu gebrauchen.

0

Was möchtest Du wissen?