Phát tiếng beep ở loa con trên mainboard

JackV

Administrator
Staff member
Hi anh em, tớ có vấn đề cùng anh em nghiên cứu đây :D

Thường thì khi chúng ta khởi động máy tính lên sẽ có âm báo tình trạng phần cứng từ cái loa chút xíu trên mainboard, nó rất hữu ích khi chúng ta không cần phải gắn loa vào mới biết vấn đề gì. Tớ viết phần mềm ứng dụng và muốn dùng nó để báo lỗi nhưng tìm trên mạng đa phần là nói về 2 cách sau:
Print the ASCII Bell character to the console
Code:
public class TestBeep {
  public static main(String args[]) {
    // ASCII bell
    System.out.print("\007");
    System.out.flush();
  }
}
Starting with JDK 1.1, use the beep method in the Toolkit
Code:
import java.awt.*;
public class Beep {
  public static void main(String args[]) {
    Toolkit.getDefaultToolkit().beep();
  }
}
Hai cách trên dùng đúng thì cũng chỉ có một số main đặc biệt mới dùng được, đa phần là tiếng beep đó phát ra loa thùng.

Sau một vòng lớp trên internet mình cũng tìm được một cách khác là dùng JNI cho chương trình gọi native method trong một file .dll (Tất nhiên là nó chỉ giới hạn là windows rồi).
Trong thư mục đính kèm bạn có thể giải nén ra và chạy file run PlaySound.bat thì sẽ nghe được một giai điệu từ cái loa nho nhỏ trên mainboard.

Vấn đề bắt đầu thực sự là vấn đề khi đưa nó vào chương trình để kết hợp với các class khác.
  • Chạy main class PlaySound ở default package thì chương trình chạy bình > Có điệu nhạc.
  • Chạy main class PlaySound ở package withPackage thì bị lỗi java.lang.UnsatisfiedLinkError: withPackage.InternalSpeaker.beepPCSpeaker(II)V
Vấn đề chính là tớ muốn các class ở các package khác phải import được được class phát âm thanh, trường hợp này nếu phát được âm thanh thì nó nằm ở defautpackage tức là không có package nên không thể import được, không thể viết chương trình để tất cả các class cùng một chỗ được.

Tớ đã sử dụng đến chiêu
Code:
        try {
            Class c = Class.forName("InternalSpeaker");
            Method m = c.getMethod("play", new Class[]{int.class, int.class});
            m.invoke(c.newInstance(), new int[]{880, 500});
        } catch (Exception ex) {
            ex.printStackTrace();
        }
để load class InternalSpeaker.class không có package thì gặp thông báo Class testCallDefaultPackageClass.Test can not access a member of class InternalSpeaker with modifiers "public" khi bỏ public của phương thức /*public*/ synchronized void play(int frequency, int duration) trong class InternalSpeaker đi thì nhận được thông báo lỗi java.lang.NoSuchMethodException: InternalSpeaker.play(int, int)

Đến đây tớ bớ tay :( Bạn nào có nhiều kinh nghiệm sử dụng các native lib thì chia sẻ với.

Tớ đưa kèm project netbeans và đầy đủ file cho các bạn test thử, mong được chia sẻ.
 

Attachments

JackV

Administrator
Staff member
Anh em nào đang nghiên cứu cài này cùng tớ vậy ;;)

Tớ định viết thành javabean để import nhưng không có package thì các class trong các package cũng không thể import được.

Định viết thành một chương trình riêng biệt rồi thông qua dữ liệu trung gian của 2 chương trình để phát âm báo nhưng như thế thì thành ra phải chạy nhiều chương trình để làm một công tác chung.

Anh em có sáng kiến nào mới hơn không ;;)
 

KiraArus

Member
28/9/11
145
23
18
HCM
Anh em nào đang nghiên cứu cài này cùng tớ vậy ;;)

Tớ định viết thành javabean để import nhưng không có package thì các class trong các package cũng không thể import được.

Định viết thành một chương trình riêng biệt rồi thông qua dữ liệu trung gian của 2 chương trình để phát âm báo nhưng như thế thì thành ra phải chạy nhiều chương trình để làm một công tác chung.

Anh em có sáng kiến nào mới hơn không ;;)
chạy lòng vòng một hồi vớ được cái này, hok biết có được không:D
add thư viện :http://www.mediafire.com/?60rzqnlawizz41l
PHP:
public static void main(String[] args) {
        com.softsynth.jsyn.SawtoothOscillatorBL osc;
        com.softsynth.jsyn.LineOut lineOut;
        // Start JSyn synthesizer.
        Synth.startEngine(0);

        // Create some unit generators.
        osc = new com.softsynth.jsyn.SawtoothOscillatorBL();
        lineOut = new com.softsynth.jsyn.LineOut();

        // Connect oscillator to both left and right channels of output.
        osc.output.connect(0, lineOut.input, 0);
        osc.output.connect(0, lineOut.input, 1);

        // Start the unit generators so they make sound.
        osc.start();
        lineOut.start();

        // Set the frequency of the oscillator to 200 Hz.
        osc.frequency.set(200.0);
        osc.amplitude.set(0.8);

        // Sleep for awhile so we can hear the sound.
        Synth.sleepForTicks(400);

        // Change the frequency of the oscillator.
        osc.frequency.set(300.0);
        Synth.sleepForTicks(400);

        // Stop units and delete them to reclaim their resources.
        osc.stop();
        lineOut.stop();
        osc.delete();
        lineOut.delete();

        // Stop JSyn synthesizer.
        Synth.stopEngine();
    }
nguồn :http://www.softsynth.com/jsyn/
 

Joe

Thành viên VIP
21/1/13
3,024
1,336
113
Hi JackV
I hope that Mr Joe can provide a solution for me about that (Java make a beep sound by using the mini speaker on mainboard).
A piece of cakeb-)I've checked the C code and found no error, no error with the java sources, too (InternalSpeaker.java and PlaySound.java). I suspect your trouble lies within the famous system-dependent environment. I don't know how you set your PATH in your working environment so I can't tell you how to correct it.
BUT you can run your beeping song as following (sounds a bit hm...huh... disharmonious ...)
PHP:
D:\Test>dir
10.04.2013  13:49    <DIR>          .
10.04.2013  13:49    <DIR>          ..
10.04.2013  13:14    <DIR>          C
10.04.2013  13:18    <DIR>          classes
10.04.2013  13:40            3.805 InternalSpeaker.java
10.04.2013  13:09            36.321 PlayMainboardBeepSound.zip
10.04.2013  13:40            1.983 PlaySound.java
 ...

D:\Test>dir .\classes
10.04.2013  13:18    <DIR>          .
10.04.2013  13:18    <DIR>          ..
31.03.2004  01:58            28.672 beep.dll
10.04.2013  13:40              690 InternalSpeaker.class
10.04.2013  13:41              925 PlaySound.class
...
D:\Test>java -Djava.library.path=".\classes" PlaySound
D:\Test>
1) I copied the beep.dll to my directory where the compiled class are stored (not a must),
2) java -Djava.library.path=".\classes" PlaySound
3) do...mi..fa...bla...bla...
 

Joe

Thành viên VIP
21/1/13
3,024
1,336
113
Hi Joe!
The problem is simple, please run the withPackage.PlaySound.java and no bip sound out

