📄 jspositionalsample.java
字号:
float intensityLow = 0.125f; float intensityDifference = intensityHigh - intensityLow; //TODO: time around "average" default head // int delayHigh = 32; // 32.15 samples = .731 ms // int delayLow = 0; float intensityOffset; // 0.0 -> 1.0 then 1.0 -> 0.0 for full rotation float halfX; int id; int err; float nearZero = 0.000001f; float nearOne = 0.999999f; float nearNegativeOne = -nearOne; float halfPi = (float)Math.PI * 0.5f; /* * Parameters used for IID and ITD equations. * Name of parameters (as used in Guide, E.3) are denoted in comments. */ float distanceSourceToCenterEar = 0.0f; // Dh float lastDistanceSourceToCenterEar = 0.0f; float distanceSourceToRightEar = 0.0f; // Ef or Ec float distanceSourceToLeftEar = 0.0f; // Ef or Ec float distanceBetweenEars = 0.18f; // De float radiusOfHead = 0.0f; // De/2 float radiusOverDistanceToSource = 0.0f; // De/2 * 1/Dh float alpha = 0.0f; // 'alpha' float sinAlpha = 0.0f; // sin(alpha); float gamma = 0.0f; // 'gamma' // Speed of Sound (unaffected by rolloff) in millisec/meters float speedOfSound = attribs.SPEED_OF_SOUND; float invSpeedOfSound = 1.0f / attribs.SPEED_OF_SOUND; float sampleRate = 44.1f; // 44 samples/millisec boolean rightEarClosest = false; boolean soundFromBehind = false; float distanceGain = 1.0f; float allGains = this.gain; // product of gain scale factors Point3f workingPosition = new Point3f(); Point3f workingCenterEar = new Point3f(); // Asuumes that head and ear positions can be retrieved from universe Vector3f mixScale = new Vector3f(); // for mix*Samples code // Use transformed position of this sound workingPosition.set(positions[currentIndex]); workingCenterEar.set(centerEars[currentIndex]); if (debugFlag) { debugPrint("panSample:workingPosition from" + " positions["+currentIndex+"] -> " + workingPosition.x + ", " + workingPosition.y + ", " + workingPosition.z + " for pointSound " + this); debugPrint("panSample:workingCenterEar " + workingCenterEar.x + " " + workingCenterEar.y + " " + workingCenterEar.z); debugPrint("panSample:xformLeftEar " + xformLeftEar.x + " " + xformLeftEar.y + " " + xformLeftEar.z); debugPrint("panSample:xformRightEar " + xformRightEar.x + " " + xformRightEar.y + " " + xformRightEar.z); } // Create the vectors from the sound source to head positions sourceToCenterEar.x = workingCenterEar.x - workingPosition.x; sourceToCenterEar.y = workingCenterEar.y - workingPosition.y; sourceToCenterEar.z = workingCenterEar.z - workingPosition.z; sourceToRightEar.x = xformRightEar.x - workingPosition.x; sourceToRightEar.y = xformRightEar.y - workingPosition.y; sourceToRightEar.z = xformRightEar.z - workingPosition.z; sourceToLeftEar.x = xformLeftEar.x - workingPosition.x; sourceToLeftEar.y = xformLeftEar.y - workingPosition.y; sourceToLeftEar.z = xformLeftEar.z - workingPosition.z; /* * get distances from SoundSource to * (i) head origin * (ii) right ear * (iii) left ear */ distanceSourceToCenterEar = workingPosition.distance(workingCenterEar); distanceSourceToRightEar = workingPosition.distance(xformRightEar); distanceSourceToLeftEar = workingPosition.distance(xformLeftEar); distanceBetweenEars = xformRightEar.distance(xformLeftEar); if (debugFlag) debugPrint(" distance from left,right ears to source: = (" + distanceSourceToLeftEar + ", " + distanceSourceToRightEar + ")"); radiusOfHead = distanceBetweenEars * 0.5f; if (debugFlag) debugPrint(" radius of head = " + radiusOfHead ); radiusOverDistanceToSource = // De/2 * 1/Dh radiusOfHead/distanceSourceToCenterEar; if (debugFlag) debugPrint(" radius over distance = " + radiusOverDistanceToSource ); if (debugFlag) { debugPrint("panSample:source to center ear " + sourceToCenterEar.x + " " + sourceToCenterEar.y + " " + sourceToCenterEar.z ); debugPrint("panSample:xform'd Head ZAxis " + xformHeadZAxis.x + " " + xformHeadZAxis.y + " " + xformHeadZAxis.z ); debugPrint("panSample:length of sourceToCenterEar " + sourceToCenterEar.length()); debugPrint("panSample:length of xformHeadZAxis " + xformHeadZAxis.length()); } // Dot Product double dotProduct = (double)( (sourceToCenterEar.dot(xformHeadZAxis))/ (sourceToCenterEar.length() * xformHeadZAxis.length())); if (debugFlag) debugPrint( " dot product = " + dotProduct ); alpha = (float)(Math.acos(dotProduct)); if (debugFlag) debugPrint( " alpha = " + alpha ); if (alpha > halfPi) { if (debugFlag) debugPrint(" sound from behind"); soundFromBehind = true; alpha = (float)Math.PI - alpha; if (debugFlag) debugPrint( " PI minus alpha =>" + alpha ); } else { soundFromBehind = false; if (debugFlag) debugPrint(" sound from in front"); } gamma = (float)(Math.acos(radiusOverDistanceToSource)); if (debugFlag) debugPrint( " gamma " + gamma ); rightEarClosest = (distanceSourceToRightEar>distanceSourceToLeftEar) ? false : true ; /* * Determine the quadrant sound is in */ if (rightEarClosest) { if (debugFlag) debugPrint( " right ear closest"); if (soundFromBehind) quadrant = 4; else quadrant = 1; } else { if (debugFlag) debugPrint( " left ear closest"); if (soundFromBehind) quadrant = 3; else quadrant = 2; } sinAlpha = (float)(Math.sin((double)alpha)); if (sinAlpha < 0.0) sinAlpha = -sinAlpha; if (debugFlag) debugPrint( " sin(alpha) " + sinAlpha ); /* * The path from sound source to the farthest ear is always indirect * (it wraps around part of the head). * Calculate distance wrapped around the head for farthest ear */ float DISTANCE = (float)Math.sqrt((double) distanceSourceToCenterEar * distanceSourceToCenterEar + radiusOfHead * radiusOfHead); if (debugFlag) debugPrint( " partial distance from edge of head to source = " + distanceSourceToCenterEar); if (rightEarClosest) { distanceSourceToLeftEar = DISTANCE + radiusOfHead * (halfPi+alpha-gamma); if (debugFlag) debugPrint(" new distance from left ear to source = " + distanceSourceToLeftEar); } else { distanceSourceToRightEar = DISTANCE + radiusOfHead * (halfPi+alpha-gamma); if (debugFlag) debugPrint(" new distance from right ear to source = " + distanceSourceToRightEar); } /* * The path from the source source to the closest ear could either * be direct or indirect (wraps around part of the head). * if sinAlpha >= radiusOverDistance path of sound to closest ear * is direct, otherwise it is indirect */ if (sinAlpha < radiusOverDistanceToSource) { if (debugFlag) debugPrint(" closest path is also indirect "); // Path of sound to closest ear is indirect if (rightEarClosest) { distanceSourceToRightEar = DISTANCE + radiusOfHead * (halfPi-alpha-gamma); if (debugFlag) debugPrint(" new distance from right ear to source = " + distanceSourceToRightEar); } else { distanceSourceToLeftEar = DISTANCE + radiusOfHead * (halfPi-alpha-gamma); if (debugFlag) debugPrint(" new distance from left ear to source = " + distanceSourceToLeftEar); } } else { if (debugFlag) debugPrint(" closest path is direct "); if (rightEarClosest) { if (debugFlag) debugPrint(" direct distance from right ear to source = " + distanceSourceToRightEar); } else { if (debugFlag) debugPrint(" direct distance from left ear to source = " + distanceSourceToLeftEar); } } /** * Short-cut taken. Rather than using actual delays from source * (where the overall distances would be taken into account in * determining delay) the difference in the left and right delay * are applied. * This approach will be preceptibly wrong for sound sources that * are very far away from the listener so both ears would have * large delay. */ sampleRate = channel.rateInHz * (0.001f); // rate in milliseconds if (rightEarClosest) { rightDelay = 0; leftDelay = (int)((distanceSourceToLeftEar - distanceSourceToRightEar) * invSpeedOfSound * sampleRate); } else { leftDelay = 0; rightDelay = (int)((distanceSourceToRightEar - distanceSourceToLeftEar) * invSpeedOfSound * sampleRate); } if (debugFlag) { debugPrint(" using inverted SoS = " + invSpeedOfSound); debugPrint(" and sample rate = " + sampleRate); debugPrint(" left and right delay = (" + leftDelay + ", " + rightDelay + ")"); } // What should the gain be for the different ears??? // TODO: now using a hack that sets gain based on a unit circle!!! workingPosition.sub(workingCenterEar); // offset sound pos. by head origin // normalize; put Sound on unit sphere around head origin workingPosition.scale(1.0f/distanceSourceToCenterEar); if (debugFlag) debugPrint(" workingPosition after unitization " + workingPosition.x+" "+workingPosition.y+" "+workingPosition.z ); /* * Get the correct distance gain scale factor from attenuation arrays. * This requires that sourceToCenterEar vector has been calculated. */ // TODO: now using distance from center ear to source // Using distances from each ear to source would be more accurate distanceGain = calculateDistanceAttenuation(distanceSourceToCenterEar); allGains *= distanceGain; /* * Add angular gain (for Cone sound) */ if (debugFlag) debugPrint(" all Gains (without angular gain) " + allGains); // assume that transfromed Position is already calculated allGains *= this.calculateAngularGain(); if (debugFlag) debugPrint(" (incl. angular gain) " + allGains); halfX = workingPosition.x/2.0f; if (halfX >= 0) intensityOffset = (intensityDifference * (0.5f - halfX)); else intensityOffset = (intensityDifference * (0.5f + halfX)); /* * For now have delay constant for front back sound for now */ if (debugFlag) debugPrint("panSample: quadrant " + quadrant); switch (quadrant) { case 1: // Sound from front, right of center of head case 4: // Sound from back, right of center of head rightGain = allGains * (intensityHigh - intensityOffset); leftGain = allGains * (intensityLow + intensityOffset); break; case 2: // Sound from front, left of center of head case 3: // Sound from back, right of center of head leftGain = allGains * (intensityHigh - intensityOffset); rightGain = allGains * (intensityLow + intensityOffset); break; } /* switch */ if (debugFlag) debugPrint("panSample: left/rightGain " + leftGain + ", " + rightGain); // Combines distance and angular filter to set this sample's current // frequency cutoff value calculateFilter(distanceSourceToCenterEar, attribs); } /* panSample() */// NOTE: setGain in audioengines.Sample is used to set/get user suppled factor// this class uses this single gain value to calculate the left and// right gain values}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -