How to have a different sound on each ear in js? - javascript

I need to send different sounds on the left and right ear but I don't succeed to do that. I followed those steps :
loaded my sounds (sentences and one pure tone called 'bip'),
used getChannelData() to work on the raw data (Float32Array) : apply a gain to one of the three sentences I use and do the sum in the variable 'source' to hear the 3 sentences simultaneously.
used createBuffer(1,source.length,fs) to turn my source variable from type Float32Array to AudioBuffer.
finally used createBufferSource() where I can put my buffer to play it.
It worked well but now I need to play those sentence in the 'source' variable in the left ear and the 'bip' sound in the variable of the same name in the right ear. So, I did the modifications you can bellow to put the source variable and the bip variable in one different channel. The problem is that when I hear it sentences are not completely on the left and bip is not completely on the right. I hear that it's not completely mixed but it's not completely separate. I don't understand why and how to fix it. Do js mix the channels before playing ? How could I do to really have one sound on left and the other on the right ? I didn't precise but right and left needs to be simultaneous, it's for an auditory test. I tried with StereoPannerNode and pan but it didn't work well, two problems : (1) yes I can have more level on left or right to have a balanced sound but I can't put all the sound in one hear... and (2) it seems that I can't use it to put one sound on the left and one the right because it's acting on the final mix...
// concatenate all sentences and put it in a buffer
let buffer = context.createBuffer(2, source.length, fs);
let bufferData = {
l: buffer.getChannelData(0),
r: buffer.getChannelData(1)
};
bufferData.l.set(source);
bufferData.r.set(bip);
// create a source that will be used to play the buffer
trial.sound = context.createBufferSource();
trial.sound.buffer = buffer;
trial.sound.connect(context.destination);
EDIT: The comment of Raymond Toy helped me to find the solution. When I tried his little test code it doesn't work well whereas js said it is (context.destination.channelCount = 2). It makes me remember about something that causes me a lot of problem before : the preinstalled Dolby software (as you can see below, now it's disabled). It's basically a filter (I thought) and... a mixer, I just realised it by trying to disable it. Enable : sound in the two ears, Disable : one sound in each ear... So my problem is solved in part because I need to make it work for anybody, the only solution I have for the moment is to make a video to explain to viewers how to disable it before doing the test...
Note that I can also let Dobly enabled but quote the box you see in the next image "désactiver les effets sonores" i.e. "disabled sound effects"
:

This should have worked. As a simple test of your setup, try the following (untested):
// context is the AudioContext.
let s1 = new OscillatorNode(context, {frequency: 440});
let s2 = new OscillatorNode(context, {frequency: 880});
let g1 = new GainNode(context);
let g2 = new GainNode(context);
let merger = new ChannelMergerNode(context, {numberOfInputs: 2});
merger.connect(context.destination);
s1.connect(g1).connect(merger, 0, 0);
s2.connect(g2).connect(merger, 0, 1);
s1.start();
s2.start();
You should hear a 440 Hz tone in one ear and an 880 Hz tone in the other. This, of course, assumes your audio HW supports stereo. Check to see if context.destination.channelCount is actually two.
If it still sounds funny, try setting g1.gain.value=0 or g2.gain.value=0 (but not both). This should force sound to go to only the left or right. If not, something else is wrong. I tested this at https://hoch.github.io/canopy and it's working as I expected.

Related

How To Change the turn in chessboard.js?

