Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Procedural Sound  (Read 1451 times)
0 Members and 1 Guest are viewing this topic.
Offline John Teasdale

Senior Newbie





« Posted 2011-01-03 00:28:21 »

I've been looking online for an example off procedural sound. I see how you create the sampled array (google stack overflow how-to-generate-sound-effects-in-java, wont let me post links yet). Bot once I have that array, how do I play it?

Thanks in advance,
John
Online Riven
« League of Dukes »

JGO Overlord


Medals: 744
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #1 - Posted 2011-01-03 00:52:25 »

Simple code to get you started.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
      try
      {
         AudioFormat af = new AudioFormat(sampleRate, 16, 1, true, true);
         DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
         SourceDataLine source = (SourceDataLine) AudioSystem.getLine(info);
         source.open(af);

         // increase master gain to 75%
        Type type = FloatControl.Type.MASTER_GAIN;
         FloatControl fc = (FloatControl) source.getControl(type);
         fc.setValue(fc.getMaximum() * 0.75f);

         source.start();

         while (this.isActive())
         {
              // stuff

              source.write(raw, 0, raw.length);
         }

         // adds 20 bytes :o(
        source.drain();
         source.stop();
         source.close();
      }
      catch (Exception e)
      {
         // System.out.println(e);
     }

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #2 - Posted 2011-01-03 01:54:17 »

Alternatively you can create a Clip, which is convenient for background sound

Try compiling this Smiley

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
/*
 * SoundTemplate4k.java
 *
 * Created on 29 December 2010
 */


/**
 *
 * @author  Alan Waddington
 *
 */

import java.applet.Applet;
import java.awt.Graphics;
import java.awt.AWTEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;

public class SoundTemplate4k extends Applet implements Runnable {

    private final static int SCREENWIDTH  = 600; // Screen width
   private final static int SCREENHEIGHT = 400; // Screen height

    private final static float RATE       = 16000f;// Music sample rate
   private final static float AMPLITUDE  = 2048f; // Music amplitude

    private byte musicLoop[];           // Array of 16 bit music sound samples
   private Clip music;                 // Clip to play the above music track

    // The following should be pasted in from Java4kSoundEditor
   private final static int maxNote = 730;
    private final static int length = 1018;
    private final static int tempo = 210;
    private final static String notes = "[42,#OB+^*(Un6*xG]]#io[%$\\_H]*eG:+#E7i^ W}T7 A'T7 UTR^ o^3^*)(R^ L@%7*/(E7 6@[7 /tx%$DUC^ 0y ,-)(R^ b|l]*0EX[*kKS^ (K;+#L7\\7 L3s]#/(E7 ='a^ #Un6*R<<^   8%$A[2^*)(R^ S}a^ #Un6*`#5^   8%$Mxw\\ o;'_ o;'_ rS9^*4L/,-qWf*#?rb<\"E$U%$:cP^*P<<^ .YK_ Aq]^*^#5^  # _ /yD^ 5q]^*IEv^ 1yD^ ll@^*3;2^*%8~] F7i^ qX2N!T#OM!LrXq#*LhR&po{]*+8~] qKF7 QzN]#uVT%$'8~] 7:>] .YK_ Bq]^*rDB7*grZ7 o+q7 g_/&$,q]^*-w%_ ^>[] 7Pp^ <r37*Bj\"^#0@h^ =\"+^*DUC^ 6Z{]*`#5^ oxx<\"_mw\\ 44v\\*jF5,#OB+^*(Un6*xG]]#io[%$\\_H]*eG:+#E7i^ W}T7 A'T7 UTR^ o^3^*)(R^ L@%7*/(E7 6@[7 /tx%$DUC^ 0y ,-)(R^ b|l]*0EX[*kKS^ (K;+#L7\\7 L3s]#/(E7 ='a^ #Un6*R<<^   8%$A[2^*)(R^ S}a^ #Un6*`#5^   8%$Mxw\\ o;'_ o;'_ rS9^*4L/,-qWf*#?rb<\"E$U%$:cP^*P<<^ .YK_ Aq]^*^#5^  # _ /yD^ 5q]^*IEv^ 1yD^ ll@^*3;2^*%8~] F7i^ qX2N!T#OM!LrXq#*LhR&po{]*+8~] qKF7 QzN]#uVT%$'8~] 7:>] .YK_ Bq]^*rDB7*grZ7 o+q7 g_/&$,q]^*-w%_ ^>[] 7Pp^ <r37*Bj\"^#0@h^ =\"+^*DUC^ 6Z{]*`#5^ {x^M!tbw\\ 3hE, *HKi -w%_ *$J]*eG:+#E7i^ W}T7 A'T7 UTR^ >X3,#OB+^*(Un6*xG]]#io[%$\\_H]*F7i^ ,HK] L7\\7 L3s]#/(E7 ='a^ s:S\\ fWi^ r*'] kKS^ >An]*\\_H]*l`%7*/(E7 6@[7 /tx%$DUC^ ,xa^ 9M]]#qS:+#F7i^ =\"+^*DUC^ ,xa^ 8M]]#(a2,#]l@^*yl@^*3HK] |\" _ K;u,#LC`6*)1O]#`w^]*tKS^ )+e^*/w%_ vKS^ R?O^*xl@^*ji-^ I'=_ [?O^*xP&^ :Pp^ IG6^ (;2^*%EB7*bYzM!{GeL!*7|y&T2_+#Q}a^ :#`6*c2~] [TE7 p\"D^ O?O^*{*e^*!1-_ +SE] &#r7 v71^#grZ7 btK] I'=_ ]?O^*1\"+^*FUC^ :I(] WZ!&$)(R^ S}a^ 3=eL!Q}a^ $gA<,Ria<\"1RP\\*g3ln7eG:+#E7i^ W}T7 A'T7 UTR^ >X3,#OB+^*(Un6*xG]]#io[%$\\_H]*F7i^ ,HK] L7\\7 L3s]#/(E7 ='a^ s:S\\ fWi^ r*'] kKS^ >An]*\\_H]*l`%7*/(E7 6@[7 /tx%$DUC^ ,xa^ 9M]]#qS:+#F7i^ =\"+^*DUC^ ,xa^ 8M]]#(a2,#]l@^*yl@^*3HK] |\" _ K;u,#LC`6*)1O]#`w^]*tKS^ )+e^*/w%_ vKS^ R?O^*xl@^*ji-^ I'=_ [?O^*xP&^ :Pp^ IG6^ (;2^*%EB7*bYzM!{GeL!*7|y&T2_+#Q}a^ :#`6*c2~] [TE7 p\"D^ O?O^*{*e^*!1-_ +SE] &#r7 v71^#grZ7 btK] I'=_ ]?O^*1\"+^*FUC^ :I(] WZ!&$)(R^ S}a^ 3=eL!Q}a^ zq'M+^iGM!BZl!*SwR, )d;_ Pb|[*";

