Java-Gaming.org Hi !
Featured games (85)
games approved by the League of Dukes
Games in Showcase (612)
Games in Android Showcase (173)
games submitted by our members
Games in WIP (659)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
   Home   Help   Search   Login   Register   
  Show Posts
Pages: [1] 2 3 ... 41
1  Game Development / Game Play & Game Design / Re: Game Ideas on: 2015-09-03 03:25:26
I don't think that a general list of "make a platformer game with an armadillo" ideas is very helpful to a programmer trying to think of an idea.
Not my intention to get into this sort of "meta" back and forth on this thread. But some thoughts occur to me.

I don't think that getting more specific, by laying out a mechanic, is necessary or even a good thing. To me, a story is what is going to drive a good game, and a big part of making that story work is trying to figure out how to design or program a mechanic that will support that story. Solving that for a programmer seems almost like writing homework assignments for someone.

I suggested penguins, not armadillos, because of some very compelling footage that can be seen in Attenborough's "Frozen Planet" video. The poor penguin chick fleeing for its very life from dozens of wanna-be mothers that almost
crush and trample it in the pursuit--that struck me as a story/scenario with some juice in it, both comic and violent in a weird way (comedy and violence sure worked on "Angry Birds"). Maybe it resonates, as well, due to sometimes finding myself "running away" from relationships that start to impose onerous time requirements. Whatever. Figuring out a mechanic to program this will require some creativity, but isn't that what programming is about? And when talking about the important of limitations: it seems this story imposes some definite bounds as to what might work or not.

A thread with lots of ideas in it can also maybe show that almost any scenario can be looked at as a game, can be considered for its game potential. Game making and design is to a large extent a way of looking at the world.

@Opiop
Quote
Plus, it's just fun to see what you all come up with, I like reading about different ideas and imagining them  Smiley
Yay!
2  Game Development / Game Play & Game Design / Re: Game Ideas on: 2015-09-01 23:13:37
I have to seperate myself from anybody saying "only positive feedback allowed" here though.

Agreed. Not my intention to do so.
3  Game Development / Game Play & Game Design / Re: Game Ideas on: 2015-09-01 23:07:45
@KevinWorkman Thank you for your $0.02.

The food/spaghetti/sushi analogy was faulty, imho. I wasn't asking for random ideas, especially not random lists of things that already exist. Now, if we had a forum thread where someone could suggest making sushi in a way that incorporates spaghetti noodles, that might have been a bit closer to the mark, and possibly an interesting idea for those of us who are fusion foodies and actively experimenting with mixing food traditions.

I am truly interested in the feedback if a suggested idea has already been used. Many eyes are better than one, and no single person has seen all the games there are to see.

Ideas are cheap? So are game engines, apparently, given all the people that work on them instead of actually diving in and making a game. There are an infinite number of ways to dither.

In any event, I did say "silly" was okay, and one of the tactics of successful brainstorming is to go easy on the preconditions and self-censorship.

Best wishes!
4  Game Development / Game Play & Game Design / Re: Game Ideas on: 2015-09-01 03:52:07
I'd like to see the classic "Snake" game played on a Klein Bottle surface.
5  Game Development / Game Play & Game Design / Game Ideas on: 2015-08-31 00:10:46
I thought it might be fun to have a thread where people could post game ideas (silly is okay). Then, when someone asks for an idea for a game, send them to this thread. Also, can tell someone if an idea is already in use, or a near-variant exists.

My most recent idea was inspired by my wife, who is temporarily using a walker while a hip fracture heals.

Create a puzzle game with senior-aged or handicapped avatars, who have to use a variety of walkers, crutches, wheel chairs, stair lifts, etc., to solve various levels.

I also think almost anything with penguins could work. There are some amazing life-events that happen and seem game-worthy. For example, childless penguin adults (eggs didn't hatch for whatever reason) trying to adopt penguin chicks that stray from their parents. A video of the genuinely dangerous mayhem that results from such a pursuit is jaw dropping (see Attenborough's "Frozen Planet").
6  Discussions / Miscellaneous Topics / Re: What I did today on: 2015-08-21 00:50:42
Having a little trouble diving back in...

My wife started a new job two weeks ago. Yay! She is doing technical writing/editing for the US Coast Guard, via a contract with Lockheed Martin. Huge boost for the household budget.

Then, after work on Monday, a fellow plowed his car into our car while she was driving home. She is basically okay, is now home with with two small fractures in hip, requires walker to get about. I've been dealing with care-taking, household/shopping/cooking/insurance & police & auto tow companies etc. So, yeah, a bit hard to concentrate now that I finally have a moment to myself.

Recent thread on Java compilers here, has me wondering if that would be a way to make a VST. Am looking into this. Writing in Java then converting to C# seems like asking for a ton of headaches. But if an exe can be generated from Java, maybe this is a viable way to go. Then, I should "only" have to refresh my C++ to the point where I can read the links that BurntPizza recommended (from krvaudio).

I had a breakthrough with my audio sequencer coding, right before the accident. It took several weeks and successfully programming a wrong way before I had my head well enough around the issues to come up with what I think is a much better plan. Instead of attempting to deal with a "scheduler" that works directly with frames (44100 frames per second), I've written a "PulseManager" that schedules itself every N frames (amount determined by tempo of a piece, e.g., 44100 / 8 for 8th notes at 120 bpm). This PulseManager also employs an observer design pattern, holding an array of subscribing "sequences" (I'm calling them Motif objects) that are each given a single "pulse" with each PulseManager rescheduling. This is a different way of doing things than is done by most sequencers. But I'm not worried about recording gestures in real time, only playback of scores. So it seems to me there are some benefits of doing things this way, rather than using the standard practice tiny "tick". We shall see.

I got the test code and examples working, and now, plan to use this basic structure to also code things like 'hairpins' (crescendos or diminuendos) or tempo changes that are pulse-based as opposed to requiring per-frame attention.
7  Discussions / General Discussions / Re: Oracle working on an AOT compiler for Java on: 2015-08-14 17:07:12
I agree that AOT compilation using Excelsior JET appears to be a better solution.

But startup time is one of the worst aspects of Java programs and creates negative user experiences even for non-trivial programs.
Java GUI freeze when a button is clicked for the first time is very irritating and that's due to JIT compilation.
Native programs seem to be able to start almost instantaneously.

This initial slowness definitely happens with audio coding, and is well known enough to get special mention in a very good article on low-latency audio coding in Java. But there is a work-around: one can code a silent tone to play prior to the first time that audio is heard. Though, that consumes a bit of time, too.

As a developer using Eclipse, I agree that a few extra seconds of startup time is not a problem. But I can also see where the transition from interpreted to compiled could color a common user's experience of Java, and unfairly affect its reputation.
8  Discussions / General Discussions / Re: Oracle working on an AOT compiler for Java on: 2015-08-14 04:12:36
I needed some background to find out what this discussion was about.
This article has a lot of good information about Java "executable" options, with a section on AOT compilers. It has a comparison of Excelsior and Gnu versions. From 2014. (The author works at Excelsior.)
http://www.excelsior-usa.com/articles/java-to-exe.html
9  Java Game APIs & Engines / Java Sound & OpenAL / Re: Paul's SoundSystem, set folder for files on: 2015-08-09 21:43:31
There are two different forms for locating folders for a project, depending on whether you start the location with a "/" or not. Using the "/" is an absolute address that starts from the code base, otherwise the location is relative to the location of the class that is used for the call. I'm assuming the form getResource(filename) or getResourceAsStream(filename).

The symbol ".." is useful for backing up one level.

In general URL's are more reliable, since the file system is unable to locate files embedded in a jar. URL = Uniform Resource Locator. The JavaDocs for URL has more info.

I've got the following folder structure:

Game
     src
     res
         sound
If you have a Class called PlaySound in folder src, and res is a "neighboring" folder (as in your diagram), you should be able to use the following.

1  
URL url = PlaySound.class.getResource("../res/sound");


I did a test where my structure was the following:

jgoQuestions  // a package in the Eclipse project
    res
         foo.txt
    src
         ResourceTest

From here, the following worked (running the class ResourceTest):
1  
2  
URL url = ResourceTest.class.getResource("../res/foo.txt");  // relative form
URL url = ResourceTest.class.getResource("/jgoQuestions/res/foo.txt");  //absolute form
10  Discussions / Miscellaneous Topics / Re: What I did today on: 2015-08-09 20:38:53
I asked my boss if, after my internship is up, I can have a permanent position at my job. I'm surprised the adrenaline rush I had didn't make me say something completely stupid! Tongue

Now I have to play the waiting game Sad

You had to ask? Isn't that the whole point of an internship? Usually companies hire interns as a source of future employees. My manager's manager offered me a permanent position by himself, explaining this fact to me.

It probably varies from situation to situation. But more often than not, it seems that letting the interviewer or boss know that you care enough to ask for it outright is a plus. Of course, it is also possible to overdo it!
11  Discussions / Jobs and Resumes / Re: Hayden Davenport - Video Game Composer for Hire on: 2015-08-09 20:28:15
Links still don't work.

Your tags look like the following:

