1
\$\begingroup\$

This is my practice program: a simple dialog box using which a user may specify a frequency of a sinus audio signal, and play it via pressing a button. It contains a GUI:

App.java

package net.coderodde.fun;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import net.coderodde.os.beep.Beep;
import net.coderodde.os.beep.WindowsBeep;

/**
 * This class implements a simple program for generating sinus audio signal.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6 (Mar 10, 2019)
 */
public final class App extends Application {

    private final Beep BEEP = new WindowsBeep();

    static {
        try {
            System.loadLibrary("WinBeepDLLx64");
        } catch (UnsatisfiedLinkError error) {
            error.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public void start(Stage stage) throws Exception {
        Text textFrequency = new Text("Frequency (Hz)");
        TextField frequencyField = new TextField();
        Button playButton = new Button("Play");
        VBox vbox = new VBox(textFrequency, frequencyField, playButton);

        playButton.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
                String frequencyInput = frequencyField.getText();
                BEEP.setDuration(1000);

                try {
                    int hz = Integer.parseInt(frequencyInput);
                    BEEP.setFrequency(hz);

                    if (hz <= 0) {
                        Alert alert = new Alert(
                                AlertType.INFORMATION,
                                "Frequency must be at least 1.");

                        alert.showAndWait();
                    } else {
                        BEEP.beep();
                    }
                } catch (NumberFormatException ex) {
                   Alert alert = new Alert(
                           AlertType.ERROR,
                           frequencyInput + " is not an integer.");

                   alert.showAndWait();
                }
            }
        });

        Scene scene = new Scene(vbox);
        stage.setTitle("Generate sinus audio");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Beep.java

package net.coderodde.os.beep;

/**
 * This interface provides facilities for generating a simple sinus audio 
 * signal.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6 (Mar 10, 2019)
 */
public interface Beep {

    /**
     * Returns the beep duration in milliseconds.
     * 
     * @return the beep duration in milliseconds.
     */
    public int getDuration();

    /**
     * Returns the beep frequency in milliseconds.
     * 
     * @return the beep frequency in milliseconds. 
     */
    public int getFrequency();

    /**
     * Sets the beep duration.
     * 
     * @param milliseconds the new beep duration in milliseconds.
     */
    public void setDuration(int milliseconds);

    /**
     * Sets the beep frequency.
     * 
     * @param frequency the new beep frequency in milliseconds.
     */
    public void setFrequency(int frequency);

    /**
     * Produce the bee signal.
     */
    public void beep();
}

WindowsBeep.java

package net.coderodde.os.beep;

/**
 * This class implements the beeping functionality on Windows platform.
 * 
 * @author Rodion "rodde" Efremov
 * @version 1.6
 */
public final class WindowsBeep implements Beep {

    /**
     * The duration of a beep in milliseconds.
     */
    private int beepDuration;

    /**
     * The frequency of a beep in hertzes.
     */
    private int beepFrequency;

    @Override
    public int getDuration() {
        return beepDuration;
    }

    @Override
    public int getFrequency() {
        return beepFrequency;
    }

    @Override
    public void setDuration(int milliseconds) {
        this.beepDuration = milliseconds;
    }

    @Override
    public void setFrequency(int frequency) {
        this.beepFrequency = frequency;
    }

    @Override
    public native void beep();
}

WinBeep.cpp

#include "WinBeep.h"
#include <windows.h>
#include <jni.h>

static const char* CLASS = "net/coderodde/os/beep/WindowsBeep";
static const char* FIELD_DURATION = "beepDuration";
static const char* FIELD_FREQUENCY = "beepFrequency";

static DWORD get_duration(JNIEnv* env, jobject obj) {
    jclass clazz = env->FindClass(CLASS);
    jfieldID fid = env->GetFieldID(clazz, FIELD_DURATION, "I");
    return (DWORD) env->GetIntField(obj, fid);
}

static DWORD get_frequency(JNIEnv* env, jobject obj) {
    jclass clazz = env->FindClass(CLASS);
    jfieldID fid = env->GetFieldID(clazz, FIELD_FREQUENCY, "I");
    return (DWORD) env->GetIntField(obj, fid);
}


JNIEXPORT void JNICALL Java_net_coderodde_os_beep_WindowsBeep_beep(JNIEnv* env, jobject obj) {
    DWORD dwFrequency = get_frequency(env, obj);
    DWORD dwDuration = get_duration(env, obj);
    Beep(dwFrequency, dwDuration);
}

(The other DLL code is here.)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.