예제 #1
0
void shade(const Scene * scene, const int level, const C_FLT weight,
           const Ray &ray, Intercept * intercepts, Color * color) {
  Material * entryMat = intercepts[0].material,
           * hitMat = intercepts[0].enter?
                      intercepts[0].primitive->material: ray.medium;

  C_FLT specWeight = hitMat->specular.magnitude() * weight,
        transWeight = hitMat->transmission.magnitude() * weight;

  Vector3D specDir, transDir, normal;
  std::vector<P_FLT> mapping;

  Point3D interceptPoint = ray.rayPoint(intercepts[0].t);

  intercepts[0].primitive->getIntersect(interceptPoint, &normal, &mapping);
  if (dotProduct(ray.dir, normal) > 0.0f) {
    normal.negate();
  }
  specularDirection(ray.dir, normal, &specDir);
  bool transmission = transmissionDirection(entryMat, hitMat, ray.dir, normal,
                                            &transDir);

  *color += scene->ambience * hitMat->ambience;

  for (std::vector<Light *>::const_iterator itr = scene->lights.begin();
       itr != scene->lights.end(); itr++) {
    Vector3D pointToLight = (*itr)->orig - interceptPoint;
    P_FLT distanceToLight = pointToLight.normalize();
    Ray rayToLight(interceptPoint, pointToLight, NULL);

    P_FLT lightDotNormal = dotProduct(pointToLight, normal);
    if (fGreaterZero(lightDotNormal) &&
        fGreaterZero(shadow(scene, rayToLight, distanceToLight))) {
      // Light source diffuse reflection
      *color += (*itr)->color * hitMat->diffuse * lightDotNormal;

      // Light source specular reflection
      Vector3D h = pointToLight - ray.dir;
      h.normalize();
      P_FLT specDot = dotProduct(normal, h);
      if (specDot > 0.0f) {
        *color += (*itr)->color * hitMat->specular *
                  pow(specDot, hitMat->shine);
      }
    } else if (transmission && fLessZero(lightDotNormal) &&
               fLessZero(shadow(scene, rayToLight, distanceToLight))) {
      // Light source specular transmission
      C_FLT refrRatio = hitMat->refraction / entryMat->refraction;
      if (!fEqual(refrRatio, 1.0f)) {
        Vector3D h_j = (-ray.dir - pointToLight * refrRatio) /
                       (refrRatio - 1);
        h_j.normalize();

        // TODO(kent): Define transmission highlight coefficient
        *color += (*itr)->color * hitMat->transmission *
                  pow(dotProduct(-normal, h_j), hitMat->shine);
      }
    }
  }

  if (level < MAX_LEVEL) {
    // Other body specular reflection
    if (specWeight > MIN_WEIGHT) {
      Ray specRay(interceptPoint, specDir, entryMat);
      Color specColor;

      trace(scene, level + 1, specWeight, specRay, &specColor);
      *color += specColor * hitMat->specular;
    }

    // Other body specular transmission
    if (transWeight > MIN_WEIGHT) {
      if (transmission) {
        Ray transRay(interceptPoint, transDir, hitMat);
        Color transColor;

        trace(scene, level + 1, transWeight, transRay, &transColor);
        *color += transColor * hitMat->transmission;
      } else {
        // TODO(kent): Handle total internal reflection
      }
    }
  }

  if (intercepts[0].enter && intercepts[0].primitive->texture != NULL) {
    *color *= intercepts[0].primitive->getTexColor(mapping);
  }
}
예제 #2
0
bool XSFPlayer::FillBuffer(std::vector<uint8_t> &buf, unsigned &samplesWritten)
{
	bool endFlag = false;
	unsigned detectSilence = xSFConfig->GetDetectSilenceSec();
	unsigned pos = 0, bufsize = buf.size() >> 2;
	auto trueBuffer = std::vector<uint8_t>(bufsize << (this->uses32BitSamplesClampedTo16Bit ? 3 : 2));
	auto longBuffer = std::vector<uint8_t>(bufsize << 3);
	auto bufLong = reinterpret_cast<int32_t *>(&longBuffer[0]);
	while (pos < bufsize)
	{
		unsigned remain = bufsize - pos, offset = pos;
		this->GenerateSamples(trueBuffer, pos << (this->uses32BitSamplesClampedTo16Bit ? 2 : 1), remain);
		if (this->uses32BitSamplesClampedTo16Bit)
		{
			auto trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
			std::copy_n(&trueBufLong[0], bufsize << 1, &bufLong[0]);
		}
		else
		{
			auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
			std::copy_n(&trueBufShort[0], bufsize << 1, &bufLong[0]);
		}
		if (detectSilence || skipSilenceOnStartSec)
		{
			unsigned skipOffset = 0;
			for (unsigned ofs = 0; ofs < remain; ++ofs)
			{
				uint32_t sampleL = bufLong[2 * (offset + ofs)], sampleR = bufLong[2 * (offset + ofs) + 1];
				bool silence = (sampleL + CHECK_SILENCE_BIAS + CHECK_SILENCE_LEVEL) - this->prevSampleL <= CHECK_SILENCE_LEVEL * 2 &&
					(sampleR + CHECK_SILENCE_BIAS + CHECK_SILENCE_LEVEL) - this->prevSampleR <= CHECK_SILENCE_LEVEL * 2;

				if (silence)
				{
					if (++this->detectedSilenceSample >= this->sampleRate)
					{
						this->detectedSilenceSample -= this->sampleRate;
						++this->detectedSilenceSec;
						if (this->skipSilenceOnStartSec && this->detectedSilenceSec >= this->skipSilenceOnStartSec)
						{
							this->skipSilenceOnStartSec = this->detectedSilenceSec = 0;
							if (ofs)
								skipOffset = ofs;
						}
					}
				}
				else
				{
					this->detectedSilenceSample = this->detectedSilenceSec = 0;
					if (this->skipSilenceOnStartSec)
					{
						this->skipSilenceOnStartSec = 0;
						if (ofs)
							skipOffset = ofs;
					}
				}

				prevSampleL = sampleL + CHECK_SILENCE_BIAS;
				prevSampleR = sampleR + CHECK_SILENCE_BIAS;
			}

			if (!this->skipSilenceOnStartSec)
			{
				if (skipOffset)
				{
					auto tmpBuf = std::vector<int32_t>((bufsize - skipOffset) << 1);
					std::copy(&bufLong[(offset + skipOffset) << 1], &bufLong[bufsize << 1], &tmpBuf[0]);
					std::copy_n(&tmpBuf[0], (bufsize - skipOffset) << 1, &bufLong[offset << 1]);
					pos += skipOffset;
				}
				else
					pos += remain;
			}
		}
		else
			pos += remain;
		if (pos < bufsize)
		{
			if (this->uses32BitSamplesClampedTo16Bit)
			{
				auto trueBufLong = reinterpret_cast<int32_t *>(&trueBuffer[0]);
				std::copy_n(&bufLong[0], bufsize << 1, &trueBufLong[0]);
			}
			else
			{
				auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
				std::copy_n(&bufLong[0], bufsize << 1, &trueBufShort[0]);
			}
		}
	}

	/* Detect end of song */
	if (!xSFConfig->GetPlayInfinitely())
	{
		if (this->currentSample >= this->lengthSample + this->fadeSample)
		{
			samplesWritten = 0;
			return true;
		}
		if (this->currentSample + bufsize >= this->lengthSample + this->fadeSample)
		{
			bufsize = this->lengthSample + this->fadeSample - this->currentSample;
			endFlag = true;
		}
	}

	/* Volume */
	if (!this->ignoreVolume && (!fEqual(this->volume, 1.0) || !fEqual(xSFConfig->GetVolume(), 1.0)))
	{
		double scale = this->volume * xSFConfig->GetVolume();
		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
		{
			double s1 = bufLong[2 * ofs] * scale, s2 = bufLong[2 * ofs + 1] * scale;
			if (!this->uses32BitSamplesClampedTo16Bit)
			{
				clamp(s1, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
				clamp(s2, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
			}
			bufLong[2 * ofs] = static_cast<int32_t>(s1);
			bufLong[2 * ofs + 1] = static_cast<int32_t>(s2);
		}
	}

	if (this->uses32BitSamplesClampedTo16Bit)
	{
		auto bufShort = reinterpret_cast<int16_t *>(&buf[0]);
		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
		{
			int32_t s1 = bufLong[2 * ofs], s2 = bufLong[2 * ofs + 1];
			clamp(s1, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
			clamp(s2, std::numeric_limits<int16_t>::min(), std::numeric_limits<int16_t>::max());
			bufShort[2 * ofs] = static_cast<int16_t>(s1);
			bufShort[2 * ofs + 1] = static_cast<int16_t>(s2);
		}
	}
	else
	{
		auto trueBufShort = reinterpret_cast<int16_t *>(&trueBuffer[0]);
		std::copy_n(&bufLong[0], bufsize << 1, &trueBufShort[0]);
		std::copy(&trueBuffer[0], &trueBuffer[bufsize << 2], &buf[0]);
	}

	/* Fading */
	if (!xSFConfig->GetPlayInfinitely() && this->fadeSample && this->currentSample + bufsize >= this->lengthSample)
	{
		auto bufShort = reinterpret_cast<int16_t *>(&buf[0]);
		for (unsigned ofs = 0; ofs < bufsize; ++ofs)
		{
			if (this->currentSample + ofs >= this->lengthSample && this->currentSample + ofs < this->lengthSample + this->fadeSample)
			{
				int scale = static_cast<uint64_t>(this->lengthSample + this->fadeSample - (this->currentSample + ofs)) * 0x10000 / this->fadeSample;
				bufShort[2 * ofs] = (bufShort[2 * ofs] * scale) >> 16;
				bufShort[2 * ofs + 1] = (bufShort[2 * ofs + 1] * scale) >> 16;
			}
			else if (this->currentSample + ofs >= this->lengthSample + this->fadeSample)
예제 #3
0
파일: resampler.c 프로젝트: codefoco/dumb
static float sinc(float x) {
    return fEqual(x, 0.0) ? 1.0 : sin(x * M_PI) / (x * M_PI);
}