1  
[url=http://'http://thisisthelink.com]This is the text[/url]

Basic form for the URL tag here is as follows (afaik):

1  
[url=http://thisisthelink.com]This is the text[/url]


To fix, all you have to do is select "Modify" on your previous posts, then delete the extra http://' prefix to the link.
12  Discussions / Miscellaneous Topics / Re: What I did today on: 2015-08-06 06:36:19
Audio coding seems to be in at the moment ...

Just made video of simple live synth creation using new audio coding API in Praxis LIVE

<a href="http://www.youtube.com/v/C3dv2rf4fNM?version=3&amp;hl=en_US&amp;start=" target="_blank">http://www.youtube.com/v/C3dv2rf4fNM?version=3&amp;hl=en_US&amp;start=</a>

Aiming to get this in a release on Saturday, just for the pun of it.  Wink

Nice! Neat to hear the FM towards the end. It might be nice to have a 3-deep op patch demonstrated, as that is where most FM algorithms fail. Or show, if your program supports it, the ability to copy a pair of ops and tweak the pitches slightly on the second copy, to get a bit of phasing, thickening up the sound (a very common and useful FM programming technique).

Overall, maybe the demo could be tightened up a bit, depending on what the goal is, and build to a final song that uses most of the parts built along the way. Is it maybe a bit long for something that is supposed to be "simple"? Also, very difficult to read the text, even in full screen, and maybe voice-over explaining what you are doing? But it depends on what the goal of the video is.
13  Discussions / Miscellaneous Topics / Re: What I did today on: 2015-08-05 20:20:26
So, I'm at a loss as to how to describe this. Got home from work at midnight, took my pup outside so she could pee. As I lit my Djaram, I noticed a faint noise. It was somewhat disorienting, because it didn't really feel like it was coming from any particular direction. It might help to say that I live out in the country, in the middle of the woods.

Anyway, I've never heard this before. It wasn't a howl, nor did it quite sound like a horn. I can best describe it as an odd pattern that almost sounded like a howl, without sounding like it came from an animal's throat. The most disturbing part I found was(aside from it sounding like it was all around me, close yet distant) it didn't feel chaotic. It kept building on itself until it slowly died down. Most of the noise was on the deeper side, not really high-pitched. I checked my A/C unit to make sure it wasn't about to blow up or something, but that was making its normal noise as the other went away.

Does anyone have a clue as to what I heard?

How long did this last?
"Odd pattern" is kind of ambiguous. Was it steady state or pulsing? Can you describe the tone of it? Was it pitched? Did the pitch also rise and fall? The more specifics about the noise the better.
14  Discussions / Miscellaneous Topics / Re: What I did today on: 2015-08-03 01:19:08
Just getting going with coding today. So far, though, posted an excerpt of a composition of mine on YouTube.

https://www.youtube.com/watch?v=WjkqQ9hQPQY

It is a piano rendition of a woodwind quartet accompaniment to a silent film, an old horror classic called "Der Golem" (1920). It starts off slow as preparations are made, then gets going when the spell starts. If you check it out, you'll see some neat pyrotechnic/smoke effects for the time. About 3+ minutes long.

Also, tested the data in a table I found on the correspondence between numbers used for the "modulation amplitude" on a synth (DX7S) and on the supposed resulting "modulation index", and how that MI sounds on in the FM synthesizer I wrote. It isn't matching up as expected. But it is consistent and something that can be worked with. So, file under "something wrong with theory:implementation match" and move on.

When I was getting the music ready for the posted video (two weeks ago), I was doing a LOT of MIDI editing. In the process, I worked out an innovative idea or two on how to edit MIDI key velocity data more efficiently, in relationship to measures and meters. I think it could lead to a useful editing tool for sound track composers. The functionality doesn't exist yet as a feature of any DAW that I know of.

But looking into VST programming (did this last week) was discouraging. There is a big learning curve and it is mostly being done with C++. I might be able to (I WANT to) use some of the concepts in my own audio library. But making a marketable VST requires meeting someone* with VST programming chops.

*Would be interested in meeting such a person for collaboration.
15  Game Development / Shared Code / Re: Phase Modulation for Synthesizers on: 2015-08-01 08:01:56
Having the modulation index better understood has been kind of a bigger issue for me than getting the fastest sine function worked out. So I'm glad to finally make some progress with it.

The sine function is nicely encapsulated so the method of calculation can be altered at will. It might take me a longer while to test out the various suggestions. I'll report back once I do, but it could take a couple weeks to get to it.
16  Game Development / Shared Code / Re: Phase Modulation for Synthesizers on: 2015-08-01 07:55:06
I tried various exponential curves, to see if they would match the graph cited by Dave Benson as containing the values used by the DX7S (0-99) and their corresponding modulation amounts.

The closest I could get without going nuts, that pretty much matched the curve of the graph were:
1  
2  
    f(x) = 1000^x 
    f(x) = x^6

but neither was a great fit. It makes me wonder where they got their numbers.

Both are a lot closer than the Reverse Cos function that I have been using recently. Maybe a milder curve is actually a better fit if one isn't stuck on recreating the exact numbers/settings from the Yamaha synth.
17  Game Development / Shared Code / Re: Phase Modulation for Synthesizers on: 2015-07-31 19:59:22
AFAIK, modulating any signal is possible. The results will include side band creation for each constituent tone of the carrier and modulator. So, I guess the main question is how much high frequency stuff gets generated and if it aliases. This might account for why the original DX7 operators were a little noisy compared to the DX7S (second generation): perhaps the original was also not quite as pure as the later version.

I'll make another Operator using this function and see if I get some aural changes when swapping it into existing synths I've put together, and if it speeds up processing. It's not clear to me that it will, as there are more multiplies than in the linear interpolation that accompanies the LUT.

Also on my list: plotting the DX7S modulation index chart from the Benson text and seeing if it matches any of the curves I've already encoded.
18  Game Development / Shared Code / Re: Phase Modulation for Synthesizers on: 2015-07-31 07:43:09
For constant walks you're just performing a constant rotation at each step.  The simplest method is logically you have a complex number that's your current position P=(sin,cos) and another that's your rotation rate (F for frequency).  P  = P*F.

t   = px*fx - py*fy;
py = px*fy + py*fx;
px = t;

Compounding errors make this unusable after awhile.  But you can test if it helps/hurts performance.  If helps then there are corrective steps which can be taken.  Such a renormalize outside of the main transform loop or move to a second order version.  Obviously second order is more expensive.

Hmm. If I understand what you are suggesting, usually this won't actually save us a lookup to the sin LUT, because there is a modulation amount that has to be added to the new current position, and that modulation amount varies.

But maybe it would speed up the OpN a bit, since that oscillator doesn't get modulated. But the code there is already pretty minimal:
1  
2  
3  
      cursor += pitchIncr;
      if (cursor >= tblSize) cursor -= tblSize;
      return SineTable.get(cursor);

There are only two multiplies in the linear interpolation that occurs with the lookup, and your algo has four.

In your algorithm, does the px oscillate between -1 & 1? Am I returning px?
How do I determine the values for fx and fy? Will one of them be negative, or does py grow into infinity?
19  Game Development / Shared Code / Re: Phase Modulation for Synthesizers on: 2015-07-31 04:54:02
On this sine thing...you're just walking sine at a constant rate?

In the FMOp's (often called Operators) that remain implemented, yes, the sine progresses at a constant rate. The cursor value moves one equal fraction of its period every sound frame (44100 fps). I named this fraction pitchIncrement. The modulation that occurs and is returned can be seen as a varying change to the phase of the Operator.

Original, I wrote FMOp's that employed frequency modulation instead of phase modulation. In that case, the value of cursor every frame would vary considerably, depending upon the amount of modulation which was being +='d into it.

Turns out that FM results in some rather strange effects. If I remember correctly, we can get energy at 0 Hz when stacking these beyond two layers (e.g., the frequencies ratios 1:1:1), whereas with PM, this is avoided, though I forgot exactly why. I'm really good at forgetting details once I have solved a problem, especially if my understanding of the answer is just enough to code it and little more.

Found the article that talks about the 0Hz issue: (by Bill Schottstadt, "An Introduction to FM" section "Cascade FM"
Quote
Unfortunately, FM and PM can produce energy at 0Hz (when, for example, the carrier frequency equals the modulating frequency), and in FM that 0Hz component becomes a constant offset in the phase increment (the "instantaneous frequency") of the outer or lowermost carrier.
https://ccrma.stanford.edu/software/snd/snd/fm.html
20  Game Development / Shared Code / Re: Phase Modulation for Synthesizers on: 2015-07-31 00:56:54
One thing I don't get is why you're using a cos curve on the modulation amplitude.  Would you not use the same amplitude mapping there?

It makes sense to me that the two power curves serve very different functions. The power functions used on carriers reflects an operation done to convert a linear scale for amplitudes to something that matches our "logarithmic" perception of loudness. The discussion in the volume controls article cited gets into particulars about picking an equation for expressing a range of a desired low to high db.

The function used for modulation amounts affects an operation that progressively changes harmonic content by propagating sidebands. The math used to determine sideband propagation uses Bessel functions. I don't know if there is much of a correspondence between the Bessel functions and exponential or logarithmic curves, or not, nor how the changes in timbre relate to units of human perception.

I guessed "reverse cos" based on listening and trial and error as being workable, and got some good results. But probably the work done by Chowning at Stanford and confirmed by Yamaha, using the published function table, is solid, and should be emulated. (Their chart may even be a normal power function of some sort.)

That said, it would be nice to be able to generate the values via an equation rather than just copy them from an existing table.

Looking up Bessel functions, though, all I can say is yikes!
https://en.wikipedia.org/wiki/Bessel_function
They make use of differential equations, and the results are spread out over the various sidebands. It doesn't appear be a curve that itself is going to be used for a simple amplitude mapping, not with those "wavy parts"!
21  Game Development / Shared Code / Re: Phase Modulation for Synthesizers on: 2015-07-30 20:11:55
[Edited 7/30/15]
Thanks for the article link! Nice to see some confirmation and clarification. I am also interested in ideas for a good power curve for panning. For now, I'm just using two linears, in reverse directions, one for each channel, with the plan to work on a better version if/when I get into true 3D or another situation that demands power balancing throughout the panning range.

I went through a process of trial an error for the carrier and modulator power curves, testing by ear. The "VolumeMap" object I created can have its LUT (similar in implementation to what I posted on the 'fastest sin' thread) populated by any number of methods. This made it pretty easy to swap the various maps in and out for comparison purposes. The ones that I implemented and compared follow:

  • reverse cos  : 1 - cos(x) where x [0..PI/2]

All of the rest, x goes from 0 to 1:

  • linear
  • 2^x - 1
  • (10^x - 1) / 9
  • (20^x -1) / 19
  • x^e
  • x^2
  • x^3
  • x^4
  • x^5
  • x^6
  • x^7
  • x^10

and a few miscellaneous experiments that didn't work out at all.

I compared the results, by ear, with numbers plugged into the Yamaha DX7 or Native Instruments FM7. I don't consider my choices "final" answers.

I recall x^4 (the article's "overall best") was pretty good, but I guess I am working with a larger dynamic range, hence using the higher exponent values. I remember being indecisive between x^5 and x^6 early on. Lately, I just start with the two I mentioned and try others only if I am have an audible goal in mind. For example some patches, x^7 seems to work better than x^6. The times x^7 works best are patches where the envelope levels are transitioned via "EXP" curves rather than linearly in the "parent" synth.

Thanks to this discussion, I just found another option to try: mapping derived from a Bessel function. Check out the following link, "Appendix B: Bessel Functions" from Dave Benson's book on music related mathematics.

http://homepages.abdn.ac.uk/mth192/pages/html/music.pdf#appendix.B

At the very end of this appendix section is a table, with the caption:
Quote
The following table shows how index of modulation (z) varies as a func-
tion of operator output level (an integer in the range 0–99) on the Yamaha
six operator synthesizers DX7, DX7IID, DX7IIFD, DX7S, DX5, DX1, TX7,
TX816, TX216, TX802 and TF1

I don't know much at all about Bessel functions, or even if this table arises from Bessel functions other than that it is in the "Bessel" appendix. In this table, I take it that 1.0 is one complete modulation cycle. To be more concrete: I have a sin LUT of 1024. An offset of 360 degrees would be once through the sine table, so a modulation index or amplitude of 1024 in my OpPML should correspond to the DX7S modulation index value of between 69 and 70. This rings true for the patches I've recreated. I'm going to have to confirm. I'm also going to have to experiment with using this table (with linear interpolation) for the modulation values that arise by applying the envelope to the modulation index. [EDIT8/2/15 Perhaps logic here is wrong. Since the MI is being multiplied against an output of range -1 to 1, a range of half the sine LUT is equal to a MI of 1? But even that is too high for the synth I have programmed. I'm getting an MI of 150 +/- 10 (with LUT of size 1024) as the closest, by ear, to DX7 MI of 69, or '1' according to Benson's chart. Hmmm.]

Envelopes should be pretty much the same as they are for subtractive synthesis or wave-table synthesis. Yes? No? I'm assuming you are using outputs that range from 0 to 1 and are multiplied in (but with a power curver). I assumed you have already implemented that sort of thing. I recall a JGO post with you and "AngryOctopus" (ShannonSmith), exchanging links to software synthesizers you had each made.

I think I have a pretty nifty envelope working (updates every frame), but am curious how you do it, and possible improvements.
22  Game Development / Shared Code / Phase Modulation for Synthesizers on: 2015-07-27 19:24:21
On nsigma's request (from the "Extremely Fast sine..." thread)

The code is actually being used for phase modulation at this point, not frequency modulation. So maybe I should change the name to PMOp. While I was developing, I had some actual frequency modulation implementations as well but have "phased" them out.
1  
2  
3  
4  
5  
6  
public interface FMOp
{
   float get();
   float get(float modAmt);
   void setFrequency(float freq);
}


The initials PML derived from Phase Modulation Lookup. I previously had tried calculating the sine values, but couldn't find an algorithm fast and accurate enough to compete with the lookup I'm using (1024 unit table with linear interpolation, posted on the thread cited below). I'd be most grateful to learn of a faster method (will be reading closely and trying out methods from here: http://www.java-gaming.org/topics/extremely-fast-sine-cosine/36469/msg/346129/view.html#msg346129)

[EDIT 7/30/15: renamed "index" to "cursor" in order to make the three implementations consistent.]
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  
public class OpPML implements FMOp
{
   // "public" okay, for internal use only
   float cursor;
   float pitchIncr;
   final int tblSize = SineTable.getOperationalSize();
   
   public void setFrequency(float freq)
   {
      pitchIncr = (freq * tblSize)/ 44100;
   }
   
   // TODO: should not be used, should set to cause compile error
   @Override
   public float get()
   {
      return get(0);
   }
   
   @Override
   public float get(float modulationAmt)
   {
      cursor += pitchIncr;
      if (cursor >= tblSize ) cursor -= tblSize;
     
      float temp = cursor + modulationAmt;
   
      while (temp < 0) temp += tblSize;
      while (temp >= tblSize) temp -= tblSize;
     
      return SineTable.get(temp);
   }
}


Variant with no modulator. Yes, lots of duplicate code. But minimizing processing in the .get() has the highest priority.
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  
public class OpN implements FMOp
{
   // "public" okay, for internal use only
   float cursor;
   float pitchIncr;
   final int tblSize = SineTable.getOperationalSize();
   
   public OpN(){}
   
   public OpN(float freq)
   {
      this();
      this.setFrequency(freq);
   }
   
   public OpN(float freq, float startingPhase)
   {
      this();
      this.setFrequency(freq);
      cursor = startingPhase * tblSize;
   }
   
   public void setFrequency(float freq)
   {
      pitchIncr = (freq * tblSize) / 44100f;
   }
   
   @Override
   public float get()
   {
      cursor += pitchIncr;
      if (cursor >= tblSize) cursor -= tblSize;
     
      return SineTable.get(cursor);
   }

   // TODO: should cause compile error, should not be used
   @Override
   public float get(float modulationAmt)
   {
      return 0;
   }
}
   
Variant that uses feedback instead of an external modulation source.
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  
public class OpFB implements FMOp
{
   // "public" okay, for internal use only
   float cursor;
   float pitchIncr;
   final int tblSize = SineTable.getOperationalSize();
   private float feedback;
   
   final private float feedbackAmplitude;
   
   public OpFB(float feedbackAmplitude)
   {
      this.feedbackAmplitude = feedbackAmplitude;
   }
   
   public void setFrequency(float freq)
   {
      pitchIncr = (freq * tblSize) / 44100f;
   }
     
   @Override
   public float get()
   {
      // determine feedback amt
      cursor += pitchIncr;
      if (cursor >= tblSize) cursor -= tblSize;
     
      feedback = SineTable.get(cursor);
     
      feedback = cursor + feedback * feedbackAmplitude;
      while (feedback >= tblSize) feedback -= tblSize;
     
      return SineTable.get(feedback);
   }
   
   // TODO: trigger compiler error, never should be used
   @Override
   public float get(float modulationAmt)
   {
      return 0;
   }
}


With these three, one can replicate all 32 "algorithms" employed by the Yamaha DX-7. Here is an example of the code I use for a simple modulator -> carrier pair:
1  
2  
3  
4  
5  
6  
7  
8  
9  
            currentCEnv.tick(cEnvCursor, frequency);
            currentMEnv.tick(mEnvCursor, frequency);
           
            float noteVal =
                  vmCarrier.get(cEnvCursor.value)
                  * cOp.get(
                     vmModulator.get(mEnvCursor.value)
                     * modDepth1 * mOp.get()
                  );

cOp is an OpPML
mOp is an OpN
There are envelop/cursor pairs for the carrier and modulator.
There is also another layer of mapping that converts the linear values to something more exponential/logarithmic. I am calling these "volume maps" (amplitude maps would be better?). For modulators, I usually use a "reverse cosine" mapping (1 - cos, for 1/4 of a cycle), and for carriers an exponential mapping (x^6, x=0..1) works pretty well. I was not able to figure out what Yamaha/Stanford folks were using here. nsigma, maybe you understand this better and have a suggestion for this step? My head is a little far away from the theory at the moment. Maybe there is a decibel/logrithmic function-related that would be more ideal.

[EDIT: following added 7/30/15]
Examples of FM synthesis, previously posted on JGO, can be heard playing the jars listed at the following links:
http://www.java-gaming.org/user-generated-content/members/27722/tanpura141204.jar
http://www.java-gaming.org/user-generated-content/members/27722/hexarasoundtester141130.jar

The first has a simple square and sawtooth included (just 2 ops, 2:1 and 1:1), but with pretty active envelopes, so they sound relatively reasonable. (Mouse over the note "node" on the display dial, and select from the bottommost drop-down.) The two main patches (etanpura, cirrus) have 6 ops, with a lot more internal phasing built in, for a richer sound. Oh, and the tanpura-drone project also has a basic FM-type electric-piano keyboard implemented. The second jar has a nice pad and bell/gongs.

I've another half-dozen patches implemented now--will be showing off a little sequencer/motif player soon. I just want to first implement "hairpins" (crescendos/dims) as part of the "event system" before doing so. Might take a couple weeks to get to it.

Excellent resource:
From Dave Benson, from his book posted online on music maths, specifically on FM:
http://homepages.abdn.ac.uk/mth192/pages/html/music.pdf#section.8.8
This chapter has a good reference section at the end to check out! There is also "Appendix O: Online Articles".
23  Game Development / Shared Code / Re: Extremely Fast sine/cosine on: 2015-07-27 19:09:04
Riven, your table has 8 4 times more values than mine. I'm wondering if that compensates sufficiently for the lack of linear interpolation. There is a way to calculate and compare the errors, I'm sure.

I should have noticed that all the operations were occurring within the square brackets!

I was going to use the bit masking idea for keeping the LUT cursor within bounds, but let it go when Java wouldn't allow a byte to be anded with a float. I feel like a turtle among the gazelles. With some effort, I'll look again to see if that is what you coded.
24  Game Development / Shared Code / Re: Extremely Fast sine/cosine on: 2015-07-27 02:34:43
Listening is Believing

I use a LUT for sine waves for my FM synthesizer. So, I had to give Riven's lookup method a try, actually playing a wave. His sounds just as good. If you'd like to listen: some code where I compare methods follows. (Haven't tried it with a "full stack" of 3 modulators + carrier yet. I'm guessing it will still sound good, though. Also, I want to understand the method he is using for interpolating between table values. I just use linear interpolation.)

In the code, I show a half dozen runs where all the values needed for 10-seconds worth of A-440 are calculated, comparing his and my own lookup. (The first comparison can be thrown out because it is mostly about the Audio code getting loaded into memory.) I think his method is even better than the comparison indicates, because I have to manage the cursor to make sure it doesn't look up a value outside the LUT, and his doesn't actually require this. I'm assuming the radian value inputs will remain accurate all the way up to Float.MAX_VALUE. Is this true? It takes a long time to get there playing an A=440 at 44100 fps.

Yay! Looks like this discussion will result in a significantly faster FM synthesis processing algorithm for me to use.  Grin
[EDIT: removed a duplicate line of code that resulted in the results being 880 instead of 440. Also, it looks like what I have is already pretty well optimized for my usage. Main difference: I'm using a float with a range of [0..tableSize) rather than [0..2PI) so no need to multiply by radFull, and I'm managing the range via if (cursor > tableSize) cursor -= tableSize; so that eliminates the need for the bit mask operation. I am also seeing that my get(int) method is off in phase by a tiny amount.]


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  
package fastSineTest;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.Line.Info;

public class ListeningIsBelieveing {

   static int bufferSize = 4 * 1024 * 4;
   
   static long timeDuration;
   
   public static void main(String[] args) throws LineUnavailableException,
      InterruptedException
   {        
      new RivenSine();
      new PFSine();
           
      float pfIncr, rivenIncr;
     
      rivenIncr = (float)((440 * 2 * Math.PI) / 44100f);
      pfIncr = (440 * PFSine.getOperationalSize()) / 44100f;

      float rivenTblSize = (float) (Math.PI * 2);
      float pfTblSize = PFSine.getOperationalSize();
     
      // metrics tests
      for (int i = 0; i < 6; i++)
      {
         play10Seconds(rivenIncr, rivenTblSize, false, true);
         System.out.println("Ri10SecComputationTime(nano): " + timeDuration);
         play10Seconds(pfIncr, pfTblSize, true, true);
         System.out.println("PF10SecComputationTime(nano): " + timeDuration);
         System.out.println();
      }

      // actual playback occurs here
      System.out.println("Riven's is playing...");
      play10Seconds(rivenIncr, rivenTblSize, false, false);
      System.out.println("Phil's is playing...");
      play10Seconds(pfIncr, pfTblSize, true, false);
      System.out.println("Done");
   }

   private static void play10Seconds(float incr, float tblSize,
         boolean method, boolean timeIt)
         throws LineUnavailableException
   {
      AudioFormat audioFmt = new AudioFormat(
            AudioFormat.Encoding.PCM_SIGNED,
            44100, 16, 2, 4, 44100, false);
     
      Info info = new DataLine.Info(SourceDataLine.class,
            audioFmt);
     
      SourceDataLine sdl = (SourceDataLine)AudioSystem.getLine(info);

      byte[] outBuffer = new byte[bufferSize];  
     
      sdl.open(audioFmt, bufferSize);
      sdl.start();
           
      int idx = 0;
      float cursor = 0;
      float normalizedVal = 0;
      int audioVal = 0;
     
      long startTime = System.nanoTime();
     
      for (int ii = 0; ii < 441_000; ii++)   // 10 seconds at 44100 fps
      {
         cursor += incr;
         if (cursor >= tblSize) cursor -= tblSize;
         normalizedVal = getAudioData(cursor, method);
         
         audioVal = (int)(normalizedVal * 32767);
     
         outBuffer[idx++] = (byte)audioVal;
         outBuffer[idx++] = (byte)(audioVal >> 8);        
         outBuffer[idx++] = outBuffer[idx - 2];
         outBuffer[idx++] = outBuffer[idx - 2];
         if (idx >= bufferSize)
         {  
            if (!timeIt) sdl.write(outBuffer, 0, bufferSize);
            idx = 0;
         }
         
      // [EDIT:   [s]cursor += incr;[/s]  oops! ]
         
      }
      if (!timeIt && (idx > 0)) sdl.write(outBuffer,  0, idx);
     
      timeDuration = System.nanoTime() - startTime;
     
      sdl.drain();
      sdl.close();
      sdl = null;
     
   }
   
   static float getAudioData(float cursor, boolean method)
   {
      if (method)
      {
         return PFSine.get(cursor);
      }
      else
      {
         return RivenSine.sin(cursor);
      }
   }
}


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  
package fastSineTest;

public class RivenSine {
     public static final float sin(float rad)
      {
         return sin[(int) (rad * radToIndex) & SIN_MASK];
      }

      public static final float cos(float rad)
      {
         return cos[(int) (rad * radToIndex) & SIN_MASK];
      }

      public static final float sinDeg(float deg)
      {
         return sin[(int) (deg * degToIndex) & SIN_MASK];
      }

      public static final float cosDeg(float deg)
      {
         return cos[(int) (deg * degToIndex) & SIN_MASK];
      }

      @SuppressWarnings("unused")
      private static final float   RAD,DEG;
      private static final int     SIN_BITS,SIN_MASK,SIN_COUNT;
      private static final float   radFull,radToIndex;
      private static final float   degFull,degToIndex;
//      private static final float[] sin, cos;
      public static final float[] sin, cos;

      static
      {
         RAD = (float) Math.PI / 180.0f;
         DEG = 180.0f / (float) Math.PI;

         SIN_BITS  = 12;
         SIN_MASK  = ~(-1 << SIN_BITS);
         SIN_COUNT = SIN_MASK + 1;

         radFull    = (float) (Math.PI * 2.0);
         degFull    = (float) (360.0);
         radToIndex = SIN_COUNT / radFull;
         degToIndex = SIN_COUNT / degFull;

         sin = new float[SIN_COUNT];
         cos = new float[SIN_COUNT];

         for (int i = 0; i < SIN_COUNT; i++)
         {
            sin[i] = (float) Math.sin((i + 0.5f) / SIN_COUNT * radFull);
            cos[i] = (float) Math.cos((i + 0.5f) / SIN_COUNT * radFull);
         }

         // Four cardinal directions (credits: Nate)
         for (int i = 0; i < 360; i += 90)
         {
            sin[(int)(i * degToIndex) & SIN_MASK] = (float)Math.sin(i * Math.PI / 180.0);
            cos[(int)(i * degToIndex) & SIN_MASK] = (float)Math.cos(i * Math.PI / 180.0);
         }
      }
}


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  
package fastSineTest;

public class PFSine {
   
   static final float[] data = makeSineWaveTable();
   
   public static float get(int i)
   {
      return data[i];
   }
   
   public static float get(float i)
   {
      final int idx = (int)i;
     
      return data[idx+1] * (i - idx)
            + data[idx] * ((idx+1) - i);
   }
   
   // mask used for looping through table (assuming 1024)
   public static int getMask()
   {
      return 0x3ff;
   }
   
   public static int getOperationalSize()
   {
      /*
       * Table has one redundant record to allow
       * simpler LERP coding. For example, 1024 records
       * to capture a single SINE cycle, but with a
       * 1025th record added that duplicates the first.
       *     data[0] == data[1024] is TRUE
       * So, since the get(float i) does a lookup of
       * (i + 1), the last allowable position is
       *     i = data.length - 1;
       * Example: incoming < 1024.0 is OK for a table
       * of length 1025 (1024 for cycle + 1 redundant).
       */

      return (data.length - 1);
   }

   private static final int WAVE_TABLE_SIZE = 1025;
   
   public static float[] makeSineWaveTable()
   {  
      float[] audioData = new float[WAVE_TABLE_SIZE];
     
      for (int i = 0; i < WAVE_TABLE_SIZE; i++)
      {
         audioData[i] = (float)(Math.sin(2 * i *
               (Math.PI/(WAVE_TABLE_SIZE - 1))));
      }
     
      return audioData;
   }
}

 
25  Discussions / Miscellaneous Topics / Re: What I did today on: 2015-07-21 21:07:10
Got my three monitors + VESA stand all up and running Cheesy
Nice! How is this wired/cabled? Any particular video card needed to have 3 monitors? Is 4 a possibility?
26  Game Development / Newbie & Debugging Questions / Re: Best Practices for Creating New Objects on: 2015-07-21 20:02:42
Probably no difference between this:
1  
    for (int i = 0, n = entities.size(); i < n; i++)
and this:
1  
2  
    int n = entities.size();
    for (int i = 0; i < n; i++)

??

I can't remember what prompted the change any more, but I started using the former version several years ago. It seems to me there would be no particular advantage now, if there ever was any.

True/false?
27  Discussions / Miscellaneous Topics / Re: What I did today on: 2015-07-21 19:50:50
@J0

I know that game, I have played that ~6 years ago, it was actually the inspiration for my game. But this game is going to be story based. I need the earth to be there in the background according to the story. I think I will replace that texture with a large and improved earth background.

Your game looks polished and interesting! I can also see J0's point about the planet looking a bit like a placeholder.

You may already be light-years ahead of the following information. But for what it is worth, in case it might be helpful, here is some data I used for generating an earth map via Perlin noise. Admittedly, I didn't take the approach to its potential--I was just trying to get a grasp of the basic concepts when exploring this a while back. The color mapping is a tweaked, by-eye remaking of one I found in a tutorial by AngryOctapus. http://www.angryoctopus.co.nz/?p=11 which has various ideas laid out, but would also benefit from using 3D rather than applying a lens. (I can't recall the jgo member name of this person, but he comments here now and again.)

In any event, in this case, the simplex function's -1 to 1 range is mapped to values ranging from 0 to 255 (leftmost column). These values are assigned to RGB values in the middle columns. You'd want to do it 3D instead of flat, of course. The color-mapping shown might be a good starting point for tweaking. The algorithm generating the graphic below just uses a normal sort of fractal octaves--maybe I skipped an octave here or there. (I'm happy to explain further if you haven't already delved into Perlin fractals.)

One could also bias the output towards the white end at the poles of the planet. Or tweak the colors to make it more other-worldly or more accurately reflecting Earth.


28  Games Center / Showcase / Re: VERBAL - the fast-paced thinking word game on: 2015-07-21 02:10:33
Perhaps I can implement swipe gestures to rotate left/right, with an upward swipe to remove just one letter from the word bar. So starting with BAR, right swipe twice to insert two empty slots at the beginning, then play RE for REBAR.

Or, left swipe BAR once to get AR, then play BOR for ARBOR.

Or, upward swipe the B in BAR and play O for OAR.

I like these ideas!

I have also struggled with mentally arranging letters while solving the puzzles. An idea I had to ameliorate this would be to offer clues instead of instantly awarding them. So the player could choose to accept a mediocre 5-letter clue or they could discard it. That way you can safely use the word bar to experiment without hurting your score, and you won't get mugged by low value clues any more.

That suggestion helps with the mugging, which happened a couple times to me before I understood what was going on. But the strain on working memory is still pretty high for folks who want to "play Scrabble" with their tiles. Maybe that's a feature, something the Lumosity folks would brag on.

An idea occurs to me: highlighting or otherwise marking the clued letters to make it easier to sort out those where you know where they go versus those that need maneuvering into place. That's one less thing to keep track of mentally, alleviating a bit of the struggle.
29  Games Center / Showcase / Re: VERBAL - the fast-paced thinking word game on: 2015-07-20 16:44:27
Verbal runs great on the emulator I have via Android Studio on Linux. I will try the device I have soon, but might not be able to get to it today.

The version I have has two games: the original speed challenge and the game for finding a 9-letter word using 6-8 letter words to generate clues. I like having the two modes of play to choose between. Sometimes one wants to go for a rush, sometimes one wants to ponder.

I have a suggestion/request for the "Solve the Puzzle" game. Would it be okay to enable one to click and drag the letters to rearrange them? I was having a lot of trouble trying to keep track mentally of what letters might be where. In Scrabble, one can move the tiles about on the tray, and this is very helpful for visualization. Just a swap function between two tiles would add a lot. I found myself occasionally using the strategy of trying out plausible 9-letter words while taking care to avoid 6-8 in the process. Actually managed to score 950 on one of my rounds! Of course there is some luck as some words are easier to find than others.

I was a bit skeptical that a word game would work without a keyboard. For example, with online Boggle, is impossible to get a decent score while only using the mouse to click out words. But you managed to make it work quite well! I think that is a big accomplishment.

One other idea--it would be nice, maybe, if one could add prefixes to an existing word and also get bonuses. For example, I'm thinking click and drag the first letter one (or more) to the right, leaving the first spot empty, then filling it in. BOARD becomes ABOARD, say. (Or have a little button for rightwards rotations.)

I found myself a little miffed at having to redo entire words when only the first letter needs changing. FIGHTER LIGHTER
for example. But that would also add a complication to the UI, requiring drag-and-drop or some other solution.
 
The background graphics are nicely done. They definitely add polish, but at the same time do not distract.

Definitely a fun game!
30  Discussions / Miscellaneous Topics / Re: Music composing on: 2015-07-20 04:44:14
Maybe there is a free version of a notation program like Sibelius or Finale (doesn't Coda have something called Allegro?) that lets you do playback. Or another notation program. If you could code it to MIDI, there might be a way to even play it back using Java's MIDI and record that, but I've never gone that route. Audacity is free and a good product for audio recording and editing, but doesn't play back MIDI unfortunately, as far as I know.

There might be a 30-day trial on a Native Instruments product, like Kontact or whatever their orchestration program is. I use Finale (paid for it) and Sonar Homestudio (paid for it), so haven't looked too deeply into this topic.
Pages: [1] 2 3 ... 41
 
Coldstream24 (11 views)
2015-09-03 00:41:28

Andrew_3ds (23 views)
2015-09-01 19:08:10

afikri (16 views)
2015-08-31 09:30:22

afikri (24 views)
2015-08-31 09:30:07

afikri (12 views)
2015-08-31 09:27:24

afikri (16 views)
2015-08-31 09:26:40

Roquen (23 views)
2015-08-29 11:30:54

GamerC4 (34 views)
2015-08-22 20:38:50

GamerC4 (31 views)
2015-08-22 20:37:18

GamerC4 (37 views)
2015-08-22 20:37:01
HotSpot Options
by Roquen
2015-08-29 11:33:11

Rendering resources
by Roquen
2015-08-17 12:42:29

Rendering resources
by Roquen
2015-08-17 09:36:56

Rendering resources
by Roquen
2015-08-13 07:40:51

Networking Resources
by Roquen
2015-08-13 07:40:43

List of Learning Resources
by gouessej
2015-07-09 11:29:36

How Do I Expand My Game?
by bashfrog
2015-06-14 11:34:43

List of Learning Resources
by PocketCrafter7
2015-05-31 05:37:30
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!