I am working in chessboard.js for creating a multyplayer chessboard using signalR.
but i am having a problem in player movement.
what i am doing is sending the FEN string from client1 to client2.and Thus client2 represent that FEN string on board.
Now the problem is that the player2 represent the FEN on Board but player turn is not changed by FEN.
So both Player 1 and 2 move white first then black secondly.and that is not to be supposed.
i want Player1 moves from white side.His FEN is send To Player2.then Player2 will Move with Black Color (but currently player2 move with white which is error).
So please help me how to change the turn of player1 or player2 forcely.
I was struggling with the same issue when creating a similar multiplayer chess game using chessboard.js along with chess.js (the engine running the actual game rules)
The answer lies within the chess.js file that is referenced on the chessboard.js api documentation.
Line 157 of chess.js has this:
var turn = WHITE;
If you wish to change the turn of the whole game you can simply do this:
turn = BLACK;
turn = WHITE;
turn = "w";
turn = "b";
Any of them will work. I also created a convenience function that can be more easily used by other scripts which adds setTurn() and turn() to the public API..
Convenience function to add to API for turn manipulation:
Around line 1115 of chess.js (not chessboard.js), you will find a function that starts off with:
return {
/***************************************************************************
* PUBLIC CONSTANTS (is there a better way to do this?)
**************************************************************************
I simply added The following to right below the comment:
turn: function() {
return turn;
},
setTurn: function(newTurn) {
turn = newTurn;
},
The result is that now from either any instance of chess.js
(default name is game), you can simply change turns like this:
game.setTurn("b");
game.setTurn("w");
This is but one hurdle that I ran into while making a multiplayer version. The next hurdle you will likely face is going to be: what happens if a player gets disconnected or doesn't respond? How about if they inject a JS file into the page that allows them to change turns at will? These issues will be more of a pain to solve. Also look out for other types of injection attacks such as manipulation of the game FEN externally.
Good luck!
Leave comment if you want me to share my source code -- I figured out most of the issues that come up with chessboard.js as multiplayer.

memory leak while drawing many new images to canvas

I have written a "slide show" that displays images sequentially and quickly, much like a stop-frame movie.
Once an image is displayed, I have no further use for it and would like to clear it from memory to free space for new images. However, while monitoring Google Chrome Helper in Activity Monitor, I see that the memory continues to increase steadily until the browser crashes.
I noticed a chrome garbage collection issue that was submitted as a bug and I'm wondering if maybe I'm experiencing this?
Otherwise, here is one example of a trick I tried based on this post to get Chrome to trash my old image data.
function ClearChunk()
{
imageSet1 = null; // garbage collect please?
imageSet1 = [];
}
function LoadNewChunk()
{
for (i=start_of_chunk;i<end_of_chunk;i++)
{
imageSet1[i-start_of_chunk] = new Image();
imageSet1[i-start_of_chunk].src = img[i];
}
}
This clears first and then loads in the background, all while another array of images are being displayed. It seemed like a good idea at the time, but on my machine it still climbs steadily to about 3Gb and... Aw, Snap.
How to mitigate this rampant memory consumption in the first place?
Any conversational or code-based feedback would be appreciated.
Try doing only one 'new Image()', and reuse that, instead of creating many in the loop. This helped me solve the same issue.
webworkers ? perhaps ?
==============
recently saw something about....
if you declare a variable like...
var tempa = 0;
vs not actually declaring the variable. but just assigning it something.
var tempa = 0; // DO NOT DO
temp_no_var = 0; // there is some sort of "delete" ability that removes variable from memory or rather reduces memory space.
perhaps after image is used simply assining it null or 0. vs leaving the image data in a variable and hopefully waiting for garbage collection.
==================
re-using variables, vs making huge arrays that just keep on growing and growing.
==================
check out imagemagik and see about creating a "gif" animated picture. if information in the movie clip errr set of images, does not change.

Detecting irregular Shape

Leading up from this question Detecting mouse coordinates with precision, I have learnt quite a bit in the past few days. Here are what I picked as best learning resources on this topic:
http://gamedev.tutsplus.com/tutorials/implementation/quick-tip-use-quadtrees-to-detect-likely-collisions-in-2d-space/
http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/quadtrees-r1303
http://jsfiddle.net/2dchA/2/
The code in (3) works in JSFiddle but breaks at this section in my testing environment (VS2012):
var myTree = new Quadtree({
x: 0,
y: 0,
width: 400,
height: 300
});
with the message Quadtree is undefined in IE. FF & Chrome just gloss over it and display an empty page. I couldn't sort it out. Question 1: Can someone help out with that?
My main question:
I have a region (parcels of land like a map) with about 1500 parcels drawn in html5, not jpg or png images. It is a lot of lines of code to complete that but the rendering is great, so I am keeping it that way. I intend to have a mouseover event tell me which parcel I am standing on when the mouse stops. As you will see in the previous question referred my previous attempts were not impressive. Based on the learning I have been doing, and thanks to Ken J's answer/comments, I would like to go with this new approach of slicing up my canvas into say 15 quads of 100 objects each. However, I would like some guidance before I take another wild dive the wrong way.
Question 2: Should I slice it up at creation or should the slicing happen when the mouse is over a region, ie, trail the mouse? The latter sounds better to me but I think I can do with some advice and, if possible, some start out code. The quadtree concept is completely new to me. Thanks.
Can't help with question 1.
You should definitely build the tree as early as possible, given that the objective is to get the page to respond as quick as possible once the user clicks somewhere.
Keep the tree for as long as the user interacts with the 2d area. Updating a quad tree shouldn't be too hard, so even if the area changes contents, you should be able to reuse the existing tree (just update it).
Given the fact that your draw area is well know i see no advantage in a QuadTree over a spacial hash function. This function will give you an integer out of an (x,y) point.
var blocWidth = 20;
var blocHeight = 20;
var blocsPerLine = ( 0 | ( worldWidth / blocWidth) ) + 1 ;
function hashPoint(x,y) {
return ( 0 | (x/blocWidth)) + blocsPerLine*(0|(y/blocHeight));
}
once you built that, hash all your parcels within an array :
parcelHash = [];
function addHash(i,p) {
if (!parcelHash[i]) { parcelHash[i]=[ p ]; return; }
if (parcelHash[i].indexOf(p) != -1 ) return;
parcelHash[i].push(p);
}
function hashParcel (p) {
var thisHash = hashPoint(p.x,p.y); // upper left
addHash( thisHash, p);
thisHash = hashPoint(p.x+width, p.y); // upper right
addHash(thisHash, p);
thisHash = hashPoint(p.x, p.y+p.height); // lower left
addHash(thisHash, p);
thisHash = hashPoint(p.x+width, p.y+p.height); // lower right
addHash(thisHash, p);
};
for (var i=0; i<allParcels.length; i++) { hashParcel(allParcels[i]) };
now if you have a mouse position, you can retrieve all the parcels in the
same block with :
function getParcels(x,y) {
var thisHash = hashPoint(x,y);
return parcelHash[thisHash];
}
I'll just give you few tips in addition to what others have said.
... have a mouseover event tell me which parcel I am standing on ...
From your other messages I conclude that parcels will have irregular shapes. Quadtrees in general work with rectangles, so you'd have to calculate the bounding rectangle around the shape of the parcel and insert that rectangle in the quadtree. Then are when you want to determine whether mouse is over a parcel, you'll query the quadtree which will give you a set of parcels that might be under the mouse, but you'll have to then do a more precise check on your own to see if it indeed is.
... when the mouse stops.
From your other questions I saw that you try to detect when the mouse has "stopped". Maybe you should look at it this way: mouse cursor is never moving, it's teleporting around the screen from previous point to next. It's always stopped, never moving. This might seem a bit philosophical, but it'll keep your code simpler. You should definitely be able to achieve what you intended without any setTimeout checks.
... slicing up my canvas into say 15 quads of 100 objects each.
... Should I slice it up at creation or should the slicing happen when the mouse is over a region
You won't (and can't) do slicing, quadtree implementation does that automatically (that's its purpose) when you insert or remove items from it (note that moving the item is actually removing then re-inserting it).
I didn't look into the implementation of quadtree that you're using, but here are two MX-CIF quadtree implementations in case that one doesn't work out for you:
https://github.com/pdehn/jsQuad
https://github.com/bjornharrtell/jsts/tree/master/src/jsts/index/quadtree
The problem in question 1 probably happens because jsfiddle (http) page is trying access quadtree.js which is on https

Detect loops in computer player in a cardgame

A while ago I created a small cardgame web app for fun. The player plays against the computer and mostly it works fine. Sometimes though the computer player gets into a loop, the point of the game is to lose all your cards and if you don't have a card to play you take the pile. Sometimes the computer plays x,y,z, takes the pile, plays x,yz, takes the pile etc.
I keep track of the moves I've made, so at any point I have an array that looks something like : [C2,D5,H2,S4,C5,H2,S4,C5,H2,S4,C5]
In this case I can see that I've gotten into a loop of playing H2,S4,C5, then taking the pile and then repeating.
So, the generalized problem is, what's the best way to detect repeating patterns in a list? I could probably whip something up using a simple for loop, trying to find the card I'm about to play and if I find that in position x then I could check whether the pattern from x to n repeats at position x-(n-x) to x, but this seems like the kind of problem that could have a nice algorithm for it. How would you code this given the following function signature:
function findLoops(previousMoves, nextMove, maxPatternLength) {
//Return [loopLength, loopCount] or null if there are no loops
}
p.s. this is not a homework assignment, the game exists and is at http://www.idiot-cardgame.com if anyone is interested :)
First the general question: Your suggested method
trying to find the card I'm about to play and if I find that in position x then I could check whether the pattern from x to n repeats at position x-(n-x) to x,
looks really good. I would suggest basically the same. It is O(n) and needs a fixed amount of storage, and is simple: what else would you wish for?
Second: You can check for repetition in games generally if you keep a hash table of all previous game states (complete state, nothing left out). Everytime you reach a new state look up if it is in the hashtable, if its in it: you game state is looping.
In Javascript you have builtin hastables so this is very easy to do with something similar like this:
new_state = next_move(old_state);
new_encoded_state = encode(new_state); // make it into a string
if (allstates[new_encoded_state]) {
// we are looping!
} else {
allstates[new_encoded_state] = 1;
// no looping
}
The variable allstates is not an Array but of type Object. You can have array like access with strings and this uses the Object as hastable.

How can I make my counter look less fake?

I'm using this bit of code to display the number of users on a site.
My customer is complaining it looks fake. Any suggestions?
var visitors = 187584;
var updateVisitors = function()
{
visitors++;
var vs = visitors.toString(),
i = Math.floor(vs.length / 3),
l = vs.length % 3;
while (i-->0) if (!(l==0&&i==0))
vs = vs.slice(0,i*3+l)
+ ','
+ vs.slice(i*3+l);
$('#count').text(vs);
setTimeout(updateVisitors, Math.random()*2000);
};
setTimeout(updateVisitors, Math.random()*2000);
Edited:
alt text http://img695.imageshack.us/img695/4268/reachdevs2.png
Screenshot-Advertise - Stack Overflow - Chromium http://img130.imageshack.us/img130/8083/screenshotadvertisestac.png
http://inedomedia.com/stackoverflow.aspx
Everyone knows JS counters are fake, don't bother trying to make it look "less fake", bother making a real one.
If you don't have enough visitors to show around, just don't use a counter, they're so 90's.
Warning: Attempted Humour
Did he ask for a giant splash page to go along with the fake real-time visitor counter? How about some nice "Netscape Now!" button logos and blinking text? Here are some really cool "under construction" animated gifs you can use too.
http://www.animatedgif.net/underconstruction/construction.shtml
-Oisin
I'm guessing it looks fake because every time you load the page it starts at the same number and counts upwards?
Take a look at the javascript that tells you how many megabytes of email storage you get with a Gmail account. I think it bases the starting number on the date/time, so that if you load a page, watch it count up, and then load it again, it won't reload with a smaller number.
Be honest though... it is fake right? You aren't showing precisely how many users there are and updating it live as new users create accounts. The goal then is to make sure it is somewhat close to reality. Hopefully the rate at which the number increases in your script is based on past new-user subscription rates.
make the interval parameter of the setInterval random as well ... it will look more real as it will randomly increment the random numbers :)

Categories

Resources