toxiclibs 0.4.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +16 -0
- data/.mvn/extensions.xml +8 -0
- data/.mvn/wrapper/maven-wrapper.properties +1 -0
- data/.travis.yml +23 -0
- data/CHANGELOG.md +7 -0
- data/COPYING.md +14 -0
- data/Gemfile +10 -0
- data/LICENSE +675 -0
- data/README.md +9 -7
- data/Rakefile +25 -81
- data/examples/README.md +5 -0
- data/examples/attract_repel/attract_repel.rb +30 -0
- data/examples/attract_repel/attractor.rb +23 -0
- data/examples/attract_repel/particle.rb +27 -0
- data/examples/data/ReplicaBold.ttf +0 -0
- data/examples/data/ti_yong.png +0 -0
- data/examples/force_directed/cluster.rb +76 -0
- data/examples/force_directed/force_directed_graph.rb +92 -0
- data/examples/force_directed/node.rb +26 -0
- data/examples/gray_scott_image.rb +74 -0
- data/examples/gray_scott_tone_map.rb +77 -0
- data/examples/implicit.rb +139 -0
- data/examples/inflate_mesh.rb +89 -0
- data/examples/model_align.rb +43 -0
- data/examples/physics_type.rb +77 -0
- data/examples/povmesh/data/mask.jpg +0 -0
- data/examples/povmesh/ftest.rb +59 -0
- data/examples/povmesh/mesh_align.rb +47 -0
- data/examples/povmesh/tentacle.rb +71 -0
- data/examples/simple_cluster/cluster.rb +47 -0
- data/examples/simple_cluster/node.rb +27 -0
- data/examples/simple_cluster/simple_cluster.rb +60 -0
- data/examples/soft_body/blanket.rb +45 -0
- data/examples/soft_body/connection.rb +16 -0
- data/examples/soft_body/particle.rb +22 -0
- data/examples/soft_body/soft_body_square_adapted.rb +55 -0
- data/examples/spherical_harmonics_mesh.rb +50 -0
- data/examples/test_rect.rb +32 -0
- data/lib/toxiclibs.jar +0 -0
- data/lib/toxiclibs.rb +72 -22
- data/lib/toxiclibs/version.rb +1 -1
- data/pom.rb +63 -0
- data/pom.xml +124 -0
- data/src/com/toxi/net/ClientListener.java +41 -0
- data/src/com/toxi/net/ServerListener.java +70 -0
- data/src/com/toxi/net/ServerListenerAdapter.java +47 -0
- data/src/com/toxi/net/ServerState.java +18 -0
- data/src/com/toxi/net/UDPConnection.java +66 -0
- data/src/com/toxi/net/UDPSyncClient.java +81 -0
- data/src/com/toxi/net/UDPSyncServer.java +450 -0
- data/src/com/toxi/nio/UDPClient.java +121 -0
- data/src/com/toxi/nio/UDPClientState.java +32 -0
- data/src/com/toxi/nio/UDPServer.java +129 -0
- data/src/toxi/audio/AudioBuffer.java +229 -0
- data/src/toxi/audio/AudioSource.java +288 -0
- data/src/toxi/audio/DecompressInputStream.java +159 -0
- data/src/toxi/audio/IIRFilter.java +197 -0
- data/src/toxi/audio/JOALUtil.java +388 -0
- data/src/toxi/audio/MultiTimbralManager.java +162 -0
- data/src/toxi/audio/SoundListener.java +154 -0
- data/src/toxi/audio/SynthUtil.java +109 -0
- data/src/toxi/color/AccessCriteria.java +114 -0
- data/src/toxi/color/AlphaAccessor.java +67 -0
- data/src/toxi/color/CMYKAccessor.java +122 -0
- data/src/toxi/color/CMYKDistanceProxy.java +40 -0
- data/src/toxi/color/ColorGradient.java +260 -0
- data/src/toxi/color/ColorList.java +699 -0
- data/src/toxi/color/ColorRange.java +671 -0
- data/src/toxi/color/ColorTheme.java +163 -0
- data/src/toxi/color/DistanceProxy.java +44 -0
- data/src/toxi/color/HSVAccessor.java +113 -0
- data/src/toxi/color/HSVDistanceProxy.java +40 -0
- data/src/toxi/color/HistEntry.java +85 -0
- data/src/toxi/color/Histogram.java +185 -0
- data/src/toxi/color/Hue.java +249 -0
- data/src/toxi/color/LuminanceAccessor.java +78 -0
- data/src/toxi/color/NamedColor.java +935 -0
- data/src/toxi/color/ProximityComparator.java +70 -0
- data/src/toxi/color/RGBAccessor.java +113 -0
- data/src/toxi/color/RGBDistanceProxy.java +41 -0
- data/src/toxi/color/ReadonlyTColor.java +296 -0
- data/src/toxi/color/TColor.java +1677 -0
- data/src/toxi/color/TColorAdapter.java +68 -0
- data/src/toxi/color/ToneMap.java +218 -0
- data/src/toxi/color/theory/AnalogousStrategy.java +140 -0
- data/src/toxi/color/theory/ColorTheoryRegistry.java +139 -0
- data/src/toxi/color/theory/ColorTheoryStrategy.java +56 -0
- data/src/toxi/color/theory/ComplementaryStrategy.java +111 -0
- data/src/toxi/color/theory/CompoundTheoryStrategy.java +143 -0
- data/src/toxi/color/theory/LeftSplitComplementaryStrategy.java +82 -0
- data/src/toxi/color/theory/MonochromeTheoryStrategy.java +103 -0
- data/src/toxi/color/theory/RightSplitComplementaryStrategy.java +82 -0
- data/src/toxi/color/theory/SingleComplementStrategy.java +76 -0
- data/src/toxi/color/theory/SplitComplementaryStrategy.java +77 -0
- data/src/toxi/color/theory/TetradTheoryStrategy.java +114 -0
- data/src/toxi/color/theory/TriadTheoryStrategy.java +77 -0
- data/src/toxi/data/csv/CSVAdapter.java +74 -0
- data/src/toxi/data/csv/CSVFieldMapper.java +212 -0
- data/src/toxi/data/csv/CSVListener.java +61 -0
- data/src/toxi/data/csv/CSVParser.java +202 -0
- data/src/toxi/data/feeds/AtomAuthor.java +49 -0
- data/src/toxi/data/feeds/AtomContent.java +50 -0
- data/src/toxi/data/feeds/AtomEntry.java +111 -0
- data/src/toxi/data/feeds/AtomFeed.java +129 -0
- data/src/toxi/data/feeds/AtomLink.java +62 -0
- data/src/toxi/data/feeds/RSSChannel.java +88 -0
- data/src/toxi/data/feeds/RSSEnclosure.java +60 -0
- data/src/toxi/data/feeds/RSSFeed.java +99 -0
- data/src/toxi/data/feeds/RSSItem.java +104 -0
- data/src/toxi/data/feeds/util/EntityStripper.java +2480 -0
- data/src/toxi/data/feeds/util/Iso8601DateAdapter.java +101 -0
- data/src/toxi/data/feeds/util/Rfc822DateAdapter.java +93 -0
- data/src/toxi/geom/AABB.java +658 -0
- data/src/toxi/geom/Axis3D.java +116 -0
- data/src/toxi/geom/AxisAlignedCylinder.java +163 -0
- data/src/toxi/geom/BernsteinPolynomial.java +94 -0
- data/src/toxi/geom/BezierCurve2D.java +159 -0
- data/src/toxi/geom/BezierCurve3D.java +148 -0
- data/src/toxi/geom/BooleanShapeBuilder.java +185 -0
- data/src/toxi/geom/BoxIntersector.java +52 -0
- data/src/toxi/geom/Circle.java +230 -0
- data/src/toxi/geom/CircleIntersector.java +85 -0
- data/src/toxi/geom/Cone.java +150 -0
- data/src/toxi/geom/ConvexPolygonClipper.java +136 -0
- data/src/toxi/geom/CoordinateExtractor.java +16 -0
- data/src/toxi/geom/Ellipse.java +250 -0
- data/src/toxi/geom/GMatrix.java +2599 -0
- data/src/toxi/geom/GVector.java +833 -0
- data/src/toxi/geom/GlobalGridTesselator.java +54 -0
- data/src/toxi/geom/GridTesselator.java +108 -0
- data/src/toxi/geom/Intersector2D.java +49 -0
- data/src/toxi/geom/Intersector3D.java +51 -0
- data/src/toxi/geom/IsectData2D.java +103 -0
- data/src/toxi/geom/IsectData3D.java +103 -0
- data/src/toxi/geom/Line2D.java +534 -0
- data/src/toxi/geom/Line3D.java +471 -0
- data/src/toxi/geom/LineStrip2D.java +430 -0
- data/src/toxi/geom/LineStrip3D.java +230 -0
- data/src/toxi/geom/LocalGridTesselator.java +57 -0
- data/src/toxi/geom/Matrix3d.java +3048 -0
- data/src/toxi/geom/Matrix4f.java +3446 -0
- data/src/toxi/geom/Matrix4x4.java +1076 -0
- data/src/toxi/geom/MatrixSizeException.java +58 -0
- data/src/toxi/geom/OctreeVisitor.java +44 -0
- data/src/toxi/geom/Origin3D.java +148 -0
- data/src/toxi/geom/Plane.java +293 -0
- data/src/toxi/geom/PlaneIntersector.java +57 -0
- data/src/toxi/geom/PointCloud3D.java +253 -0
- data/src/toxi/geom/PointOctree.java +502 -0
- data/src/toxi/geom/PointQuadtree.java +375 -0
- data/src/toxi/geom/Polygon2D.java +1038 -0
- data/src/toxi/geom/PolygonClipper2D.java +45 -0
- data/src/toxi/geom/PolygonTesselator.java +20 -0
- data/src/toxi/geom/QuadtreeVisitor.java +44 -0
- data/src/toxi/geom/Quaternion.java +641 -0
- data/src/toxi/geom/Ray2D.java +146 -0
- data/src/toxi/geom/Ray3D.java +150 -0
- data/src/toxi/geom/Ray3DIntersector.java +75 -0
- data/src/toxi/geom/ReadonlyVec2D.java +575 -0
- data/src/toxi/geom/ReadonlyVec3D.java +628 -0
- data/src/toxi/geom/ReadonlyVec4D.java +431 -0
- data/src/toxi/geom/Rect.java +720 -0
- data/src/toxi/geom/Reflector3D.java +58 -0
- data/src/toxi/geom/Shape2D.java +94 -0
- data/src/toxi/geom/Shape3D.java +42 -0
- data/src/toxi/geom/SingularMatrixException.java +57 -0
- data/src/toxi/geom/SpatialBins.java +182 -0
- data/src/toxi/geom/SpatialIndex.java +61 -0
- data/src/toxi/geom/Sphere.java +224 -0
- data/src/toxi/geom/SphereIntersectorReflector.java +196 -0
- data/src/toxi/geom/Spline2D.java +349 -0
- data/src/toxi/geom/Spline3D.java +351 -0
- data/src/toxi/geom/SutherlandHodgemanClipper.java +151 -0
- data/src/toxi/geom/Triangle2D.java +422 -0
- data/src/toxi/geom/Triangle3D.java +456 -0
- data/src/toxi/geom/TriangleIntersector.java +105 -0
- data/src/toxi/geom/Vec2D.java +1328 -0
- data/src/toxi/geom/Vec3D.java +1832 -0
- data/src/toxi/geom/Vec4D.java +985 -0
- data/src/toxi/geom/VecMathUtil.java +100 -0
- data/src/toxi/geom/XAxisCylinder.java +64 -0
- data/src/toxi/geom/YAxisCylinder.java +65 -0
- data/src/toxi/geom/ZAxisCylinder.java +64 -0
- data/src/toxi/geom/mesh/BezierPatch.java +200 -0
- data/src/toxi/geom/mesh/BoxSelector.java +62 -0
- data/src/toxi/geom/mesh/DefaultSTLColorModel.java +67 -0
- data/src/toxi/geom/mesh/DefaultSelector.java +50 -0
- data/src/toxi/geom/mesh/Face.java +176 -0
- data/src/toxi/geom/mesh/LaplacianSmooth.java +80 -0
- data/src/toxi/geom/mesh/MaterialiseSTLColorModel.java +150 -0
- data/src/toxi/geom/mesh/Mesh3D.java +224 -0
- data/src/toxi/geom/mesh/MeshIntersector.java +91 -0
- data/src/toxi/geom/mesh/OBJWriter.java +194 -0
- data/src/toxi/geom/mesh/PLYWriter.java +167 -0
- data/src/toxi/geom/mesh/PlaneSelector.java +90 -0
- data/src/toxi/geom/mesh/STLColorModel.java +54 -0
- data/src/toxi/geom/mesh/STLReader.java +185 -0
- data/src/toxi/geom/mesh/STLWriter.java +323 -0
- data/src/toxi/geom/mesh/SphereFunction.java +156 -0
- data/src/toxi/geom/mesh/SphericalHarmonics.java +110 -0
- data/src/toxi/geom/mesh/SuperEllipsoid.java +110 -0
- data/src/toxi/geom/mesh/SurfaceFunction.java +75 -0
- data/src/toxi/geom/mesh/SurfaceMeshBuilder.java +149 -0
- data/src/toxi/geom/mesh/Terrain.java +451 -0
- data/src/toxi/geom/mesh/TriangleMesh.java +1201 -0
- data/src/toxi/geom/mesh/Vertex.java +78 -0
- data/src/toxi/geom/mesh/VertexSelector.java +193 -0
- data/src/toxi/geom/mesh/WEFace.java +100 -0
- data/src/toxi/geom/mesh/WEMeshFilterStrategy.java +51 -0
- data/src/toxi/geom/mesh/WETriangleMesh.java +761 -0
- data/src/toxi/geom/mesh/WEVertex.java +134 -0
- data/src/toxi/geom/mesh/WingedEdge.java +115 -0
- data/src/toxi/geom/mesh/subdiv/CentroidSubdiv.java +37 -0
- data/src/toxi/geom/mesh/subdiv/DisplacementSubdivision.java +85 -0
- data/src/toxi/geom/mesh/subdiv/DualDisplacementSubdivision.java +94 -0
- data/src/toxi/geom/mesh/subdiv/DualSubdivision.java +49 -0
- data/src/toxi/geom/mesh/subdiv/EdgeLengthComparator.java +50 -0
- data/src/toxi/geom/mesh/subdiv/FaceCountComparator.java +51 -0
- data/src/toxi/geom/mesh/subdiv/MidpointDisplacementSubdivision.java +80 -0
- data/src/toxi/geom/mesh/subdiv/MidpointSubdiv.java +42 -0
- data/src/toxi/geom/mesh/subdiv/MidpointSubdivision.java +48 -0
- data/src/toxi/geom/mesh/subdiv/NewSubdivStrategy.java +23 -0
- data/src/toxi/geom/mesh/subdiv/NormalDisplacementSubdivision.java +74 -0
- data/src/toxi/geom/mesh/subdiv/SubdivisionStrategy.java +83 -0
- data/src/toxi/geom/mesh/subdiv/TriSubdivision.java +51 -0
- data/src/toxi/geom/mesh2d/DelaunayTriangle.java +222 -0
- data/src/toxi/geom/mesh2d/DelaunayTriangulation.java +327 -0
- data/src/toxi/geom/mesh2d/DelaunayVertex.java +560 -0
- data/src/toxi/geom/mesh2d/Voronoi.java +149 -0
- data/src/toxi/geom/nurbs/BasicNurbsCurve.java +210 -0
- data/src/toxi/geom/nurbs/BasicNurbsSurface.java +233 -0
- data/src/toxi/geom/nurbs/ControlNet.java +148 -0
- data/src/toxi/geom/nurbs/CurveCreator.java +112 -0
- data/src/toxi/geom/nurbs/CurveUtils.java +259 -0
- data/src/toxi/geom/nurbs/InterpolationException.java +65 -0
- data/src/toxi/geom/nurbs/KnotVector.java +333 -0
- data/src/toxi/geom/nurbs/NurbsCreator.java +815 -0
- data/src/toxi/geom/nurbs/NurbsCurve.java +120 -0
- data/src/toxi/geom/nurbs/NurbsMeshCreator.java +145 -0
- data/src/toxi/geom/nurbs/NurbsSurface.java +147 -0
- data/src/toxi/image/util/Filter8bit.java +331 -0
- data/src/toxi/image/util/TiledFrameExporter.java +162 -0
- data/src/toxi/math/BezierInterpolation.java +102 -0
- data/src/toxi/math/CircularInterpolation.java +88 -0
- data/src/toxi/math/CosineInterpolation.java +51 -0
- data/src/toxi/math/DecimatedInterpolation.java +77 -0
- data/src/toxi/math/ExponentialInterpolation.java +68 -0
- data/src/toxi/math/InterpolateStrategy.java +60 -0
- data/src/toxi/math/Interpolation2D.java +93 -0
- data/src/toxi/math/LinearInterpolation.java +46 -0
- data/src/toxi/math/MathUtils.java +990 -0
- data/src/toxi/math/NonLinearScaleMap.java +101 -0
- data/src/toxi/math/ScaleMap.java +183 -0
- data/src/toxi/math/SigmoidInterpolation.java +78 -0
- data/src/toxi/math/SinCosLUT.java +141 -0
- data/src/toxi/math/ThresholdInterpolation.java +58 -0
- data/src/toxi/math/ZoomLensInterpolation.java +126 -0
- data/src/toxi/math/conversion/UnitTranslator.java +161 -0
- data/src/toxi/math/noise/PerlinNoise.java +281 -0
- data/src/toxi/math/noise/SimplexNoise.java +542 -0
- data/src/toxi/math/waves/AMFMSineWave.java +143 -0
- data/src/toxi/math/waves/AbstractWave.java +248 -0
- data/src/toxi/math/waves/ConstantWave.java +48 -0
- data/src/toxi/math/waves/FMHarmonicSquareWave.java +155 -0
- data/src/toxi/math/waves/FMSawtoothWave.java +144 -0
- data/src/toxi/math/waves/FMSineWave.java +142 -0
- data/src/toxi/math/waves/FMSquareWave.java +143 -0
- data/src/toxi/math/waves/FMTriangleWave.java +126 -0
- data/src/toxi/math/waves/SineWave.java +81 -0
- data/src/toxi/math/waves/Wave2D.java +68 -0
- data/src/toxi/math/waves/WaveState.java +69 -0
- data/src/toxi/music/scale/AbstractScale.java +117 -0
- data/src/toxi/music/scale/GenericScale.java +66 -0
- data/src/toxi/music/scale/MajorScale.java +41 -0
- data/src/toxi/newmesh/AttributedEdge.java +106 -0
- data/src/toxi/newmesh/AttributedFace.java +63 -0
- data/src/toxi/newmesh/IndexedTriangleMesh.java +809 -0
- data/src/toxi/newmesh/MeshAttributeCompiler.java +45 -0
- data/src/toxi/newmesh/MeshFaceNormalCompiler.java +52 -0
- data/src/toxi/newmesh/MeshUVCompiler.java +52 -0
- data/src/toxi/newmesh/MeshVertexColorCompiler.java +49 -0
- data/src/toxi/newmesh/MeshVertexCompiler.java +54 -0
- data/src/toxi/newmesh/MeshVertexNormalCompiler.java +55 -0
- data/src/toxi/newmesh/SpatialIndex.java +78 -0
- data/src/toxi/physics2d/ParticlePath2D.java +100 -0
- data/src/toxi/physics2d/ParticleString2D.java +184 -0
- data/src/toxi/physics2d/PullBackSpring2D.java +51 -0
- data/src/toxi/physics2d/VerletConstrainedSpring2D.java +89 -0
- data/src/toxi/physics2d/VerletMinDistanceSpring2D.java +57 -0
- data/src/toxi/physics2d/VerletParticle2D.java +457 -0
- data/src/toxi/physics2d/VerletPhysics2D.java +448 -0
- data/src/toxi/physics2d/VerletSpring2D.java +181 -0
- data/src/toxi/physics2d/behaviors/AttractionBehavior2D.java +212 -0
- data/src/toxi/physics2d/behaviors/ConstantForceBehavior2D.java +112 -0
- data/src/toxi/physics2d/behaviors/GravityBehavior2D.java +61 -0
- data/src/toxi/physics2d/behaviors/ParticleBehavior2D.java +66 -0
- data/src/toxi/physics2d/constraints/AngularConstraint.java +83 -0
- data/src/toxi/physics2d/constraints/AxisConstraint.java +71 -0
- data/src/toxi/physics2d/constraints/CircularConstraint.java +69 -0
- data/src/toxi/physics2d/constraints/MaxConstraint.java +66 -0
- data/src/toxi/physics2d/constraints/MinConstraint.java +66 -0
- data/src/toxi/physics2d/constraints/ParticleConstraint2D.java +47 -0
- data/src/toxi/physics2d/constraints/PolygonConstraint.java +93 -0
- data/src/toxi/physics2d/constraints/RectConstraint.java +114 -0
- data/src/toxi/physics3d/ParticlePath3D.java +100 -0
- data/src/toxi/physics3d/ParticleString3D.java +184 -0
- data/src/toxi/physics3d/PullBackSpring3D.java +50 -0
- data/src/toxi/physics3d/VerletConstrainedSpring3D.java +88 -0
- data/src/toxi/physics3d/VerletMinDistanceSpring3D.java +56 -0
- data/src/toxi/physics3d/VerletParticle3D.java +385 -0
- data/src/toxi/physics3d/VerletPhysics3D.java +417 -0
- data/src/toxi/physics3d/VerletSpring3D.java +180 -0
- data/src/toxi/physics3d/behaviors/AttractionBehavior3D.java +182 -0
- data/src/toxi/physics3d/behaviors/ConstantForceBehavior3D.java +92 -0
- data/src/toxi/physics3d/behaviors/GravityBehavior3D.java +61 -0
- data/src/toxi/physics3d/behaviors/ParticleBehavior3D.java +52 -0
- data/src/toxi/physics3d/constraints/AxisConstraint.java +68 -0
- data/src/toxi/physics3d/constraints/BoxConstraint.java +121 -0
- data/src/toxi/physics3d/constraints/CylinderConstraint.java +87 -0
- data/src/toxi/physics3d/constraints/MaxConstraint.java +65 -0
- data/src/toxi/physics3d/constraints/MinConstraint.java +65 -0
- data/src/toxi/physics3d/constraints/ParticleConstraint3D.java +49 -0
- data/src/toxi/physics3d/constraints/PlaneConstraint.java +78 -0
- data/src/toxi/physics3d/constraints/SoftBoxConstraint.java +87 -0
- data/src/toxi/physics3d/constraints/SphereConstraint.java +108 -0
- data/src/toxi/processing/ArrowModifier.java +116 -0
- data/src/toxi/processing/DashedLineModifier.java +48 -0
- data/src/toxi/processing/DeltaOrientationMapper.java +57 -0
- data/src/toxi/processing/Line2DRenderModifier.java +18 -0
- data/src/toxi/processing/MeshToVBO.java +127 -0
- data/src/toxi/processing/NormalMapper.java +18 -0
- data/src/toxi/processing/POVInterface.java +121 -0
- data/src/toxi/processing/POVMesh.java +219 -0
- data/src/toxi/processing/POVWriter.java +460 -0
- data/src/toxi/processing/RCOpaque.java +77 -0
- data/src/toxi/processing/RCTransp.java +78 -0
- data/src/toxi/processing/TextureBuilder.java +232 -0
- data/src/toxi/processing/Textures.java +110 -0
- data/src/toxi/processing/ToxiclibsSupport.java +1239 -0
- data/src/toxi/processing/Tracing.java +25 -0
- data/src/toxi/processing/XYZNormalMapper.java +30 -0
- data/src/toxi/sim/automata/CAMatrix.java +297 -0
- data/src/toxi/sim/automata/CARule.java +76 -0
- data/src/toxi/sim/automata/CARule2D.java +354 -0
- data/src/toxi/sim/automata/CAWolfram1D.java +309 -0
- data/src/toxi/sim/automata/EvolvableMatrix.java +61 -0
- data/src/toxi/sim/automata/MatrixEvolver.java +42 -0
- data/src/toxi/sim/dla/BottomUpOrder.java +76 -0
- data/src/toxi/sim/dla/DLA.java +497 -0
- data/src/toxi/sim/dla/DLAConfiguration.java +364 -0
- data/src/toxi/sim/dla/DLAEventAdapter.java +64 -0
- data/src/toxi/sim/dla/DLAEventListener.java +57 -0
- data/src/toxi/sim/dla/DLAGuideLines.java +219 -0
- data/src/toxi/sim/dla/DLAParticle.java +102 -0
- data/src/toxi/sim/dla/DLASegment.java +88 -0
- data/src/toxi/sim/dla/PipelineOrder.java +50 -0
- data/src/toxi/sim/dla/RadialDistanceOrder.java +92 -0
- data/src/toxi/sim/erosion/ErosionFunction.java +122 -0
- data/src/toxi/sim/erosion/TalusAngleErosion.java +145 -0
- data/src/toxi/sim/erosion/ThermalErosion.java +75 -0
- data/src/toxi/sim/fluids/FluidSolver2D.java +762 -0
- data/src/toxi/sim/fluids/FluidSolver3D.java +326 -0
- data/src/toxi/sim/grayscott/GrayScott.java +469 -0
- data/src/toxi/util/DateUtils.java +141 -0
- data/src/toxi/util/FileSequenceDescriptor.java +181 -0
- data/src/toxi/util/FileUtils.java +467 -0
- data/src/toxi/util/datatypes/ArraySet.java +128 -0
- data/src/toxi/util/datatypes/ArrayUtil.java +404 -0
- data/src/toxi/util/datatypes/BiasedDoubleRange.java +141 -0
- data/src/toxi/util/datatypes/BiasedFloatRange.java +141 -0
- data/src/toxi/util/datatypes/BiasedIntegerRange.java +141 -0
- data/src/toxi/util/datatypes/DoubleRange.java +251 -0
- data/src/toxi/util/datatypes/FloatRange.java +251 -0
- data/src/toxi/util/datatypes/GenericSet.java +215 -0
- data/src/toxi/util/datatypes/IntegerRange.java +247 -0
- data/src/toxi/util/datatypes/IntegerSet.java +149 -0
- data/src/toxi/util/datatypes/ItemIndex.java +72 -0
- data/src/toxi/util/datatypes/SingletonRegistry.java +91 -0
- data/src/toxi/util/datatypes/TypedProperties.java +291 -0
- data/src/toxi/util/datatypes/UndirectedGraph.java +134 -0
- data/src/toxi/util/datatypes/UniqueItemIndex.java +223 -0
- data/src/toxi/util/datatypes/WeightedRandomEntry.java +76 -0
- data/src/toxi/util/datatypes/WeightedRandomSet.java +125 -0
- data/src/toxi/util/events/EventDispatcher.java +86 -0
- data/src/toxi/volume/AdditiveBrush.java +19 -0
- data/src/toxi/volume/ArrayIsoSurface.java +297 -0
- data/src/toxi/volume/BoxBrush.java +100 -0
- data/src/toxi/volume/BrushMode.java +16 -0
- data/src/toxi/volume/HashIsoSurface.java +354 -0
- data/src/toxi/volume/IsoSurface.java +59 -0
- data/src/toxi/volume/MarchingCubesIndex.java +312 -0
- data/src/toxi/volume/MeshLatticeBuilder.java +358 -0
- data/src/toxi/volume/MeshVoxelizer.java +216 -0
- data/src/toxi/volume/MultiplyBrush.java +20 -0
- data/src/toxi/volume/PeakBrush.java +21 -0
- data/src/toxi/volume/ReplaceBrush.java +19 -0
- data/src/toxi/volume/RoundBrush.java +113 -0
- data/src/toxi/volume/VolumetricBrush.java +160 -0
- data/src/toxi/volume/VolumetricHashMap.java +179 -0
- data/src/toxi/volume/VolumetricSpace.java +195 -0
- data/src/toxi/volume/VolumetricSpaceArray.java +214 -0
- data/toxiclibs.gemspec +28 -0
- metadata +442 -31
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
3
|
+
*
|
|
4
|
+
* This library is free software; you can redistribute it and/or
|
|
5
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
6
|
+
* License as published by the Free Software Foundation; either
|
|
7
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
10
|
+
*
|
|
11
|
+
* This library is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14
|
+
* Lesser General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
17
|
+
* License along with this library; if not, write to the Free Software
|
|
18
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
19
|
+
* Modified and updated by Martin Prout December 2015
|
|
20
|
+
*/
|
|
21
|
+
package toxi.audio;
|
|
22
|
+
|
|
23
|
+
import java.io.IOException;
|
|
24
|
+
import java.io.InputStream;
|
|
25
|
+
import java.nio.IntBuffer;
|
|
26
|
+
import java.util.ArrayList;
|
|
27
|
+
import java.util.logging.Logger;
|
|
28
|
+
|
|
29
|
+
import javax.sound.sampled.UnsupportedAudioFileException;
|
|
30
|
+
|
|
31
|
+
import com.jogamp.openal.AL;
|
|
32
|
+
import com.jogamp.openal.ALC;
|
|
33
|
+
import com.jogamp.openal.ALCcontext;
|
|
34
|
+
import com.jogamp.openal.ALCdevice;
|
|
35
|
+
import com.jogamp.openal.ALException;
|
|
36
|
+
import com.jogamp.openal.ALFactory;
|
|
37
|
+
import com.jogamp.openal.eax.EAX;
|
|
38
|
+
import com.jogamp.openal.eax.EAXConstants;
|
|
39
|
+
import com.jogamp.openal.eax.EAXFactory;
|
|
40
|
+
import com.jogamp.openal.util.WAVData;
|
|
41
|
+
import com.jogamp.openal.util.WAVLoader;
|
|
42
|
+
import java.util.logging.Level;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* <a href="https://joal.dev.java.net/">JOAL</a> convenience wrapper. Full
|
|
46
|
+
* documentation forthcoming. Please see the attached Processing demo & source
|
|
47
|
+
* distribution of this package for basic usage.
|
|
48
|
+
*/
|
|
49
|
+
public class JOALUtil {
|
|
50
|
+
|
|
51
|
+
public static String HARDWARE = "Generic Hardware";
|
|
52
|
+
public static String SOFTWARE = "Generic Software";
|
|
53
|
+
|
|
54
|
+
public static final Logger logger = Logger.getLogger(JOALUtil.class
|
|
55
|
+
.getName());
|
|
56
|
+
|
|
57
|
+
protected static JOALUtil instance;
|
|
58
|
+
|
|
59
|
+
public static JOALUtil getInstance() {
|
|
60
|
+
synchronized (JOALUtil.class) {
|
|
61
|
+
if (instance == null) {
|
|
62
|
+
instance = new JOALUtil();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return instance;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
protected ArrayList<AudioBuffer> buffers;
|
|
69
|
+
protected ArrayList<AudioSource> sources;
|
|
70
|
+
|
|
71
|
+
protected SoundListener listener;
|
|
72
|
+
protected AL al;
|
|
73
|
+
protected ALC alc;
|
|
74
|
+
protected ALCcontext context;
|
|
75
|
+
protected ALCdevice device;
|
|
76
|
+
|
|
77
|
+
protected EAX eax;
|
|
78
|
+
protected boolean isInited;
|
|
79
|
+
|
|
80
|
+
protected boolean isEAX;
|
|
81
|
+
|
|
82
|
+
protected JOALUtil() {
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Deletes & releases all sources and buffers created via this class.
|
|
87
|
+
*/
|
|
88
|
+
public void deleteAll() {
|
|
89
|
+
logger.info("deleting all sources & buffers...");
|
|
90
|
+
while (sources.size() > 0) {
|
|
91
|
+
deleteSource(sources.get(0), true);
|
|
92
|
+
}
|
|
93
|
+
sources.clear();
|
|
94
|
+
buffers.clear();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public boolean deleteBuffer(AudioBuffer b) {
|
|
98
|
+
if (b != null) {
|
|
99
|
+
sources.stream().filter((s) -> (s.getBuffer() == b)).map((s) -> {
|
|
100
|
+
s.stop();
|
|
101
|
+
return s;
|
|
102
|
+
}).forEach((s) -> {
|
|
103
|
+
logger.log(Level.FINE, "forced stopping source: {0}", s);
|
|
104
|
+
});
|
|
105
|
+
boolean result = b.delete();
|
|
106
|
+
if (buffers.remove(b)) {
|
|
107
|
+
logger.log(Level.INFO, "deleted buffer: {0}", b);
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
} else {
|
|
111
|
+
logger.warning("attempted to delete null buffer");
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public boolean deleteSource(AudioSource src) {
|
|
117
|
+
return deleteSource(src, false);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
public boolean deleteSource(AudioSource src, boolean killBuffer) {
|
|
121
|
+
AudioBuffer buffer = src.getBuffer();
|
|
122
|
+
boolean result = src.delete();
|
|
123
|
+
if (sources.remove(src)) {
|
|
124
|
+
logger.log(Level.INFO, "deleted source: {0}", src);
|
|
125
|
+
} else {
|
|
126
|
+
logger.log(Level.WARNING, "deleted unmanaged source: {0}", src);
|
|
127
|
+
}
|
|
128
|
+
if (killBuffer && buffer != null) {
|
|
129
|
+
result = result && deleteBuffer(buffer);
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Creates the specified number of audio sample buffers and returns an array
|
|
136
|
+
* of {@link AudioBuffer} wrappers.
|
|
137
|
+
*
|
|
138
|
+
* @param numBuffers
|
|
139
|
+
* number of requested buffers
|
|
140
|
+
* @return array
|
|
141
|
+
*/
|
|
142
|
+
public AudioBuffer[] generateBuffers(int numBuffers) {
|
|
143
|
+
if (!isInited) {
|
|
144
|
+
init();
|
|
145
|
+
}
|
|
146
|
+
AudioBuffer[] result = new AudioBuffer[numBuffers];
|
|
147
|
+
int[] arr = new int[numBuffers];
|
|
148
|
+
al.alGenBuffers(numBuffers, arr, 0);
|
|
149
|
+
for (int i = 0; i < numBuffers; i++) {
|
|
150
|
+
result[i] = new AudioBuffer(al, arr[i]);
|
|
151
|
+
buffers.add(result[i]);
|
|
152
|
+
}
|
|
153
|
+
return result;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Convenience wrapper for {@link #generateSources(int)} to create a single
|
|
158
|
+
* {@link AudioSource}.
|
|
159
|
+
*
|
|
160
|
+
* @return audio source instance
|
|
161
|
+
*/
|
|
162
|
+
public AudioSource generateSource() {
|
|
163
|
+
return generateSources(1)[0];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Convenience wrapper bundling {@link #loadBuffer(String)} &
|
|
168
|
+
* {@link #generateSource()} in a single method call. Generates a new
|
|
169
|
+
* {@link AudioSource} and assigns the sample buffer created from the given
|
|
170
|
+
* WAV file.
|
|
171
|
+
*
|
|
172
|
+
* @param file
|
|
173
|
+
* absolute path to WAV file
|
|
174
|
+
* @return configured audio source instance
|
|
175
|
+
*/
|
|
176
|
+
public AudioSource generateSourceFromFile(String file) {
|
|
177
|
+
if (!isInited) {
|
|
178
|
+
init();
|
|
179
|
+
}
|
|
180
|
+
AudioSource source = null;
|
|
181
|
+
AudioBuffer buffer = loadBuffer(file);
|
|
182
|
+
if (buffer != null) {
|
|
183
|
+
source = generateSource();
|
|
184
|
+
source.setBuffer(buffer);
|
|
185
|
+
}
|
|
186
|
+
return source;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Creates the specified number of hardware audio sources required to
|
|
191
|
+
* actually play the sample data stored in {@link AudioBuffer}s.
|
|
192
|
+
*
|
|
193
|
+
* @param numSources
|
|
194
|
+
* number of sources required
|
|
195
|
+
* @return array
|
|
196
|
+
*/
|
|
197
|
+
public AudioSource[] generateSources(int numSources) {
|
|
198
|
+
if (!isInited) {
|
|
199
|
+
init();
|
|
200
|
+
}
|
|
201
|
+
AudioSource[] result = new AudioSource[numSources];
|
|
202
|
+
int[] arr = new int[numSources];
|
|
203
|
+
al.alGenSources(numSources, arr, 0);
|
|
204
|
+
for (int i = 0; i < numSources; i++) {
|
|
205
|
+
result[i] = new AudioSource(al, arr[i]);
|
|
206
|
+
sources.add(result[i]);
|
|
207
|
+
}
|
|
208
|
+
return result;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Returns a direct reference to the OpenAL API.
|
|
213
|
+
*
|
|
214
|
+
* @return JOAL context
|
|
215
|
+
*/
|
|
216
|
+
public AL getAL() {
|
|
217
|
+
if (!isInited) {
|
|
218
|
+
init();
|
|
219
|
+
}
|
|
220
|
+
return al;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Retrieves a list of available OpenAL compatible audio devices. This
|
|
225
|
+
* method can be called before a call to {@link #init()}.
|
|
226
|
+
*
|
|
227
|
+
* @return array of device names
|
|
228
|
+
*/
|
|
229
|
+
public String[] getDeviceList() {
|
|
230
|
+
if (alc == null) {
|
|
231
|
+
alc = ALFactory.getALC();
|
|
232
|
+
}
|
|
233
|
+
return alc.alcGetDeviceSpecifiers();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Returns the {@link SoundListener} instance for the associated OpenAL
|
|
238
|
+
* context.
|
|
239
|
+
*
|
|
240
|
+
* @return listener object
|
|
241
|
+
*/
|
|
242
|
+
public SoundListener getListener() {
|
|
243
|
+
if (!isInited) {
|
|
244
|
+
init();
|
|
245
|
+
}
|
|
246
|
+
if (listener == null) {
|
|
247
|
+
listener = new SoundListener(this);
|
|
248
|
+
}
|
|
249
|
+
return listener;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Initializes the OpenAL context. Safe to be called multiple times (only
|
|
254
|
+
* first time is executed).
|
|
255
|
+
*
|
|
256
|
+
* @return true, if successful
|
|
257
|
+
*/
|
|
258
|
+
public boolean init() {
|
|
259
|
+
return init(null, false);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Initializes the OpenAL context and if parameter is true, will attempt to
|
|
264
|
+
* also setup an EAX environment. The method does nothing if it had been
|
|
265
|
+
* called previously and not been {@link #shutdown()} meanwhile.
|
|
266
|
+
*
|
|
267
|
+
* @param deviceName
|
|
268
|
+
* @param attemptEAX
|
|
269
|
+
* @return true, if successful (does not care if EAX is supported & has
|
|
270
|
+
* succeeded).
|
|
271
|
+
*/
|
|
272
|
+
public boolean init(String deviceName, boolean attemptEAX) {
|
|
273
|
+
if (context != null) {
|
|
274
|
+
throw new ALException("OpenAL already initialized");
|
|
275
|
+
}
|
|
276
|
+
if (al == null) {
|
|
277
|
+
al = ALFactory.getAL();
|
|
278
|
+
}
|
|
279
|
+
if (alc == null) {
|
|
280
|
+
alc = ALFactory.getALC();
|
|
281
|
+
}
|
|
282
|
+
ALCdevice d = alc.alcOpenDevice(deviceName);
|
|
283
|
+
if (d == null) {
|
|
284
|
+
throw new ALException("Error opening default OpenAL device");
|
|
285
|
+
}
|
|
286
|
+
ALCcontext c = alc.alcCreateContext(d, null);
|
|
287
|
+
if (c == null) {
|
|
288
|
+
alc.alcCloseDevice(d);
|
|
289
|
+
throw new ALException("Error creating OpenAL context");
|
|
290
|
+
}
|
|
291
|
+
alc.alcMakeContextCurrent(c);
|
|
292
|
+
if (alc.alcGetError(d) != 0) {
|
|
293
|
+
alc.alcDestroyContext(c);
|
|
294
|
+
alc.alcCloseDevice(d);
|
|
295
|
+
throw new ALException("Error making OpenAL context current");
|
|
296
|
+
}
|
|
297
|
+
// Fully initialized; finish setup
|
|
298
|
+
device = d;
|
|
299
|
+
context = c;
|
|
300
|
+
isInited = (al.alGetError() == AL.AL_NO_ERROR);
|
|
301
|
+
buffers = new ArrayList<>();
|
|
302
|
+
sources = new ArrayList<>();
|
|
303
|
+
listener = new SoundListener(this);
|
|
304
|
+
isEAX = al.alIsExtensionPresent("EAX2.0");
|
|
305
|
+
if (isEAX && attemptEAX) {
|
|
306
|
+
initEAX();
|
|
307
|
+
}
|
|
308
|
+
return isInited;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
protected void initEAX() {
|
|
312
|
+
eax = EAXFactory.getEAX();
|
|
313
|
+
IntBuffer b = IntBuffer.allocate(1);
|
|
314
|
+
b.put(EAXConstants.EAX_ENVIRONMENT_HANGAR);
|
|
315
|
+
eax.setListenerProperty(
|
|
316
|
+
EAXConstants.DSPROPERTY_EAXLISTENER_ENVIRONMENT, b);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Checks if EAX are supported by the underlying hardware.
|
|
321
|
+
*
|
|
322
|
+
* @return true, if supported.
|
|
323
|
+
*/
|
|
324
|
+
public boolean isEAXSupported() {
|
|
325
|
+
return isEAX;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Loads a WAV file from the given {@link InputStream}.
|
|
330
|
+
*
|
|
331
|
+
* @param is
|
|
332
|
+
* input stream
|
|
333
|
+
* @return buffer wrapper instance
|
|
334
|
+
* @throws UnsupportedAudioFileException
|
|
335
|
+
* @throws IOException
|
|
336
|
+
*/
|
|
337
|
+
public AudioBuffer loadBuffer(InputStream is)
|
|
338
|
+
throws UnsupportedAudioFileException, IOException {
|
|
339
|
+
AudioBuffer result;
|
|
340
|
+
AudioBuffer[] tmp = generateBuffers(1);
|
|
341
|
+
result = tmp[0];
|
|
342
|
+
WAVData wd = WAVLoader.loadFromStream(is);
|
|
343
|
+
result.configure(wd.data, wd.format, wd.freq);
|
|
344
|
+
return result;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Loads a WAV file (mono/stereo) from the specified file name
|
|
349
|
+
*
|
|
350
|
+
* @param fileName
|
|
351
|
+
* audio file name
|
|
352
|
+
* @return buffer wrapper instance
|
|
353
|
+
*/
|
|
354
|
+
public AudioBuffer loadBuffer(String fileName) {
|
|
355
|
+
AudioBuffer result = null;
|
|
356
|
+
try {
|
|
357
|
+
WAVData wd = WAVLoader.loadFromFile(fileName);
|
|
358
|
+
AudioBuffer[] tmp = generateBuffers(1);
|
|
359
|
+
result = tmp[0];
|
|
360
|
+
result.configure(wd.data, wd.format, wd.freq);
|
|
361
|
+
} catch (IOException e) {
|
|
362
|
+
logger.severe(e.getMessage());
|
|
363
|
+
}
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Destroys all objects, sources, buffers, contexts created by this class.
|
|
369
|
+
*/
|
|
370
|
+
public void shutdown() {
|
|
371
|
+
if (isInited) {
|
|
372
|
+
logger.info("shutting down JOAL");
|
|
373
|
+
deleteAll();
|
|
374
|
+
alc.alcMakeContextCurrent(null);
|
|
375
|
+
alc.alcDestroyContext(context);
|
|
376
|
+
alc.alcCloseDevice(device);
|
|
377
|
+
|
|
378
|
+
context = null;
|
|
379
|
+
device = null;
|
|
380
|
+
alc = null;
|
|
381
|
+
al = null;
|
|
382
|
+
buffers = null;
|
|
383
|
+
sources = null;
|
|
384
|
+
|
|
385
|
+
isInited = false;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* __ .__ .__ ._____.
|
|
3
|
+
* _/ |_ _______ __|__| ____ | | |__\_ |__ ______
|
|
4
|
+
* \ __\/ _ \ \/ / |/ ___\| | | || __ \ / ___/
|
|
5
|
+
* | | ( <_> > <| \ \___| |_| || \_\ \\___ \
|
|
6
|
+
* |__| \____/__/\_ \__|\___ >____/__||___ /____ >
|
|
7
|
+
* \/ \/ \/ \/
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) 2006-2011 Karsten Schmidt
|
|
10
|
+
*
|
|
11
|
+
* This library is free software; you can redistribute it and/or
|
|
12
|
+
* modify it under the terms of the GNU Lesser General Public
|
|
13
|
+
* License as published by the Free Software Foundation; either
|
|
14
|
+
* version 2.1 of the License, or (at your option) any later version.
|
|
15
|
+
*
|
|
16
|
+
* http://creativecommons.org/licenses/LGPL/2.1/
|
|
17
|
+
*
|
|
18
|
+
* This library is distributed in the hope that it will be useful,
|
|
19
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
20
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
21
|
+
* Lesser General Public License for more details.
|
|
22
|
+
*
|
|
23
|
+
* You should have received a copy of the GNU Lesser General Public
|
|
24
|
+
* License along with this library; if not, write to the Free Software
|
|
25
|
+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
26
|
+
* Modified and updated by Martin Prout December 2015
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
package toxi.audio;
|
|
30
|
+
|
|
31
|
+
import java.util.logging.Level;
|
|
32
|
+
import java.util.logging.Logger;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Implements a manager to play a number of shared samples in a multitimbral
|
|
36
|
+
* manner without interrupting/restarting the playback of currently playing
|
|
37
|
+
* sources. This is different to the default JOAL way of accessing sources
|
|
38
|
+
* directly. The manager is keeping track of active sources and will attempt to
|
|
39
|
+
* assign free ones for newly requested playbacks. If all voices are active, the
|
|
40
|
+
* oldest one will be stopped and used as the newly requested voice.
|
|
41
|
+
*/
|
|
42
|
+
public class MultiTimbralManager {
|
|
43
|
+
|
|
44
|
+
static class SourceState {
|
|
45
|
+
|
|
46
|
+
AudioSource src;
|
|
47
|
+
boolean isActive;
|
|
48
|
+
long startTime;
|
|
49
|
+
|
|
50
|
+
SourceState(AudioSource src) {
|
|
51
|
+
this.src = src;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
void activate() {
|
|
55
|
+
isActive = true;
|
|
56
|
+
startTime = System.currentTimeMillis();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
boolean updateStatus() {
|
|
60
|
+
isActive = isActive
|
|
61
|
+
&& (src.isLooping() || src.getBuffersProcessed() == 0);
|
|
62
|
+
return isActive;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private static final Logger logger = Logger
|
|
67
|
+
.getLogger(MultiTimbralManager.class.getName());
|
|
68
|
+
protected SourceState[] pool;
|
|
69
|
+
protected int maxSources;
|
|
70
|
+
|
|
71
|
+
protected int currIndex;
|
|
72
|
+
|
|
73
|
+
public MultiTimbralManager(JOALUtil liboal, int num) {
|
|
74
|
+
logger.log(Level.INFO, "attempting to allocate {0} audio voices", num);
|
|
75
|
+
AudioSource[] tmp = liboal.generateSources(num);
|
|
76
|
+
maxSources = tmp.length;
|
|
77
|
+
pool = new SourceState[maxSources];
|
|
78
|
+
for (int i = 0; i < maxSources; i++) {
|
|
79
|
+
AudioSource src = tmp[i];
|
|
80
|
+
src.setReferenceDistance(100);
|
|
81
|
+
src.setGain(1);
|
|
82
|
+
pool[i] = new SourceState(src);
|
|
83
|
+
}
|
|
84
|
+
logger.info("done. all sources created.");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Uses the class' logger to print out status information about the current
|
|
89
|
+
* usage of the managed audio sources.
|
|
90
|
+
*/
|
|
91
|
+
public void debug() {
|
|
92
|
+
String sources = "";
|
|
93
|
+
int numActive = 0;
|
|
94
|
+
for (int i = 0; i < maxSources; i++) {
|
|
95
|
+
if (pool[i].isActive) {
|
|
96
|
+
sources += i + ",";
|
|
97
|
+
numActive++;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
String info = "active sources: " + numActive;
|
|
101
|
+
logger.info(info);
|
|
102
|
+
logger.info(sources);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Attempts to find an available, currently unused {@link AudioSource}
|
|
107
|
+
* instance which can then be configured and played by the client
|
|
108
|
+
* application. If no free source is available the oldest playing one will
|
|
109
|
+
* be stopped and returned as free.
|
|
110
|
+
*
|
|
111
|
+
* @return a free AudioSource instance
|
|
112
|
+
*/
|
|
113
|
+
public AudioSource getNextVoice() {
|
|
114
|
+
boolean hasFreeSource = false;
|
|
115
|
+
int numIterations = 0;
|
|
116
|
+
int origID = currIndex;
|
|
117
|
+
int id;
|
|
118
|
+
// find first free slot...
|
|
119
|
+
do {
|
|
120
|
+
id = currIndex;
|
|
121
|
+
currIndex = (currIndex + 1) % maxSources;
|
|
122
|
+
if (pool[id].isActive) {
|
|
123
|
+
if (!pool[id].updateStatus()) {
|
|
124
|
+
hasFreeSource = true;
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
hasFreeSource = true;
|
|
128
|
+
}
|
|
129
|
+
numIterations++;
|
|
130
|
+
} while (!hasFreeSource && numIterations < maxSources);
|
|
131
|
+
// use oldest slot if no free one is available
|
|
132
|
+
if (!hasFreeSource) {
|
|
133
|
+
long now = System.currentTimeMillis();
|
|
134
|
+
id = origID;
|
|
135
|
+
for (int i = 0; i < maxSources; i++) {
|
|
136
|
+
if (pool[i].startTime < now) {
|
|
137
|
+
id = i;
|
|
138
|
+
now = pool[i].startTime;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
pool[id].src.stop();
|
|
142
|
+
logger.log(Level.WARNING, "no free src, using oldest slot #{0}", id);
|
|
143
|
+
currIndex = (id + 1) % maxSources;
|
|
144
|
+
}
|
|
145
|
+
pool[id].activate();
|
|
146
|
+
return pool[id].src;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Produces an array of status flags of used voices. Elements set to true
|
|
151
|
+
* indicate the voice is currently active/playing.
|
|
152
|
+
*
|
|
153
|
+
* @return boolean array
|
|
154
|
+
*/
|
|
155
|
+
public boolean[] getUsage() {
|
|
156
|
+
boolean[] usage = new boolean[maxSources];
|
|
157
|
+
for (int i = 0; i < maxSources; i++) {
|
|
158
|
+
usage[i] = pool[i].isActive;
|
|
159
|
+
}
|
|
160
|
+
return usage;
|
|
161
|
+
}
|
|
162
|
+
}
|