D:Test>java -Djava.library.path=".\classes\withPackage" PlaySound
Again a piece of cake...JackV, because you include the source InternalSpeaker in the withPackage you have to re-generate the JNI header file so that JVM knows where to find. In other words: You must include the generated C-code in the package. That why you got this terror
Code:
Exception in thread "main" java.lang.UnsatisfiedLinkError: withPackage.InternalSpeaker.beepPCSpeaker(II)V
Just run
Code:
javah -o withPackage.InternalSpeaker.h withPackage.InternalSpeaker
then you get this (compare it to your original one then you'll see the discrepancy)
PHP:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class withPackage_InternalSpeaker */

#ifndef _Included_withPackage_InternalSpeaker
#define _Included_withPackage_InternalSpeaker
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:    withPackage_InternalSpeaker
* Method:    beepPCSpeaker
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_withPackage_InternalSpeaker_beepPCSpeaker
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif
 

Joe

Thành viên VIP
21/1/13
3,024
1,336
113
...Sorry JackV, I've almost forgotten. You need a C/C++ compiler and the source beep.c(pp) to recreate a new beep.dll with the newly generated JNI stub. Otherwise it won't work. Or just use it as it is:D
 

JackV

Administrator
Staff member
...Sorry JackV, I've almost forgotten. You need a C/C++ compiler and the source beep.c(pp) to recreate a new beep.dll with the newly generated JNI stub. Otherwise it won't work. Or just use it as it is:D
Could you please recreate a new beep.dll with the newly generated JNI stub to sole this problem, take a look in speaker10.zip.
Build_Beep_Dll.bat file
PHP:
rem =============================================
rem Erzeugen einer DLL fuer JNI Glue
rem Java Klasse : InternalSpeaker.class
rem Header      : InternalSpeaker.h
rem C Code      : InernalSpeakerImp.c
rem Author      : Martin Mosisch, mmosisch@web.de
rem =============================================
cl -Ic:\java\include -Ic:\java\include\win32 -LD InternalSpeakerImp.c -Febeep.dll
Build_Headerdatei.bat file
PHP:
rem ==============================================
rem Creating the Header File for JNI Glue
rem Author      : Martin Mosisch, mmosisch@web.de
rem ==============================================
javah -jni InternalSpeaker
 

Joe

Thành viên VIP
21/1/13
3,024
1,336
113
Could you please recreate a new beep.dll with the newly generated JNI stub to sole this problem, take a look in speaker10.zip.
Nope! I don't have a C compiler on my Window. Just on my SunOS. Here is the InternalSpeakerImp.c
PHP:
#include <windows.h>
#include <jni.h>
#include "InternalSpeaker.h"
#include <stdio.h>

/**
* JNI-Glue to make the internal pc speaker beep.
* @author Martin Mosisch
* E-Mail : MMosisch@web.de
*/
JNIEXPORT void JNICALL
Java_withPackage_InternalSpeaker_beepPCSpeaker(JNIEnv *env, jobject obj, jint frequency ,jint duration)
{
Beep(
frequency, // DWORD dwFreq frequency
duration   // DWORD duration
);
}
 

Joe

Thành viên VIP
21/1/13
3,024
1,336
113
Yes, thank Joe, i will try :D
I can't let you down and because I don't have a C++ on Window (except on my SunOS) I designed this piece for you as a booby prize:))
Compile it and listen
PHP:
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.text.*;
import javax.sound.midi.*;
// Joe T. Nartca
public class JoeDrummer extends JFrame {
  private MidiChannel channel;
  public static void main(String[] args) throws Exception {
      int speed = (args.length == 0)? 70 : Integer.parseInt(args[0]);
      (new JoeDrummer( )).init(speed);
  }
  private int speed;
  private JLabel drum;
  public JoeDrummer( ) {
      super("JoeTheDrummer");
  }
  private void init(int speed) throws Exception {
      this.speed = speed;
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      Synthesizer synth = MidiSystem.getSynthesizer( );
      synth.open( );
      //
      channel = synth.getChannels( )[9];
      addKeyListener(new KeyAdapter( ) {
        public void keyPressed(KeyEvent e) {
            actionKeyPressed(e);
        }
        public void keyReleased(KeyEvent e) {
            actionKeyFreed(e);
        }
      });
      addMouseMotionListener(new MouseMotionAdapter( ) {
        public void mouseMoved(MouseEvent me) {
            getSpeed(me);
        }
      });
      drum = new JLabel("Press Key between 0..Z you'll hear how Joe drums....");
      drum.setFont(new Font("Times",Font.BOLD, 20));
      JPanel jp = new JPanel();
      jp.add(drum);
      add("North", jp);
      setSize(520, 70);
      setVisible(true);
  }
  //qw
  private void actionKeyPressed(KeyEvent ke) {
      int key = ke.getKeyCode( );
      if (key >= 30 && key <= 122) channel.noteOn(key, speed);
      drum.setText("Joe drums @"+(char)key);
  }
  private void actionKeyFreed(KeyEvent ke) {
      int key = ke.getKeyCode( );
      if (key >= 30 && key <= 122) channel.noteOff(key);
      drum.setText("Joe drummed @"+(char)key);
  }
  private void getSpeed(MouseEvent me) {
      speed = me.getX( );
      drum.setText("New DrummingSpeed for Joe: "+speed);
  }
}
Just compile and play...The movement of your mouse defines the speed...=))
 

