private static float[][] generateSmoothNoise( float[][] baseNoise, int octave )
	{
		int width = baseNoise.length;
		int height = baseNoise[0].length;

		float[][] smoothNoise = new float[width][height];

		int samplePeriod = 1 << octave; // calculates 2 ^ k
		float sampleFrequency = 1.0f / samplePeriod;

		for ( int i = 0; i < width; i++ )
		{
			//calculate the horizontal sampling indices
			int sample_i0 = ( i / samplePeriod ) * samplePeriod;
			int sample_i1 = ( sample_i0 + samplePeriod ) % width; //wrap around
			float horizontal_blend = ( i - sample_i0 ) * sampleFrequency;

			for ( int j = 0; j < height; j++ )
			{
				//calculate the vertical sampling indices
				int sample_j0 = ( j / samplePeriod ) * samplePeriod;
				int sample_j1 = ( sample_j0 + samplePeriod ) % height; //wrap around
				float vertical_blend = ( j - sample_j0 ) * sampleFrequency;

				//blend the top two corners
				float top = interpolate( baseNoise[sample_i0][sample_j0], baseNoise[sample_i1][sample_j0], horizontal_blend );

				//blend the bottom two corners
				float bottom = interpolate( baseNoise[sample_i0][sample_j1], baseNoise[sample_i1][sample_j1], horizontal_blend );

				//final blend
				smoothNoise[i][j] = interpolate( top, bottom, vertical_blend );
			}
		}

		return smoothNoise;
	}