예제 #1
0
INT imdct_copy_ov_and_nr(
        H_MDCT hMdct,
        FIXP_DBL * pTimeData,
        INT nrSamples
        )
{
  FIXP_DBL *pOvl;
  int nt, nf, i;

  nt = fMin(hMdct->ov_offset, nrSamples);
  nrSamples -= nt;
  nf = fMin(hMdct->prev_nr, nrSamples);
  nrSamples -= nf;
  FDKmemcpy(pTimeData, hMdct->overlap.time, nt*sizeof(FIXP_DBL));
  pTimeData += nt;

  pOvl = hMdct->overlap.freq + hMdct->ov_size - 1;
  for (i=0; i<nf; i++) {
    FIXP_DBL x = - (*pOvl--);
    *pTimeData = IMDCT_SCALE_DBL(x);
    pTimeData ++;
  }

  return (nt+nf);
}
예제 #2
0
  //
  // ClampToFringe
  //
  // Clamp the given cell location to the closest fringe cell
  //
  void ClampToFringe(const Point<S32> &min, const Point<S32> &max, Point<S32> &pos)
  {
    // Get fringe bounds
    Point<S32> fMin(min - 1);
    Point<S32> fMax(max + 1);

    // Clamp both values into the fringe area
    pos.x = Clamp<S32>(fMin.x, pos.x, fMax.x);
    pos.z = Clamp<S32>(fMin.z, pos.z, fMax.z);

    // For internal points, get the closest fringe for each axis
    S32 cx = (abs(fMin.x - pos.x) < abs(fMax.x - pos.x)) ? fMin.x : fMax.x;
    S32 cz = (abs(fMin.z - pos.z) < abs(fMax.z - pos.z)) ? fMin.z : fMax.z;

    // Jump to the closest fringe
    if (abs(cx - pos.x) < abs(cz - pos.z))
    {
      pos.x = cx;
    }
    else
    {
      pos.z = cz;
    }

    ASSERT(CellOnFringe(min, max, pos))
  }
예제 #3
0
  //
  // CellOnFringe
  //
  // Is the given map cell on the fringe of the given footprint
  //
  Bool CellOnFringe(const Point<S32> &min, const Point<S32> &max, const Point<S32> &pos)
  {
    // Get fringe bounds
    Point<S32> fMin(min - 1);
    Point<S32> fMax(max + 1);

    return 
    (
      (((pos.x == fMin.x) || (pos.x == fMax.x)) && ((pos.z >= fMin.z && pos.z <= fMax.z)))

      ||

      (((pos.z == fMin.z) || (pos.z == fMax.z)) && ((pos.x >= fMin.x && pos.x <= fMax.x)))
    );    
  }
예제 #4
0
/**
 * \brief Apply synthesis filter with zero input to x. The overall filter gain
 * is 1.0.
 * \param a LPC filter coefficients.
 * \param length length of the input/output data vector x.
 * \param x input/output vector, where the synthesis filter is applied in place.
 */
