void AudioVisualizerApp::setup()
{
	// initialize signals
	signalChannelEnd = false;

	// make a list of valid audio file extensions and initialize audio variables
	const char* extensions[] = { "mp3", "wav", "ogg" };
	mAudioExtensions = vector<string>( extensions, extensions + 2 );
	mAudioPath = getAssetPath( "" );
	mIsAudioPlaying = false;

	// setup camera
	mCamera.setPerspective( 50.0f, 1.0f, 1.0f, 10000.0f );
	mCamera.lookAt( vec3( -kWidth / 4, kHeight / 2, -kWidth / 8 ), vec3( kWidth / 4, -kHeight / 8, kWidth / 4 ) );

	mCameraUi.setCamera( &mCamera );

	// create channels from which we can construct our textures
	mChannelLeft = Channel32f( kBands, kHistory );
	mChannelRight = Channel32f( kBands, kHistory );
	memset( mChannelLeft.getData(), 0, mChannelLeft.getRowBytes() * kHistory );
	memset( mChannelRight.getData(), 0, mChannelRight.getRowBytes() * kHistory );

	// create texture format (wrap the y-axis, clamp the x-axis)
	mTextureFormat.setWrapS( GL_CLAMP_TO_BORDER );
	mTextureFormat.setWrapT( GL_REPEAT );
	mTextureFormat.setMinFilter( GL_LINEAR );
	mTextureFormat.setMagFilter( GL_LINEAR );
	mTextureFormat.loadTopDown( true );

	// compile shader
	try {
		mShader = gl::GlslProg::create( loadAsset( "shaders/spectrum.vert" ), loadAsset( "shaders/spectrum.frag" ) );
	}
	catch( const std::exception& e ) {
		console() << e.what() << std::endl;
		quit();
		return;
	}

	// create static mesh (all animation is done in the vertex shader)
	std::vector<vec3>		positions;
	std::vector<Colorf>		colors;
	std::vector<vec2>		coords;
	std::vector<uint32_t>	indices;

	for( size_t h = 0; h < kHeight; ++h ) {
		for( size_t w = 0; w < kWidth; ++w ) {
			// add polygon indices
			if( h < kHeight - 1 && w < kWidth - 1 ) {
				size_t offset = positions.size();

				indices.emplace_back( offset );
				indices.emplace_back( offset + kWidth );
				indices.emplace_back( offset + kWidth + 1 );
				indices.emplace_back( offset );
				indices.emplace_back( offset + kWidth + 1 );
				indices.emplace_back( offset + 1 );
			}

			// add vertex
			positions.emplace_back( vec3( float( w ), 0, float( h ) ) );

			// add texture coordinates
			// note: we only want to draw the lower part of the frequency bands,
			//  so we scale the coordinates a bit
			const float part = 0.5f;
			float s = w / float( kWidth - 1 );
			float t = h / float( kHeight - 1 );
			coords.emplace_back( vec2( part - part * s, t ) );

			// add vertex colors
			colors.emplace_back( Color( CM_HSV, s, 0.5f, 0.75f ) );
		}
	}

	gl::VboMesh::Layout layout;
	layout.usage( GL_STATIC_DRAW );
	layout.attrib( geom::Attrib::POSITION, 3 );
	layout.attrib( geom::Attrib::COLOR, 3 );
	layout.attrib( geom::Attrib::TEX_COORD_0, 2 );

	mMesh = gl::VboMesh::create( positions.size(), GL_TRIANGLES, { layout }, indices.size(), GL_UNSIGNED_INT );
	mMesh->bufferAttrib( geom::POSITION, positions.size() * sizeof( vec3 ), positions.data() );
	mMesh->bufferAttrib( geom::COLOR, colors.size() * sizeof( vec3 ), colors.data() );
	mMesh->bufferAttrib( geom::TEX_COORD_0, coords.size() * sizeof( vec2 ), coords.data() );
	mMesh->bufferIndices( indices.size() * sizeof( uint32_t ), indices.data() );

	// play audio using the Cinder FMOD block
	FMOD::System_Create( &mFMODSystem );
	mFMODSystem->init( 32, FMOD_INIT_NORMAL | FMOD_INIT_ENABLE_PROFILE, NULL );
	mFMODSound = nullptr;
	mFMODChannel = nullptr;

	playAudio( findAudio( mAudioPath ) );

	mIsMouseDown = false;
	mMouseUpDelay = 30.0;
	mMouseUpTime = getElapsedSeconds() - mMouseUpDelay;

	// the texture offset has two purposes:
	//  1) it tells us where to upload the next spectrum data
	//  2) we use it to offset the texture coordinates in the shader for the scrolling effect
	mOffset = 0;
}
Exemple #2
0
void FiretrailApp::setup()
{
    mCamera.lookAt(vec3(.0f, .0f, -1.0f), vec3(.0f));
    
    mParams = params::InterfaceGl::create( getWindow(), "App parameters", toPixels( ivec2( 200, 300 ) ) );
    mParams->addParam("FPS", &mFps);
    mParams->addParam("Max D Slice",  &mMaxDSlice);
    mParams->addParam("Time Factor",  &mTimeFactor);
    mParams->addParam("Gain",         &mGain      ).updateFn( [this] { mGlsl->uniform("gain", mGain);} );
    mParams->addParam("Lacunarity",   &mLacunarity).updateFn( [this] { mGlsl->uniform("lacunarity", mLacunarity);} );
    mParams->addParam("Magnitude",    &mMagnitude ).updateFn( [this] { mGlsl->uniform("magnitude", mMagnitude);} );
    mParams->addParam("Frag Mul",     &mFragMul   ).updateFn( [this] { mGlsl->uniform("fragMul", mFragMul);} );
    mParams->addParam("Noise Scale",  &mNoiseScale).updateFn( [this] { mGlsl->uniform("noiseScale", mNoiseScale);} );
    mParams->addParam("Layer Offset", &mLayerOffset).updateFn( [this] { mGlsl->uniform("layerOffset", mLayerOffset);} );
    
    mParams->addButton("Start Recording", [this]
    {
        if (!mRecordingMovie) startMovieRecording();
    });
    
    mParams->addButton("End Recording", [this]
    {
        if (mRecordingMovie) endMovieRecording();
    });
    
    gl::Texture::Format mTexFormat;
    mTexFormat.magFilter( GL_LINEAR ).minFilter( GL_LINEAR ).internalFormat( GL_RGBA );//.wrap(GL_REPEAT);
    mFireTex = gl::Texture::create( loadImage( loadAsset( "flame6.png" ) ), mTexFormat );
    
    mTexFormat.wrap(GL_REPEAT);
    mNoiseTex = gl::Texture::create( loadImage( loadAsset( "nzw.png" ) ), mTexFormat );
    
    mGlsl = gl::GlslProg::create(gl::GlslProg::Format()
                                 .vertex( loadAsset( "fire.vert" ) )
                                 .fragment( loadAsset( "fire.frag" ) )
                                 .geometry( loadAsset( "fire.geom" )).attrib( geom::CUSTOM_0, "vSize" ) );

    mGlsl->uniform("fireTex", 0);
    mGlsl->uniform("noiseTex", 1);
    mGlsl->uniform("fragMul", mFragMul);
    mGlsl->uniform("gain", mGain);
    mGlsl->uniform("magnitude", mMagnitude);
    mGlsl->uniform("lacunarity", mLacunarity);
    mGlsl->uniform("noiseScale", mNoiseScale);
    mGlsl->uniform("layerOffset", mLayerOffset);

    // compute texture coordinates
    vector<float> amp( NUM_SPLINE_NODES );
    amp.resize(NUM_SPLINE_NODES);
    
    for (size_t i = 0; i < NUM_SPLINE_NODES; ++i)
    {
        const auto t = (float)i / (float)(NUM_SPLINE_NODES - 1);
        amp[i] = 1.0f - easeInOutSine(t);
    }
    
    mVboMesh = gl::VboMesh::create( NUM_SPLINE_NODES, GL_POINTS, {
        gl::VboMesh::Layout().usage( GL_DYNAMIC_DRAW ).attrib( geom::POSITION, 3 ),
        gl::VboMesh::Layout().usage( GL_STATIC_DRAW ).attrib( geom::Attrib::CUSTOM_0, 1 ),
    });
    
    mVboMesh->bufferAttrib(geom::Attrib::CUSTOM_0, amp);
    
    mBatch = gl::Batch::create(mVboMesh, mGlsl);
    
    resize();
}