Attachments

Joe

Thành viên VIP
21/1/13
3,024
1,336
113
@Joe, just for fun, right ;))
a new PURE java booby prize
PHP:
import java.util.*;
import javax.sound.sampled.*;
public class Beeping {
  private float frequency = 8000f;
  public Beeping( ) { }
  public void playSound(int hertz, int duration, double volume) throws Exception {

      if (hertz <= 0) hertz = 800;
      if (duration <= 0) duration = 500; // 0.5sec
      if (volume > 1.0 || volume < 0.0) volume = 0.5;
      byte[] buf = new byte[(int)frequency * duration / 1000];
      for (int i = 0; i < buf.length; ++i)
      buf[i] = (byte)(Math.sin(i / (frequency / hertz) * 2.0 * Math.PI) * 127.0 * volume);
      // produce the frequency wave
      int max1 = buf.length / 2;
      int max2 = (int) (frequency / 100.0);
      for (int i = 0, l = buf.length-1; i < max1 && i < max2; ++i, --l) {
        buf[i] = (byte)(buf[i] * i / (frequency / 100.0));
        buf[l] = (byte)(buf[l] * i / (frequency / 100.0));
      }
      AudioFormat af = new AudioFormat(frequency, 8, 1, true, false);
      SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
      sdl.open(af);
      sdl.start();
      sdl.write(buf,0,buf.length);
      sdl.drain();
      sdl.close();
  }
}
and your PlaySound.java is now PlayJoeSound.java
PHP:
public class PlayJoeSound {
  public static void main(String[] args) {
      PlayJoeSound pjs = new PlayJoeSound( );
      try {
        double vol = (args.length == 0)? 0.1 : Double.parseDouble(args[0]);
        pjs.playMelody(vol);
      } catch (Exception e) {
        e.printStackTrace();
      }
  }
  private Beeping beep;
  public PlayJoeSound( ) {
      beep = new Beeping( );
  }
  public void playMelody(double vol) throws Exception {
      beep.playSound(391,250, vol);//G
      beep.playSound(523,500, vol);//C
      beep.playSound(466,250, vol);//H,A#
      beep.playSound(523,300, vol);//C
      beep.playSound(659,300, vol);//E
      beep.playSound(587,500, vol);//D
      beep.playSound(523,250, vol);//C
      beep.playSound(587,300, vol);//D
      beep.playSound(659,250, vol);//E
      beep.playSound(587,250, vol);//D
      beep.playSound(523,300, vol);//C
      beep.playSound(523,250, vol);//C
      beep.playSound(659,250, vol);//E
      beep.playSound(784,250, vol);//G
      beep.playSound(880,500, vol);//A
      beep.playSound(880,250, vol);//A
      beep.playSound(784,300, vol);//G
      beep.playSound(659,250, vol);//E
      beep.playSound(659,250, vol);//E
      beep.playSound(784,300, vol);//G
      beep.playSound(880,500, vol);//A
      beep.playSound(880,250, vol);//A
      beep.playSound(784,300, vol);//G
      beep.playSound(659,250, vol);//E
      beep.playSound(659,250, vol);//E
      beep.playSound(523,250, vol);//C
      beep.playSound(587,500, vol);//D
      beep.playSound(523,250, vol);//C
      beep.playSound(587,300, vol);//D
      beep.playSound(659,250, vol);//E
      beep.playSound(587,250, vol);//D
      beep.playSound(523,300, vol);//C
      beep.playSound(440,250, vol);//A
      beep.playSound(440,250, vol);//A
      beep.playSound(391,300, vol);//G
      beep.playSound(523,500, vol);//C
  }
}//end
Jovial Jackv ---- Have fun !
 
  • Like