    private final static int    TRIANGLEHARMONICS = 7;    // Number of harmonics
    private final static double TRIANGLEAMPLITUDE = 0.5;  // Triangle Volume
    private final static double SINAMPLITUDE      = 0.2;  // Sinewave Volume
    private final static int    ATTACK            = 1000; // Note attack
    private final static int    DECAY             = 1000; // Note decay

    @Override
    public void start() {
        enableEvents(AWTEvent.KEY_EVENT_MASK);
        new Thread(this).start();
    }

    public void run() {

        //
        //  Initialise and start background music
        //

        // Create array of music frequencies
        int i, j, k;
        double[] freq = new double[100];
        double f = 16.351562;        // Frequency of C0 (C4 is middle C)
        for (i=0; i<7*12; i++) {
            freq[i] = f;
            f *= 1.0594630944;       // Evenly tempered scale (12th root 2)
        }

        // Create an array of bytes to store the background music
        musicLoop = new byte[2*(int)( length*15f/tempo*RATE )];

        // Read each note and render it into the loop
        int semiQuaver = 0;             // Start time for next note
        int byte0, byte1, twoNotes=0;
        for (i=0; i<maxNote; i++) {
            if ((i & 1)==0) {
                // Decode 5 chars to 1 int
                twoNotes = 0;
                for (j=4;j>=0;j--)
                    twoNotes = twoNotes*95+(int)notes.charAt(5*(i>>1)+j)-0x20;
            }
            byte0 = twoNotes & 0xff;        // Frequency
            byte1 = twoNotes>>8 & 0xff;     // Delay & Duration
            twoNotes=twoNotes>>16;
            double frequency = freq[byte0 & 0x7f];
            if (byte0 >127) // If bit7 is set, there is a delay before note
                semiQuaver += (byte1>>4 & 0x0f) + 1;    // Note start time
            int duration = (byte1 & 0x0f) + 1;          // Note duration
            // Calculate start and stop times in terms of samples
            int start = (int)( (semiQuaver)*15f/tempo*RATE );
            int stop  = (int)( (semiQuaver+duration)*15f/tempo*RATE );

            // Calculate each sample and render it into the music loop
            double sample;
            for (j=start; j<stop; j++) {
                double time = (j-start)/RATE;   // Time (seconds)
                // Triangle fundamental + sinusoidal 4th and 6th harmonics

                sample = 0.0;
                for (k=1; k<=TRIANGLEHARMONICS; k+=2) {
                    f = frequency*k;
                    if (f<RATE/2.0) // Nyquist frequency
                        sample += Math.sin(Math.PI*f*time*2.0)/(k*k);
                }
                sample = sample*TRIANGLEAMPLITUDE
                       + (Math.sin(Math.PI*frequency*time*8.0)
                       +  Math.sin(Math.PI*frequency*time*12.0))
                       *  SINAMPLITUDE;

                // Apply attack and decay to avoid clicks
                if (j-start<ATTACK) sample *= (j-start)/(float)ATTACK;
                if (stop-j<DECAY) sample *= (stop-j)/(float)DECAY;

                // Add the 16 bit sample to loop
                int data = (musicLoop[2*j]<<8)+(musicLoop[2*j+1] & 0xff);
                data += (int)(AMPLITUDE*sample);
                musicLoop[2*j+1] = (byte)(data & 0xff);
                musicLoop[2*j] = (byte)((data>>8) & 0xff);
            }
        }
        try {
            // Initialise Sound System
            AudioFormat audioFormat = new AudioFormat(RATE, 16, 1, true, true);
            DataLine.Info info = new DataLine.Info(Clip.class, audioFormat);
            music = (Clip)AudioSystem.getLine(info);
            music.open(audioFormat, musicLoop, 0, musicLoop.length);
            music.loop(Clip.LOOP_CONTINUOUSLY);
        } catch (Exception e) {}

        //
        // End of Music Section
        //

        BufferedImage screen = new BufferedImage(
                SCREENWIDTH, SCREENHEIGHT, BufferedImage.TYPE_INT_RGB);

        while(!isActive()) Thread.yield();
        Graphics g = getGraphics();
        requestFocus();
        do {

            if (g!=null) {
                g.drawImage(screen, 0,0,null);
            }
            Thread.yield();
        } while (isActive());
        music.stop(); // Required to stop music when applet is not in foreground
    }