static void Syn_filt_zero(const FIXP_LPC a[], const INT a_exp, INT length,
                          FIXP_DBL x[]) {
  int i, j;
  FIXP_DBL L_tmp;

  for (i = 0; i < length; i++) {
    L_tmp = (FIXP_DBL)0;

    for (j = 0; j < fMin(i, M_LP_FILTER_ORDER); j++) {
      L_tmp -= fMultDiv2(a[j], x[i - (j + 1)]) >> (LP_FILTER_SCALE - 1);
    }

    L_tmp = scaleValue(L_tmp, a_exp + LP_FILTER_SCALE);
    x[i] = fAddSaturate(x[i], L_tmp);
  }
}
예제 #5
0
void pvcDecodeTimeSlot(PVC_STATIC_DATA *pPvcStaticData,
                       PVC_DYNAMIC_DATA *pPvcDynamicData,
                       FIXP_DBL **qmfSlotReal, FIXP_DBL **qmfSlotImag,
                       const int qmfExponent, const int pvcBorder0,
                       const int timeSlotNumber, FIXP_DBL predictedEsgSlot[],
                       int *predictedEsg_exp) {
  int i, band, ksg, ksg_start = 0;
  int RATE = pPvcDynamicData->RATE;
  int Esg_index = pPvcStaticData->Esg_slot_index;
  const SCHAR *sg_borders = pPvcDynamicData->sg_offset_low;
  FIXP_DBL *pEsg = pPvcStaticData->Esg[Esg_index];
  FIXP_DBL E[PVC_NBLOW] = {0};

  /* Subband grouping in QMF subbands below SBR range */
  /* Within one timeslot ( i = [0...(RATE-1)] QMF subsamples) calculate energy
     E(ib,t) and group them to Esg(ksg,t). Then transfer values to logarithmical
     domain and store them for time domain smoothing. (7.5.6.3 Subband grouping
     in QMF subbands below SBR range)
  */
  for (ksg = 0; sg_borders[ksg] < 0; ksg++) {
    pEsg[ksg] = FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */
    ksg_start++;
  }

  for (i = 0; i < RATE; i++) {
    FIXP_DBL *qmfR, *qmfI;
    qmfR = qmfSlotReal[i];
    qmfI = qmfSlotImag[i];
    for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
      for (band = sg_borders[ksg]; band < sg_borders[ksg + 1]; band++) {
        /* The division by 8 == (RATE*lbw) is required algorithmically */
        E[ksg] += (fPow2Div2(qmfR[band]) + fPow2Div2(qmfI[band])) >> 2;
      }
    }
  }
  for (ksg = ksg_start; ksg < PVC_NBLOW; ksg++) {
    if (E[ksg] > (FIXP_DBL)0) {
      /* 10/log2(10) = 0.752574989159953 * 2^2 */
      int exp_log;
      FIXP_DBL nrg = CalcLog2(E[ksg], 2 * qmfExponent, &exp_log);
      nrg = fMult(nrg, FL2FXCONST_SGL(LOG10FAC));
      nrg = scaleValue(nrg, exp_log - PVC_ESG_EXP + 2);
      pEsg[ksg] = fMax(nrg, FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)));
    } else {
      pEsg[ksg] =
          FL2FXCONST_DBL(-10.0 / (1 << PVC_ESG_EXP)); /* 10*log10(0.1) */
    }
  }

  /* Time domain smoothing of subband-grouped energy */
  {
    int idx = pPvcStaticData->Esg_slot_index;
    FIXP_DBL *pEsg_filt;
    FIXP_SGL SCcoeff;

    E[0] = E[1] = E[2] = (FIXP_DBL)0;
    for (i = 0; i < pPvcDynamicData->ns; i++) {
      SCcoeff = pPvcDynamicData->pSCcoeffs[i];
      pEsg_filt = pPvcStaticData->Esg[idx];
      /* Div2 is compensated by scaling of coeff table */
      E[0] = fMultAddDiv2(E[0], pEsg_filt[0], SCcoeff);
      E[1] = fMultAddDiv2(E[1], pEsg_filt[1], SCcoeff);
      E[2] = fMultAddDiv2(E[2], pEsg_filt[2], SCcoeff);
      if (i >= pPvcDynamicData->pastEsgSlotsAvail) {
        /* if past Esg values are not available use the ones from the last valid
         * slot */
        continue;
      }
      if (idx > 0) {
        idx--;
      } else {
        idx += PVC_NS_MAX - 1;
      }
    }
  }

  /* SBR envelope scalefactor prediction */
  {
    int E_high_exp[PVC_NBHIGH_MAX];
    int E_high_exp_max = 0;
    int pvcTab1ID;
    int pvcTab2ID = (int)pPvcDynamicData->pPvcID[timeSlotNumber];
    const UCHAR *pTab1, *pTab2;
    if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[0]) {
      pvcTab1ID = 0;
    } else if (pvcTab2ID < pPvcDynamicData->pPVCTab1_dp[1]) {
      pvcTab1ID = 1;
    } else {
      pvcTab1ID = 2;
    }
    pTab1 = &(pPvcDynamicData
                  ->pPVCTab1[pvcTab1ID * PVC_NBLOW * pPvcDynamicData->nbHigh]);
    pTab2 = &(pPvcDynamicData->pPVCTab2[pvcTab2ID * pPvcDynamicData->nbHigh]);
    for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
      FIXP_SGL predCoeff;
      FIXP_DBL accu;
      int predCoeff_exp, kb;
      E_high_exp[ksg] = 0;

      /* residual part */
      accu = ((LONG)(SCHAR)*pTab2++) << (DFRACT_BITS - 8 - PVC_ESG_EXP +
                                         pPvcDynamicData->pScalingCoef[3]);

      /* linear combination of lower grouped energies part */
      for (kb = 0; kb < PVC_NBLOW; kb++) {
        predCoeff = (FIXP_SGL)(
            (SHORT)(SCHAR)pTab1[kb * pPvcDynamicData->nbHigh + ksg] << 8);
        predCoeff_exp = pPvcDynamicData->pScalingCoef[kb] +
                        1; /* +1 to compensate for Div2 */
        accu += fMultDiv2(E[kb], predCoeff) << predCoeff_exp;
      }
      /* convert back to linear domain */
      accu = fMult(accu, FL2FXCONST_SGL(LOG10FAC_INV));
      accu = f2Pow(
          accu, PVC_ESG_EXP - 1,
          &predCoeff_exp); /* -1 compensates for exponent of LOG10FAC_INV */
      predictedEsgSlot[ksg] = accu;
      E_high_exp[ksg] = predCoeff_exp;
      if (predCoeff_exp > E_high_exp_max) {
        E_high_exp_max = predCoeff_exp;
      }
    }

    /* rescale output vector according to largest exponent */
    for (ksg = 0; ksg < pPvcDynamicData->nbHigh; ksg++) {
      int scale = E_high_exp[ksg] - E_high_exp_max;
      predictedEsgSlot[ksg] = scaleValue(predictedEsgSlot[ksg], scale);
    }
    *predictedEsg_exp = E_high_exp_max;
  }

  pPvcStaticData->Esg_slot_index =
      (pPvcStaticData->Esg_slot_index + 1) & (PVC_NS_MAX - 1);
  pPvcDynamicData->pastEsgSlotsAvail =
      fMin(pPvcDynamicData->pastEsgSlotsAvail + 1, PVC_NS_MAX - 1);
  return;
}
예제 #6
0
// Load a mesh using the assimp library, and calculate its mesh saliency
bool load_mesh (const char* file_name, GLuint* vao, int* point_count) {
	const aiScene* scene = aiImportFile (file_name, aiProcess_Triangulate);
	if (!scene) {
		fprintf (stderr, "ERROR: reading mesh %s\n", file_name);
		return false;
	}
   
	// Get first mesh in file only
	const aiMesh* mesh = scene->mMeshes[0];
	printf ("    %i vertices in mesh[0]\n", mesh->mNumVertices);
	printf ("    %i faces in mesh[0]\n", mesh->mNumFaces);
	
	// Pass back number of vertex points in mesh 
	*point_count = mesh->mNumVertices;
    vertexCnt = *point_count;
	
	// Generate a VAO, using the pass-by-reference parameter that we give to the function 
    glGenVertexArrays (1, vao);
	glBindVertexArray (*vao);
	
	points = NULL; // array of vertex points
    if (!mesh->HasPositions()) {
        fprintf(stderr, "ERROR: mesh %s don't have vertex data!\n", file_name);
        return false;
    }

    float xMin = oo, yMin = oo, zMin = oo;
    float xMax = -oo, yMax = -oo, zMax = -oo;
    // Get the mesh's vertecies
    points = (GLfloat*)malloc (vertexCnt * 3 * sizeof (GLfloat));
    for (int i = 0; i < vertexCnt; i++) {
        const aiVector3D* vp = &(mesh->mVertices[i]);
        points[i * 3] = (GLfloat)vp->x;
        points[i * 3 + 1] = (GLfloat)vp->y;
        points[i * 3 + 2] = (GLfloat)vp->z;
        xMin = fMin(xMin, vp->x), xMax = fMax(xMax, vp->x);
        yMin = fMin(yMin, vp->y), yMax = fMax(yMax, vp->y);
        zMin = fMin(zMin, vp->z), zMax = fMax(zMax, vp->z);
    }

    // Calculate the mesh's normal
    normals = (GLfloat*)malloc(vertexCnt * 3 * sizeof(GLfloat));
    for(int i = 0; i < mesh->mNumFaces; i++) {
        int idx[3];
        for(int k = 0; k < 3; k++)
            idx[k] = mesh->mFaces[i].mIndices[k];
        // get all vertecies' location
        const aiVector3D* v1 = &(mesh->mVertices[idx[0]]);
        const aiVector3D* v2 = &(mesh->mVertices[idx[1]]);
        const aiVector3D* v3 = &(mesh->mVertices[idx[2]]);
        // vectors
        vec3 faceVec1 = vec3(v2->x - v1->x, v2->y - v1->y, v2->z - v1->z);
        vec3 faceVec2 = vec3(v3->x - v2->x, v3->y - v2->y, v3->z - v2->z);
        vec3 crossProd = cross(faceVec1, faceVec2);
        for(int k = 0; k < 3; k++) {
            normals[idx[k]*3+0] += (GLfloat)crossProd.v[0],
            normals[idx[k]*3+1] += (GLfloat)crossProd.v[1],
            normals[idx[k]*3+2] += (GLfloat)crossProd.v[2];
         }
    }

    for(int i = 0; i < vertexCnt; i++) {
        float norm = 0.0f;
        for(int k = 0; k < 3; k++)
            norm += normals[i*3+k]*normals[i*3+k];
        for(int k = 0; k < 3; k++)
            normals[i*3+k] /= sqrt(norm);
    }

    // Calculate each vertecies' shape operator
    mat3* shapeOperators = NULL;
    float* vertexArea = NULL;
    shapeOperators = (mat3*)malloc(vertexCnt * sizeof(mat3));
    vertexArea = (float*)malloc(vertexCnt * sizeof(float));
    for(int i = 0; i < vertexCnt ; i++) {
        vertexArea[i] = 0.0f;
        for(int j = 0; j < 9; j++)
            shapeOperators[i].m[j] = 0.0f;
    }
    for(int k = 0; k < mesh->mNumFaces; k++) {
        // Calculate the face's area
        aiVector3D* aiVec[3];
        for(int idx = 0; idx < 3; idx++)
            aiVec[idx] = &(mesh->mVertices[mesh->mFaces[k].mIndices[idx]]);
        vec3 faceVec1 = vec3(aiVec[1]->x - aiVec[0]->x, 
                             aiVec[1]->y - aiVec[0]->y, 
                             aiVec[1]->z - aiVec[0]->z);
        vec3 faceVec2 = vec3(aiVec[2]->x - aiVec[1]->x,
                             aiVec[2]->y - aiVec[1]->y,
                             aiVec[2]->z - aiVec[1]->z);
        vec3 vecArea = cross(faceVec1, faceVec2);
        float faceArea = sqrt(vecArea.v[0]*vecArea.v[0] + vecArea.v[1]*vecArea.v[1] + vecArea.v[2]*vecArea.v[2]);

        for(int idx = 0; idx < 3; idx++) {
            int i = mesh->mFaces[k].mIndices[idx];
            int j = mesh->mFaces[k].mIndices[(idx+1)%3];
            // Get vertex i and j's normal vectors.
            vec3 Ni = vec3(normals[i*3], normals[i*3+1], normals[i*3+2]);
            vec3 Nj = vec3(normals[j*3], normals[j*3+1], normals[j*3+2]);
            // Get vertex i and j's location.
            const aiVector3D* aiVi = &(mesh->mVertices[i]);
            const aiVector3D* aiVj = &(mesh->mVertices[j]);
            vec3 Vi = vec3(aiVi->x, aiVi->y, aiVi->z);
            vec3 Vj = vec3(aiVj->x, aiVj->y, aiVj->z);
            
            // For vertex i, update the relative part of its shape operator
            vec3 Tij = (identity_mat3() - wedge(Ni, Ni))*(Vi-Vj);
            Tij = normalise(Tij);
            float kappa_ij = 2*dot(Ni, Vj-Vi);
            kappa_ij /= get_squared_dist(Vi, Vj);
            // Maintain vi's shape operator
            shapeOperators[i] = shapeOperators[i] + (wedge(Tij, Tij) * (kappa_ij * faceArea));
            vertexArea[i] += faceArea;

            // For vertex j, update the relative part of its shape operator
            vec3 Tji = (identity_mat3() - wedge(Nj, Nj))*(Vj-Vi);
            Tji = normalise(Tji);
            float kappa_ji = 2*dot(Nj, Vi-Vj);
            kappa_ji /= get_squared_dist(Vi, Vj);
            // Maintain vj's shape operator
            shapeOperators[j] = shapeOperators[j] + (wedge(Tji, Tji) * (kappa_ji * faceArea));
            
            vertexArea[j] += faceArea;
        }
    }

    for(int i = 0; i < vertexCnt; i++) {
        shapeOperators[i] = shapeOperators[i] * (1.0f/vertexArea[i]);// * 10000000.0f;
        //print(shapeOperators[i]);
    }
    free(vertexArea);

    // Diagonalize the shape operator, and get the mean curvature
    meanCurvature = (float*)malloc(vertexCnt * sizeof(float));
    for(int k = 0; k < vertexCnt; k++) {
        vec3 E1 = vec3(1.0f, 0.0f, 0.0f);
        vec3 Nk = vec3(normals[k*3], normals[k*3+1], normals[k*3+2]);
        bool isMinus = get_squared_dist(E1, Nk) > get_squared_dist(E1 * (-1.0f), Nk);
        vec3 Wk;
        // Diagnoalization by the Householder transform
        if (!isMinus)
            Wk = E1 + Nk;
        else
            Wk = E1 - Nk;
        Wk = normalise(Wk);
        mat3 Qk = identity_mat3() - (wedge(Wk, Wk) * 2.0f);
        mat3 Mk = transpose(Qk) * shapeOperators[k] * Qk;
        // Calculate the mean curvature by M_k's trace;
        meanCurvature[k] = (GLfloat)(Mk.m[4] + Mk.m[8]);
    }
    free(shapeOperators);

    // Calculate the incident matrix ( as linked list )
    int* first = NULL;
    int* next = NULL;
    int* incidentVertex = NULL;
    first = (int*)malloc(vertexCnt * sizeof(int));
    for(int i = 0; i < vertexCnt; i++)
        first[i] = -1;
    next = (int*)malloc(mesh->mNumFaces * 6 * sizeof(int));
    incidentVertex = (int*)malloc(mesh->mNumFaces * 6 * sizeof(int));
    int edgeCnt = 0;
    for(int k = 0; k < mesh->mNumFaces; k++) {
        int idx[3];
        for(int i = 0; i < 3; i++)
            idx[i] = mesh->mFaces[k].mIndices[i];
        for(int i = 0; i < 3; i++) {
            int j1 = idx[(i+1)%3], j2 = idx[(i+2)%3];
            incidentVertex[++edgeCnt] = j1;
            next[edgeCnt] = first[idx[i]]; first[idx[i]] = edgeCnt;
            incidentVertex[++edgeCnt] = j2;
            next[edgeCnt] = first[idx[i]]; first[idx[i]] = edgeCnt;
        }
    }
    
    printf("BFS 1\n");
    // Calculate the mesh saliency by BFS
    float diagonalLength = sqrt((xMax-xMin)*(xMax-xMin) + (yMax-yMin)*(yMax-yMin) + (zMax-zMin)*(zMax-zMin));
    float sigma = 0.003 * diagonalLength;
    float* saliency[7];
    float maxSaliency[7];
    for(int i = 2; i <= 6; i++) {
        saliency[i] = NULL;;
        saliency[i] = (float*)malloc(vertexCnt * sizeof(float));
        maxSaliency[i] = -oo;
    }

    // Labeled the vertecies whether covered or not.
    bool* used = NULL;
    used = (bool*)malloc(vertexCnt * sizeof(bool));
    for(int k = 0; k < vertexCnt; k++) {
        if(k%1000 == 0)
            printf("#%d#\n", k);
        // Initialize the saliency and its local counter.
        for(int i = 2; i <= 6; i++)
            saliency[i][k] = 0.0f;
        // Initialize the saliency's Gaussian filter.
        float gaussianSigma1[7], gaussianSigma2[7], sumSigma1[7], sumSigma2[7];
        for(int i = 2; i <= 6; i++)
            gaussianSigma1[i] = gaussianSigma2[i] = 0.0f,
            sumSigma1[i] = sumSigma2[i] = 0.0f;
        // Get the current vertex's information.
        aiVector3D* aiVec = &(mesh->mVertices[k]);
        vec3 vVec = vec3(aiVec->x, aiVec->y, aiVec->z);
        // Initialize the queue to find neighbourhood.
        for(int i = 0; i < vertexCnt; i++)
            used[i] = false;
        queue<int> Q;
        Q.push(k);
        used[k] = true;
        // Frsit BFS
        while(!Q.empty()) {
            // Get the front element in the queue.
            int idx = Q.front(); Q.pop();
            aiVec = &(mesh->mVertices[idx]);
            vec3 idxVec = vec3(aiVec->x, aiVec->y, aiVec->z);
            // Put the next level vertecies into the queue.
            for(int e = first[idx]; e != -1; e = next[e]) {
                int idxNext = incidentVertex[e];
                // Expand the next level vertecies.
                if(!used[idxNext]) {
                    aiVec = &(mesh->mVertices[idxNext]);
                    vec3 idxNextVec = vec3(aiVec->x, aiVec->y, aiVec->z);
                    if(get_squared_dist(vVec, idxNextVec) <= 36*sigma*sigma)
                        Q.push(incidentVertex[e]),
                        used[incidentVertex[e]] = 1;
                }
            }
            // Update Gaussian filter
            float dist = get_squared_dist(vVec, idxVec);
            for(int i = 2; i <= 6; i++) {
                float sigmaHere = i*i*sigma*sigma;
                if(dist <= sigmaHere) {
                    float factor = exp(-dist/(2*sigmaHere));
                    gaussianSigma1[i] += meanCurvature[idx] * factor;
                    sumSigma1[i] += factor;
                }
                if(dist <= 2*sigmaHere) {
                    float factor = exp(-dist/(8*sigma*sigma));
                    gaussianSigma2[i] += meanCurvature[idx] * factor;
                    sumSigma2[i] += factor;
                }
            }
        }
        for(int i = 2; i <= 6; i++) {
            saliency[i][k] = fabs(gaussianSigma1[i]/sumSigma1[i]
                                - gaussianSigma2[i]/sumSigma2[i]);
            maxSaliency[i] = fMax(maxSaliency[i], saliency[i][k]);
        }
    }

    printf("BFS 2\n");
    // Second BFS and get the non-linear normailization of suppressian's saliency.
    smoothSaliency = (float*)malloc(vertexCnt * sizeof(float));
    for(int k = 0; k < vertexCnt; k++) {
        if(k%1000 == 0)
            printf("[%d]\n", k);
        smoothSaliency[k] = 0.0f;
        float localMaxSaliency[7];//, localCntSaliency[7];
        for(int i = 2; i <= 6; i++)
            localMaxSaliency[i] = -oo;
        // Get the current vertex's information.
        aiVector3D* aiVec = &(mesh->mVertices[k]);
        vec3 vVec = vec3(aiVec->x, aiVec->y, aiVec->z);
        // Initialize the queue to find neighbourhood.
        for(int i = 0; i < vertexCnt; i++)
            used[i] = false;
        queue<int> Q;
        Q.push(k);
        used[k] = true;
        while(!Q.empty()) {
            // Get the front element in the queue.
            int idx = Q.front(); Q.pop();
            //aiVec = &(mesh->mVertices[idx]);
            //vec3 idxVec = vec3(aiVec->x, aiVec->y, aiVec->z);
            // Put the next level vertecies into the queue.
            for(int e = first[idx]; e != -1; e = next[e]) {
                int idxNext = incidentVertex[e]; 
                // Expand the next level vertecies.
                if(!used[idxNext]) {
                    aiVec = &(mesh->mVertices[idxNext]); 
                    vec3 idxNextVec = vec3(aiVec->x, aiVec->y, aiVec->z);
                    if(get_squared_dist(vVec, idxNextVec) <= 36*sigma*sigma)
                        Q.push(incidentVertex[ e]),
                        used[incidentVertex[e]] = 1;
                }
            }
            // Update Gaussian filter
            for(int i = 2; i <= 6; i++) 
                localMaxSaliency[i] = fMax(localMaxSaliency[i], saliency[i][idx]);
        }
        // Calculate the weighted saliency
        float saliencySum = 0.0f;
        for(int i = 2; i <= 6; i++) {
            float factor = (maxSaliency[i]-localMaxSaliency[i])*(maxSaliency[i]-localMaxSaliency[i]);
            smoothSaliency[k] += (GLfloat)saliency[i][k] * factor;
            saliencySum += factor;
        }
        smoothSaliency[k] /= (GLfloat)saliencySum;
    }

    // Clean up resources
    free(first);
    free(next);
    free(incidentVertex);
    for(int i = 2; i <= 6; i++)
        free(saliency[i]);
    
	// Copy all vertecies and normal vertors in mesh data into VBOs
    /*
    {
        GLuint vbo;
        glGenBuffers (1, &vbo);
        glBindBuffer (GL_ARRAY_BUFFER, vbo);
        glBufferData (
            GL_ARRAY_BUFFER,
            3 * vertexCnt * sizeof (GLfloat),
            points,
            GL_STATIC_DRAW
        );
        glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
        glEnableVertexAttribArray (0);
        free (points);
    }
    */

    // Copy all normal vectors in mesh data into VBOs
    updateDisplayType(1);
	aiReleaseImport (scene);
	printf ("mesh loaded\n");
	
	return true;
}
예제 #7
0
QMF_DOMAIN_ERROR FDK_QmfDomain_Configure(HANDLE_FDK_QMF_DOMAIN hqd) {
  FDK_ASSERT(hqd != NULL);
  QMF_DOMAIN_ERROR err = QMF_DOMAIN_OK;
  int i, size_main, size, size_temp = 0;

  HANDLE_FDK_QMF_DOMAIN_GC hgc = &hqd->globalConf;
  FIXP_DBL **pWorkBuffer = hgc->pWorkBuffer;

  int hasChanged = 0;

  if ((hgc->nQmfProcChannels_requested > 0) &&
      (hgc->nQmfProcBands_requested != 64)) {
    return QMF_DOMAIN_INIT_ERROR;
  }
  if (hgc->nBandsAnalysis_requested > hgc->nQmfProcBands_requested) {
    /* In general the output of the qmf analysis is written to QMF memory slots
       which size is defined by nQmfProcBands. nBandsSynthesis may be larger
       than nQmfProcBands. This is e.g. the case if the QMF based resampler is
       used.
    */
    return QMF_DOMAIN_INIT_ERROR;
  }

  /* 1. adjust change of processing channels by comparison of current and
   * requested parameters */
  if ((hgc->nQmfProcChannels != hgc->nQmfProcChannels_requested) ||
      (hgc->nQmfProcBands != hgc->nQmfProcBands_requested) ||
      (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested)) {
    for (i = 0; i < hgc->nQmfProcChannels_requested; i++) {
      hqd->QmfDomainIn[i].workBuf_nBands = hgc->nQmfProcBands_requested;
      hgc->nQmfProcBands = hgc->nQmfProcBands_requested;

      hqd->QmfDomainIn[i].workBuf_nTimeSlots = hgc->nQmfTimeSlots_requested;
    }

    hgc->nQmfProcChannels =
        hgc->nQmfProcChannels_requested; /* keep highest value encountered so
                                            far as allocated */

    hasChanged = 1;
  }

  /* 2. reallocate persistent memory if necessary (analysis state-buffers,
   * timeslot-pointer-array, overlap-buffers, synthesis state-buffers) */
  if ((hgc->nInputChannels != hgc->nInputChannels_requested) ||
      (hgc->nBandsAnalysis != hgc->nBandsAnalysis_requested) ||
      (hgc->nQmfTimeSlots != hgc->nQmfTimeSlots_requested) ||
      (hgc->nQmfOvTimeSlots != hgc->nQmfOvTimeSlots_requested) ||
      (hgc->nOutputChannels != hgc->nOutputChannels_requested) ||
      (hgc->nBandsSynthesis != hgc->nBandsSynthesis_requested) ||
      (hgc->parkChannel != hgc->parkChannel_requested)) {
    hgc->nInputChannels = hgc->nInputChannels_requested;
    hgc->nBandsAnalysis = hgc->nBandsAnalysis_requested;
    hgc->nQmfTimeSlots = hgc->nQmfTimeSlots_requested;
    hgc->nQmfOvTimeSlots = hgc->nQmfOvTimeSlots_requested;
    hgc->nOutputChannels = hgc->nOutputChannels_requested;
    hgc->nBandsSynthesis = hgc->nBandsSynthesis_requested;
    hgc->parkChannel = hgc->parkChannel_requested;

    if (FDK_QmfDomain_AllocatePersistentMemory(hqd)) {
      err = QMF_DOMAIN_OUT_OF_MEMORY;
      goto bail;
    }

    /* 3. set request-flag for downsampled SBR */
    if ((hgc->nBandsAnalysis == 32) && (hgc->nBandsSynthesis == 32) &&
        !(hgc->flags & (QMF_FLAG_CLDFB | QMF_FLAG_MPSLDFB))) {
      hgc->flags_requested |= QMF_FLAG_DOWNSAMPLED;
    }

    hasChanged = 1;
  }

  /* 4. initialize tables and buffer for QMF-resampler */

  /* 5. set requested flags */
  if (hgc->flags != hgc->flags_requested) {
    if ((hgc->flags_requested & QMF_FLAG_MPSLDFB) &&
        (hgc->flags_requested & QMF_FLAG_CLDFB)) {
      hgc->flags_requested &= ~QMF_FLAG_CLDFB;
    }
    hgc->flags = hgc->flags_requested;
    hasChanged = 1;
  }

  if (hasChanged) {
    /* 6. recalculate and check size of required workbuffer-space */

    if (hgc->parkChannel && (hqd->globalConf.nQmfProcChannels == 1)) {
      /* configure temp QMF buffer for parking right channel MPS212 output,
       * (USAC stereoConfigIndex 3 only) */
      hqd->QmfDomainIn[1].workBuf_nBands = hqd->globalConf.nBandsAnalysis;
      hqd->QmfDomainIn[1].workBuf_nTimeSlots = hqd->globalConf.nQmfTimeSlots;
      size_temp = hqd->QmfDomainIn[1].workBuf_nBands *
                  hqd->QmfDomainIn[1].workBuf_nTimeSlots * CMPLX_MOD;
    }

    size_main = hqd->QmfDomainIn[0].workBuf_nBands *
                hqd->QmfDomainIn[0].workBuf_nTimeSlots * CMPLX_MOD;

    size = size_main * hgc->nQmfProcChannels + size_temp;

    if (size > (QMF_MAX_WB_SECTIONS * QMF_WB_SECTION_SIZE)) {
      err = QMF_DOMAIN_OUT_OF_MEMORY;
      goto bail;
    }

    /* 7. allocate additional workbuffer if necessary */
    if ((size > 0 /* *QMF_WB_SECTION_SIZE */) && (pWorkBuffer[0] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[0] = GetQmfWorkBufferCore6();
    }

    if ((size > 1 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[1] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[1] = GetQmfWorkBufferCore1();
    }

    if ((size > 2 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[2] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[2] = GetQmfWorkBufferCore3();
    }

    if ((size > 3 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[3] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[3] = GetQmfWorkBufferCore4();
    }

    if ((size > 4 * QMF_WB_SECTION_SIZE) && (pWorkBuffer[4] == NULL)) {
      /* get work buffer of size QMF_WB_SECTION_SIZE */
      pWorkBuffer[4] = GetQmfWorkBufferCore5();
    }

    /* 8. distribute workbuffer over processing channels */
    for (i = 0; i < hgc->nQmfProcChannels; i++) {
      FDK_QmfDomain_FeedWorkBuffer(hqd, i, pWorkBuffer, size_main * i,
                                   QMF_WB_SECTION_SIZE, size_main);
    }
    if (hgc->parkChannel) {
      for (; i < hgc->nInputChannels; i++) {
        FDK_QmfDomain_FeedWorkBuffer(hqd, 1, pWorkBuffer,
                                     size_main * hgc->nQmfProcChannels,
                                     QMF_WB_SECTION_SIZE, size_temp);
      }
    }

    /* 9. (re-)init filterbank */
    for (i = 0; i < hgc->nOutputChannels; i++) {
      if ((hqd->QmfDomainOut[i].fb.lsb == 0) &&
          (hqd->QmfDomainOut[i].fb.usb == 0)) {
        /* Although lsb and usb are set in the SBR module, they are initialized
         * at this point due to the case of using MPS without SBR. */
        hqd->QmfDomainOut[i].fb.lsb = hgc->nBandsAnalysis_requested;
        hqd->QmfDomainOut[i].fb.usb =
            fMin((INT)hgc->nBandsSynthesis_requested, 64);
      }
    }
    if (FDK_QmfDomain_InitFilterBank(hqd, 0)) {
      err = QMF_DOMAIN_INIT_ERROR;
    }
  }

bail:
  if (err) {
    FDK_QmfDomain_FreeMem(hqd);
  }
  return err;
}
예제 #8
0
void FDK_QmfDomain_GetSlot(const HANDLE_FDK_QMF_DOMAIN_IN qd_ch, const int ts,
                           const int start_band, const int stop_band,
                           FIXP_DBL *pQmfOutReal, FIXP_DBL *pQmfOutImag,
                           const int exp_out) {
  FDK_ASSERT(qd_ch != NULL);
  FDK_ASSERT(pQmfOutReal != NULL);
  HANDLE_FDK_QMF_DOMAIN_GC gc = qd_ch->pGlobalConf;
  const FIXP_DBL *real = qd_ch->hQmfSlotsReal[ts];
  const FIXP_DBL *imag = qd_ch->hQmfSlotsImag[ts];
  const int ovSlots = gc->nQmfOvTimeSlots;
  const int exp_lb = SCALE2EXP((ts < ovSlots) ? qd_ch->scaling.ov_lb_scale
                                              : qd_ch->scaling.lb_scale);
  const int exp_hb = SCALE2EXP(qd_ch->scaling.hb_scale);
  const int lsb = qd_ch->fb.lsb;
  const int usb = qd_ch->fb.usb;
  int b = start_band;
  int lb_sf, hb_sf;

  int target_exp =
      ALGORITHMIC_SCALING_IN_ANALYSIS_FILTERBANK + qd_ch->fb.filterScale;

  FDK_ASSERT(ts < (gc->nQmfTimeSlots + gc->nQmfOvTimeSlots));
  FDK_ASSERT(start_band >= 0);
  FDK_ASSERT(stop_band <= gc->nQmfProcBands);

  if (qd_ch->fb.no_channels == 24) {
    target_exp -= 1;
  }

  /* Limit scaling factors to maximum negative value to avoid faulty behaviour
     due to right-shifts. Corresponding asserts were observed during robustness
     testing.
   */
  lb_sf = fMax(exp_lb - target_exp - exp_out, -31);
  FDK_ASSERT(lb_sf < 32);
  hb_sf = fMax(exp_hb - target_exp - exp_out, -31);
  FDK_ASSERT(hb_sf < 32);

  if (pQmfOutImag == NULL) {
    for (; b < fMin(lsb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], lb_sf);
    }
    for (; b < fMin(usb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], hb_sf);
    }
    for (; b < stop_band; b++) {
      pQmfOutReal[b] = (FIXP_DBL)0;
    }
  } else {
    FDK_ASSERT(imag != NULL);
    for (; b < fMin(lsb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], lb_sf);
      pQmfOutImag[b] = scaleValue(imag[b], lb_sf);
    }
    for (; b < fMin(usb, stop_band); b++) {
      pQmfOutReal[b] = scaleValue(real[b], hb_sf);
      pQmfOutImag[b] = scaleValue(imag[b], hb_sf);
    }
    for (; b < stop_band; b++) {
      pQmfOutReal[b] = (FIXP_DBL)0;
      pQmfOutImag[b] = (FIXP_DBL)0;
    }
  }
}
예제 #9
0
int FDK_QmfDomain_InitFilterBank(HANDLE_FDK_QMF_DOMAIN qd, UINT extra_flags) {
  FDK_ASSERT(qd != NULL);
  int err = 0;
  int ch, ts;
  HANDLE_FDK_QMF_DOMAIN_GC gc = &qd->globalConf;
  int noCols = gc->nQmfTimeSlots;
  int lsb = gc->nBandsAnalysis;
  int usb = fMin((INT)gc->nBandsSynthesis, 64);
  int nProcBands = gc->nQmfProcBands;
  FDK_ASSERT(nProcBands % ALIGNMENT_DEFAULT == 0);

  if (extra_flags & QMF_FLAG_MPSLDFB) {
    gc->flags &= ~QMF_FLAG_CLDFB;
    gc->flags |= QMF_FLAG_MPSLDFB;
  }
  for (ch = 0; ch < gc->nInputChannels; ch++) {
    /* distribute memory to slots array */
    FIXP_DBL *ptrOv =
        qd->QmfDomainIn[ch].pOverlapBuffer; /* persistent memory for overlap */
    if ((ptrOv == NULL) && (gc->nQmfOvTimeSlots != 0)) {
      err = 1;
      return err;
    }
    /* This assumes the workbuffer defined for ch0 is the big one being used to
     * hold one full frame of QMF data. */
    FIXP_DBL **ptr =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .pWorkBuffer; /* non-persistent workbuffer */
    USHORT workBufferOffset =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .workBufferOffset;
    USHORT workBufferSectSize =
        qd->QmfDomainIn[fMin(ch, fMax((INT)gc->nQmfProcChannels - 1, 0))]
            .workBufferSectSize;

    if ((ptr == NULL) && (gc->nQmfTimeSlots != 0)) {
      err = 1;
      return err;
    }

    qd->QmfDomainIn[ch].pGlobalConf = gc;
    for (ts = 0; ts < gc->nQmfOvTimeSlots; ts++) {
      qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = ptrOv;
      ptrOv += nProcBands;
      qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = ptrOv;
      ptrOv += nProcBands;
    }
    for (; ts < (gc->nQmfOvTimeSlots + gc->nQmfTimeSlots); ts++) {
      qd->QmfDomainIn[ch].hQmfSlotsReal[ts] = FDK_getWorkBuffer(
          ptr, workBufferOffset, workBufferSectSize, nProcBands);
      workBufferOffset += nProcBands;
      qd->QmfDomainIn[ch].hQmfSlotsImag[ts] = FDK_getWorkBuffer(
          ptr, workBufferOffset, workBufferSectSize, nProcBands);
      workBufferOffset += nProcBands;
    }
    err |= qmfInitAnalysisFilterBank(
        &qd->QmfDomainIn[ch].fb, qd->QmfDomainIn[ch].pAnaQmfStates, noCols,
        (qd->QmfDomainIn[ch].fb.lsb == 0) ? lsb : qd->QmfDomainIn[ch].fb.lsb,
        (qd->QmfDomainIn[ch].fb.usb == 0) ? usb : qd->QmfDomainIn[ch].fb.usb,
        gc->nBandsAnalysis, gc->flags | extra_flags);
  }

  for (ch = 0; ch < gc->nOutputChannels; ch++) {
    FIXP_DBL outGain_m = qd->QmfDomainOut[ch].fb.outGain_m;
    int outGain_e = qd->QmfDomainOut[ch].fb.outGain_e;
    int outScale = qmfGetOutScalefactor(&qd->QmfDomainOut[ch].fb);
    err |= qmfInitSynthesisFilterBank(
        &qd->QmfDomainOut[ch].fb, qd->QmfDomainOut[ch].pSynQmfStates, noCols,
        (qd->QmfDomainOut[ch].fb.lsb == 0) ? lsb : qd->QmfDomainOut[ch].fb.lsb,
        (qd->QmfDomainOut[ch].fb.usb == 0) ? usb : qd->QmfDomainOut[ch].fb.usb,
        gc->nBandsSynthesis, gc->flags | extra_flags);
    if (outGain_m != (FIXP_DBL)0) {
      qmfChangeOutGain(&qd->QmfDomainOut[ch].fb, outGain_m, outGain_e);
    }
    if (outScale) {
      qmfChangeOutScalefactor(&qd->QmfDomainOut[ch].fb, outScale);
    }
  }

  return err;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
    double *points,a,b,b2,f,e2,eps2,ec;
    size_t numVec,i;
    mxArray *retMat;
    double *retData;
    
    if(nrhs>3||nrhs<1){
        mexErrMsgTxt("Wrong number of inputs");
    }
    
    if(nlhs>1) {
        mexErrMsgTxt("Wrong number of outputs.");
        return;
    }
    
    checkRealDoubleArray(prhs[0]);
    numVec = mxGetN(prhs[0]);
    
    if(mxGetM(prhs[0])!=3) {
        mexErrMsgTxt("The input vector has a bad dimensionality.");
    }
    
    points=(double*)mxGetData(prhs[0]);
    //points[0] is x
    //points[1] is y
    //points[2] is z
    
    if(nrhs>1) {
        a=getDoubleFromMatlab(prhs[1]);
    } else {
        a=getScalarMatlabClassConst("Constants", "WGS84SemiMajorAxis");
    }

    if(nrhs>2) {
        f=getDoubleFromMatlab(prhs[2]);
    } else {
        f=getScalarMatlabClassConst("Constants", "WGS84Flattening");   
    }
    
    b=a*(1-f);//The semi-minor axis of the reference ellipsoid.
    b2=b*b;

    //The square of the first numerical eccentricity. 
    e2=2*f-f*f;
    //The square of the second numerical eccentricity.
    eps2=a*a/(b2)-1;

    //This value is used if Fukushima's method is chosen.
    ec=sqrt(1-e2);

    //Allocate space for the return variables.
    retMat=mxCreateDoubleMatrix(3,numVec,mxREAL);
    retData=(double*)mxGetData(retMat);
    
    for(i=0;i<numVec;i++) {
        double *phi, *lambda, *h;
        double x0,y0,z0;
        double r0,p,s,q;
        
        //Get the Cartesian point to convert.
        x0=points[3*i];
        y0=points[3*i+1];
        z0=points[3*i+2];
        
        //Get the addresses of where the converted components will go
        phi=retData+3*i;
        lambda=retData+3*i+1;
        h=retData+3*i+2;
        
        r0=sqrt(x0*x0+y0*y0);
        p=fabs(z0)/eps2;
        s=r0*r0/(e2*eps2);
        q=p*p-b2+s;
    
        *lambda=atan2(y0,x0);
        if(q>=0) {//Use Sofair's algorithm
            double u,v,P,Q,t,c,w,z,Ne,val;
            
            u=p/sqrt(q);
            v=b2*u*u/q;
            P=27.0*v*s/q;
            Q=pow(sqrt(P+1.0)+sqrt(P),2.0/3.0);
            t=(1.0+Q+1/Q)/6.0;
            c=u*u-1+2*t;
            //This condition prevents finite precision problems due to
            //subtraction within the square root.
            c=fMax(c,0);
            c=sqrt(c);
            w=(c-u)/2.0;

        //The z coordinate of the closest point projected on the ellipsoid.
        //The fmax command deals with precision problems when the argument
        //is nearly zero. The problems arise due to the subtraction within
        //the square root.
            z=sqrt(t*t+v)-u*w-t/2.0-1.0/4.0;
            z=fMax(z,0);
            z=copySign(sqrt(q)*(w+sqrt(z)),z0);
            
            Ne=a*sqrt(1+eps2*z*z/b2);

            //The min and max terms deals with finite precision problems.
            val=fMin(z*(eps2+1)/Ne,1);
            val=fMax(val,-1.0);
            *phi=asin(val);
            *h=r0*cos(*phi)+z0*sin(*phi)-a*a/Ne;
        } else {//Use Fukushima's algorithm.
            double Cc,P,Z,S,C;
            //A gets a value within the loop. This initialization is just
            //to silence a warning when compiling with
            //-Wconditional-uninitialized
            double A=0;
            size_t curIter;
            const size_t maxIter=6;
            
            P=r0/a;
            Z=(ec/a)*fabs(z0);

            S=Z;
            C=ec*P;

            //Loop until convergence. Assume convergence in 6 iterations.
            for(curIter=0;curIter<maxIter;curIter++) {
                double B,F,D,SNew,CNew;
                
                A=sqrt(S*S+C*C);
                B=1.5*e2*S*C*C*((P*S-Z*C)*A-e2*S*C);
                F=P*A*A*A-e2*C*C*C;
                D=Z*A*A*A+e2*S*S*S;

                SNew=D*F-B*S;
                CNew=F*F-B*C;

                SNew=SNew/CNew;
                
                if(!isFinite(SNew)) {
                    S=SNew;
                    C=1;
                    A=sqrt(S*S+C*C);
                    break;
                } else {
                    S=SNew;
                    C=1;
                }
            }
            Cc=ec*C;

            //If the point is along the z-axis, then SNew and CNew will
            //both be zero, leading to a non-finite result.
            if(!isFinite(S)) {
                *phi=copySign(pi/2,z0);
                *h=fabs(z0)-b;
            } else {
                *phi=copySign(atan(S/Cc),z0);
                *h=(r0*Cc+fabs(z0)*S-b*A)/sqrt(Cc*Cc+S*S);
            }
        }
    }

    plhs[0]=retMat;
}
예제 #11
0
// Update display mode depends on keyboard state
void updateDisplayType(int type) {
    if(type != 1 && type != 2 && type != 3 && type != 4 && type != 5) {
        fprintf(stderr, "Wrong Display Type!\n");
        return;
    }

    int vertexCntHere = (type >= 4 ? simplifiedVertexCnt : vertexCnt);
    // Copy all vertecies in mesh data into VBOs
    {
        GLuint vbo;
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData (
            GL_ARRAY_BUFFER,
            3 * vertexCntHere * sizeof (GLfloat),
            type >= 4 ? simplifiedPoints : points,
            GL_STATIC_DRAW
        );
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
        glEnableVertexAttribArray(0);
    }
    // Copy all vertices' color values in mesh data into VBOs
    {
        GLuint vbo;
        glGenBuffers (1, &vbo);
        glBindBuffer (GL_ARRAY_BUFFER, vbo);
        float* colors = NULL;
        colors = (float*)malloc(vertexCntHere * 3 * sizeof(float));
        switch(type) {
            // Normals mode
            case 1: {
                        for(int i = 0; i < vertexCntHere; i++)
                            colors[3*i+0] = normals[3*i+0],
                            colors[3*i+1] = normals[3*i+1],
                            colors[3*i+2] = normals[3*i+2];
                        break;
                    }
            // Mean curvature mode
            case 2: {
                        float xMin = oo, xMax = -oo;
                        for(int i = 0; i < vertexCntHere; i++)
                            xMin = fMin(xMin, fabs(meanCurvature[i])),
                            xMax = fMax(xMax, fabs(meanCurvature[i]));
                        // Normalize the Y value
                        for(int i = 0; i < vertexCntHere; i++) {
                            float Y = 255.0f*((log(1e-8+fabs(meanCurvature[i]))-log(1e-8+xMin))
                                    / (log(1e-8+xMax)-log(1e-8+xMin)));
                            getYUVtoRGB(meanCurvature[i]>0.0, Y, 255.0f, 255.0f, colors[3*i], colors[3*i+1], colors[3*i+2]);
                        }
                        break;
                    }
            // Mesh saliency mode
            case 3: {
                         float xMin = oo, xMax = -oo;
                        for(int i = 0; i < vertexCntHere; i++)
                            xMin = fMin(xMin, fabs(smoothSaliency[i])),
                            xMax = fMax(xMax, fabs(smoothSaliency[i]));
                        // Normalize the Y value
                        for(int i = 0; i < vertexCntHere; i++) {
                            float Y = 255.0f*(log(1e-8+smoothSaliency[i])-log(1e-8+xMin))
                                    / (log(1e-8+xMax)-log(1e-8+xMin));
                            getYUVtoRGB(smoothSaliency[i]>0, Y, 255.0f, 255.0f, colors[3*i], colors[3*i+1], colors[3*i+2]);
                        }
                        break;
                    }
            case 4: {
                        for(int i = 0; i < vertexCntHere; i++)
                            colors[3*i+0] = simplifiedNormals[3*i+0],
                            colors[3*i+1] = simplifiedNormals[3*i+1],
                            colors[3*i+2] = simplifiedNormals[3*i+2];
                        break;
                    }
        }
        glBufferData (
            GL_ARRAY_BUFFER,
            3 * vertexCntHere * sizeof (GLfloat),
            colors,
            GL_STATIC_DRAW
        );
        glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
        glEnableVertexAttribArray (1);
    }
}
예제 #12
0
void CJointStereo_ApplyMS(
        CAacDecoderChannelInfo *pAacDecoderChannelInfo[2],
        const SHORT *pScaleFactorBandOffsets,
        const UCHAR *pWindowGroupLength,
        const int windowGroups,
        const int scaleFactorBandsTransmittedL,
        const int scaleFactorBandsTransmittedR
        )
{
  CJointStereoData *pJointStereoData = &pAacDecoderChannelInfo[L]->pComData->jointStereoData;
  int window, group, scaleFactorBandsTransmitted;

  FDK_ASSERT(scaleFactorBandsTransmittedL == scaleFactorBandsTransmittedR);
  scaleFactorBandsTransmitted = scaleFactorBandsTransmittedL;
  for (window = 0, group = 0; group < windowGroups; group++)
  {
    UCHAR groupMask = 1 << group;

    for (int groupwin=0; groupwin<pWindowGroupLength[group]; groupwin++, window++)
    {
      int band;
      FIXP_DBL *leftSpectrum, *rightSpectrum;
      SHORT *leftScale = &pAacDecoderChannelInfo[L]->pDynData->aSfbScale[window*16];
      SHORT *rightScale = &pAacDecoderChannelInfo[R]->pDynData->aSfbScale[window*16];

      leftSpectrum = SPEC(pAacDecoderChannelInfo[L]->pSpectralCoefficient, window, pAacDecoderChannelInfo[L]->granuleLength);
      rightSpectrum = SPEC(pAacDecoderChannelInfo[R]->pSpectralCoefficient, window, pAacDecoderChannelInfo[R]->granuleLength);

      for (band=0; band<scaleFactorBandsTransmitted; band++)
      {
        if (pJointStereoData->MsUsed[band] & groupMask)
        {
          int lScale=leftScale[band];
          int rScale=rightScale[band];
          int commonScale=lScale > rScale ? lScale:rScale;

          /* ISO/IEC 14496-3 Chapter 4.6.8.1.1 :
             M/S joint channel coding can only be used if common_window is ‘1’. */
          FDK_ASSERT(GetWindowSequence(&pAacDecoderChannelInfo[L]->icsInfo) == GetWindowSequence(&pAacDecoderChannelInfo[R]->icsInfo));
          FDK_ASSERT(GetWindowShape(&pAacDecoderChannelInfo[L]->icsInfo) == GetWindowShape(&pAacDecoderChannelInfo[R]->icsInfo));

          commonScale++;
          leftScale[band]=commonScale;
          rightScale[band]=commonScale;

          lScale = fMin(DFRACT_BITS-1, commonScale - lScale);
          rScale = fMin(DFRACT_BITS-1, commonScale - rScale);

          FDK_ASSERT(lScale >= 0 && rScale >= 0);

          for (int index=pScaleFactorBandOffsets[band]; index<pScaleFactorBandOffsets[band+1]; index++)
          {
            FIXP_DBL leftCoefficient  = leftSpectrum [index] ;
            FIXP_DBL rightCoefficient = rightSpectrum [index] ;

            leftCoefficient >>= lScale ;
            rightCoefficient >>= rScale ;

            leftSpectrum [index] = leftCoefficient + rightCoefficient ;
            rightSpectrum [index] = leftCoefficient - rightCoefficient ;
          }
        }
      }
    }
  }