Reactions: JackV

JackV

Administrator
Staff member
a new PURE java booby prize
PHP:
import java.util.*;
import javax.sound.sampled.*;
public class Beeping {
  private float frequency = 8000f;
  public Beeping( ) { }
  public void playSound(int hertz, int duration, double volume) throws Exception {

      if (hertz <= 0) hertz = 800;
      if (duration <= 0) duration = 500; // 0.5sec
      if (volume > 1.0 || volume < 0.0) volume = 0.5;
      byte[] buf = new byte[(int)frequency * duration / 1000];
      for (int i = 0; i < buf.length; ++i)
      buf[i] = (byte)(Math.sin(i / (frequency / hertz) * 2.0 * Math.PI) * 127.0 * volume);
      // produce the frequency wave
      int max1 = buf.length / 2;
      int max2 = (int) (frequency / 100.0);
      for (int i = 0, l = buf.length-1; i < max1 && i < max2; ++i, --l) {
        buf[i] = (byte)(buf[i] * i / (frequency / 100.0));
        buf[l] = (byte)(buf[l] * i / (frequency / 100.0));
      }
      AudioFormat af = new AudioFormat(frequency, 8, 1, true, false);
      SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
      sdl.open(af);
      sdl.start();
      sdl.write(buf,0,buf.length);
      sdl.drain();
      sdl.close();
  }
}
and your PlaySound.java is now PlayJoeSound.java
PHP:
public class PlayJoeSound {
  public static void main(String[] args) {
      PlayJoeSound pjs = new PlayJoeSound( );
      try {
        double vol = (args.length == 0)? 0.1 : Double.parseDouble(args[0]);
        pjs.playMelody(vol);
      } catch (Exception e) {
        e.printStackTrace();
      }
  }
  private Beeping beep;
  public PlayJoeSound( ) {
      beep = new Beeping( );
  }
  public void playMelody(double vol) throws Exception {
      beep.playSound(391,250, vol);//G
      beep.playSound(523,500, vol);//C
      beep.playSound(466,250, vol);//H,A#
      beep.playSound(523,300, vol);//C
      beep.playSound(659,300, vol);//E
      beep.playSound(587,500, vol);//D
      beep.playSound(523,250, vol);//C
      beep.playSound(587,300, vol);//D
      beep.playSound(659,250, vol);//E
      beep.playSound(587,250, vol);//D
      beep.playSound(523,300, vol);//C
      beep.playSound(523,250, vol);//C
      beep.playSound(659,250, vol);//E
      beep.playSound(784,250, vol);//G
      beep.playSound(880,500, vol);//A
      beep.playSound(880,250, vol);//A
      beep.playSound(784,300, vol);//G
      beep.playSound(659,250, vol);//E
      beep.playSound(659,250, vol);//E
      beep.playSound(784,300, vol);//G
      beep.playSound(880,500, vol);//A
      beep.playSound(880,250, vol);//A
      beep.playSound(784,300, vol);//G
      beep.playSound(659,250, vol);//E
      beep.playSound(659,250, vol);//E
      beep.playSound(523,250, vol);//C
      beep.playSound(587,500, vol);//D
      beep.playSound(523,250, vol);//C
      beep.playSound(587,300, vol);//D
      beep.playSound(659,250, vol);//E
      beep.playSound(587,250, vol);//D
      beep.playSound(523,300, vol);//C
      beep.playSound(440,250, vol);//A
      beep.playSound(440,250, vol);//A
      beep.playSound(391,300, vol);//G
      beep.playSound(523,500, vol);//C
  }
}//end
Jovial Jackv ---- Have fun !
It's not fun :( not for my situation.
Thank you Joe. I want to hear sound from the small speakers on mainboard, not from speaker or headphone.
 

Attachments

Joe

Thành viên VIP
21/1/13
3,024
1,336
113
OKAY JackV
I misunderstood you profoundly :(