    /** Process Key Event */
    @Override
    protected void processKeyEvent(KeyEvent e) {
        // Key Handler ...
    }

}

Time flies like a bird. Fruit flies like a banana.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline steveyO
« Reply #3 - Posted 2011-01-03 12:09:56 »

I tried this last night and looks good (SoundTemplate4K).  Is there any explanation anywhere on how to create new songs.. The notes string/code looks too complex for my simple 'lazy' mind to decipher :-)
Also, have you tried this within a game, ie.. Does the sound cause the game/graphics to stutter once you implement your game logic.

https://play.google.com/store/apps/details?id=com.bullsquared.alggame Annoying Little Gits (Android)
www.bullsquared.com   Play java (applet) games! www.chessclockpro.com Free Online Chess Clock
Offline Alan_W

JGO Knight


Medals: 8
Projects: 3


Java tames rock!


« Reply #4 - Posted 2011-01-03 17:03:34 »

 /* Music Data
  * Each note is a short
  * Bits 0-6: Note in semitones in range C0-B7 (C4 is middle C)
  * Bit  7: This note starts at the same time as the previous note if clear
  * Bits 8-11: Length of this note (1-8) in semiquavers [Value stored 0-7]
  * Bits 12-15: Delay in semi-quavers (1-8) from start of previous note to
  * start of this note [Value stored 0-7]
  *
  * Two shorts are packed into each integer, the first note in the low short
  */

Each integer is then encoded into 5 chars and added to the string.  Don't forget to escape '\' and '"' for pasting into your source code.
1  
2  
3  
4  
5  
6  
7  
8  
                    n = integer representing two notes
                    for (int k=0;k<5;k++) {
                        char ch = (char)(n - 95*(int)(n/95)+ 0x20);
                        if (ch=='"' || ch=='\\')
                            s += '\\';
                        s += ch;
                        n /=95;
                    }


I wrote a program to convert MIDI files, but it is a bit quirky, so not really releaseable.

Time flies like a bird. Fruit flies like a banana.
Offline John Teasdale

Senior Newbie





« Reply #5 - Posted 2011-01-04 04:05:31 »

Thank you all, this will undoubtedly come in handy.
Offline steveyO
« Reply #6 - Posted 2011-01-05 10:03:46 »

Thanks Alan, Very helpful.  Your template doesn't appear to use double buffering (I think appel pointed this out last year too), but was easily fixed, other than this looks good for music.  Will see!

https://play.google.com/store/apps/details?id=com.bullsquared.alggame Annoying Little Gits (Android)
www.bullsquared.com   Play java (applet) games! www.chessclockpro.com Free Online Chess Clock
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (37 views)
2014-07-24 01:59:36

Riven (38 views)
2014-07-23 21:16:32

Riven (26 views)
2014-07-23 21:07:15

Riven (28 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21

Zero Volt (50 views)
2014-07-17 23:47:54

danieldean (42 views)
2014-07-17 23:41:23

MustardPeter (44 views)
2014-07-16 23:30:00

Cero (60 views)
2014-07-16 00:42:17

Riven (57 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!