コード例 #1
0
void ofxZenGarden::processNonInterleaved(float *input, float *output, int frameCount) {
	if(context==NULL || !running) return;
	setBlockSize(frameCount);
	memset(output, 0, frameCount*sizeof(float)*numOutputChannels);

	zg_process(context, input, output);
	
}
コード例 #2
0
ファイル: main.cpp プロジェクト: brolin/ZenGarden
int main(int argc, char * const argv[]) {
  const int blockSize = 64;
  const int numInputChannels = 2;
  const int numOutputChannels = 2;
  const float sampleRate = 22050.0f;
  
  // pass directory and filename of the patch to load
  PdContext *context = zg_new_context(numInputChannels, numOutputChannels, blockSize, sampleRate,
      callbackFunction, NULL);
  PdGraph *graph = zg_new_graph(context, "/Users/mhroth/workspace/ZenGarden/test/", "MessageMessageBox.pd");
  if (graph == NULL) {
    zg_delete_context(context);
    return 1;
  }
  
  zg_attach_graph(context, graph);
  
  float *inputBuffers = (float *) calloc(numInputChannels * blockSize, sizeof(float));
  float *outputBuffers = (float *) calloc(numOutputChannels * blockSize, sizeof(float));
  
  timeval start, end;
  gettimeofday(&start, NULL);
  for (int i = 0; i < NUM_ITERATIONS; i++) {
    zg_process(context, inputBuffers, outputBuffers);
  }
  gettimeofday(&end, NULL);
  double elapsedTime = (end.tv_sec - start.tv_sec) * 1000.0; // sec to ms
  elapsedTime += (end.tv_usec - start.tv_usec) / 1000.0; // us to ms
  printf("Runtime is: %i iterations in %f milliseconds == %f iterations/second.\n", NUM_ITERATIONS,
    elapsedTime, ((double) NUM_ITERATIONS)*1000.0/elapsedTime);
  double simulatedTime = ((double) blockSize / (double) sampleRate) * (double) NUM_ITERATIONS * 1000.0; // milliseconds
  printf("Runs in realtime: %s (x%.3f)\n", (simulatedTime >= elapsedTime) ? "YES" : "NO", simulatedTime/elapsedTime);
  
  zg_delete_context(context);
  free(inputBuffers);
  free(outputBuffers);
  
  return 0;
}
コード例 #3
0
void ofxZenGarden::process(float *input, float *output, int frameCount) {
	if(context==NULL || !running) return;
	setBlockSize(frameCount);
	memset(output, 0, frameCount*sizeof(float)*numOutputChannels);

	zg_process(context, input, outputBuffer);

	
	
	if(numOutputChannels==1) {
		memcpy(output, outputBuffer, sizeof(float)*frameCount);
	} else if(numOutputChannels==2) {
		for(int i = 0; i < frameCount; i++) { 
			output[i*2] = outputBuffer[i];
			output[i*2 + 1] = outputBuffer[i + blockSize];
		}
	} else {
		for(int i = 0; i < blockSize; i++) { 
			for(int channel = 0; channel < numOutputChannels; channel++) { 
				output[i*numOutputChannels + channel] = outputBuffer[i + channel*blockSize]; 
			} 
		}
	}
}
コード例 #4
0
ファイル: jnizengarden.cpp プロジェクト: roikr/ZenGarden
// this function uses bit-wise manupulation in order to more quickly multiply floats by
// -1 or 32768. See http://en.wikipedia.org/wiki/IEEE_754-1985
JNIEXPORT void JNICALL Java_me_rjdj_zengarden_ZenGarden_process(
    JNIEnv *env, jobject jobj, jshortArray jinputBuffer, jshortArray joutputBuffer, jlong nativePtr) {
  
  PureDataMobileNativeVars *pdmnv = (PureDataMobileNativeVars *) nativePtr;
  
  // set up the floating point input buffers
  short *cinputBuffer = (short *) env->GetPrimitiveArrayCritical(jinputBuffer, NULL);
  switch (pdmnv->numInputChannels) {
    case 1: { // if there is only one input channel (mono)
      // convert all shorts to floats
      for (int i = 0; i < pdmnv->blockSize; i++) {
        pdmnv->finputBuffer[i] = shortSampleToFloat(cinputBuffer[i], pdmnv);
      }
      // copy the float buffer from the left to right channel
      memcpy(pdmnv->finputBuffer + pdmnv->blockSize, pdmnv->finputBuffer, pdmnv->numBytesInBlock);
      break;
    }
    case 2: { // if there is a stereo input
      // uninterleave the short buffer
      for (int i = 0, j = 0; i < pdmnv->blockSize; i++) {
        for (int k = 0, z = i; k < pdmnv->numInputChannels; k++, j++, z+=pdmnv->blockSize) {
          pdmnv->finputBuffer[z] = shortSampleToFloat(cinputBuffer[j], pdmnv);
        }
      }
      break;
    }
    default: {
      break;
    }
  }
  env->ReleasePrimitiveArrayCritical(jinputBuffer, cinputBuffer, JNI_ABORT); // no need to copy back changes. release native buffer.
  
  zg_process(pdmnv->pdGraph, pdmnv->finputBuffer, pdmnv->foutputBuffer);
  
  // read back from the floating point output buffers
  // regarding use of lrintf, see http://www.mega-nerd.com/FPcast/
  short *coutputBuffer = (short *) env->GetPrimitiveArrayCritical(joutputBuffer, NULL);
  for (int i = 0, j = 0; i < pdmnv->blockSize; i++) {
    for (int k = 0, z = i; k < pdmnv->numOutputChannels; k++, j++, z+=pdmnv->blockSize) {
      // clip the output (like Pd does)
      float f = pdmnv->foutputBuffer[z];
      if (f > 1.0f) {
        coutputBuffer[j] = 32767;
      } else if (f < -1.0f) {
        coutputBuffer[j] = -32768;
      } else {
        coutputBuffer[j] = (short) lrintf(f * 32767.0f);
      }
      /*
       * WARNING: if pdmnv->foutputBuffer[z] == 1.0f, this method will result in -32768, not 32767
       * and cause a click in the output (i.e., there is overflow when converting to a short)
       int floatAsInt = *(int *)(pdmnv->foutputBuffer+z);
       int exponent = floatAsInt & 0x7F800000;
       exponent += 0x07800000; // multiply by 32768.0f == 2^15 (add 15 to the exponent)
       floatAsInt = (floatAsInt & 0x807FFFFF) | exponent;
       coutputBuffer[j] = (short) lrintf(*(float *)&floatAsInt);
       */
    }
  }
  env->ReleasePrimitiveArrayCritical(joutputBuffer, coutputBuffer, 0); // copy back the changes and release native buffer
}
コード例 #5
0
void PdSynth :: audioCB() {
    if (mPd == NULL) return;

    int from = synth.mStart;
    int to = synth.mEnd;

    PortReader input_p1(synth, 0);
    PortReader input_p2(synth, 1);
    PortReader out_p1(synth, 2);
    PortReader out_p2(synth, 3);
    PortReader amp_p1(synth, 4);

    luaav_audio_config cfg = luaav_audio_config_current();
    //int blocksize = cfg.blocksize;
//	int nchnls =  csound->GetNchnls();
//	int ksmps = csound->GetKsmps();
//	double scale = csound->Get0dBFS();
//	double inv_scale = 1.0 / scale;
    //long inbufsize = csound->GetInputBufferSize();
    //long outbufsize = csound->GetOutputBufferSize();


//	sample * outbuffers[2];
//	outbuffers[0] = luaav3_OutPort_data(&self->synth.output, 0);
//	outbuffers[1] = luaav3_OutPort_data(&self->synth.output, 1);
//
//	sample const * inbuffers[2];
//	inbuffers[0] = luaav3_InPort_data(&self->input, 0);
//	inbuffers[1] = luaav3_InPort_data(&self->input, 1);

    // if ksmps is less than blocksize, need to run multiple passes


    // copy buffers in:
    // TODO: use a Control array instead of globals
    float * dst1 = mInputBuffers;
    float * dst2 = mInputBuffers + mBlockSize;
    for (int i=0; i<mBlockSize; i++) {
        dst1[i] = (float)input_p1[i];
        dst2[i] = (float)input_p2[i];
    }

    // let PD do the work:
    zg_process(mPd, mInputBuffers, mOutputBuffers);

    // copy buffers back out:
    // TODO: use a Control array instead of globals
    float * src1 = mOutputBuffers;
    float * src2 = mOutputBuffers + mBlockSize;
    for (int i=0; i<mBlockSize; i++) {
        sample amp = amp_p1[i];
        out_p1[i] += amp * (sample)src1[i];
        out_p2[i] += amp * (sample)src2[i];
    }

    //
//		// because csound is interleaved, and LuaAV isn't.
//		MYFLT * csin = csound->GetSpin();
//		for (int i=0; i<ksmps; i++) {
//			const sample input1 = input_p1[i+offset];
//			const sample input2 = input_p1[i+offset];
//
//			csin[    i*nchnls] = input1 * scale;
//			csin[1 + i*nchnls] = input2 * scale;
//		}
//
//		/*
//		luaav_sample v1 = inbuffers[0][0];
//		luaav_sample v2 = csin[0];
//		printf("%f %f\n", v1, v2); // ok, got data!
//		*/
//
//		// run one ksmps of audio processing in csound
//		csound->PerformKsmps();
//
//		//convert csound interleaved audio back into LuaAV non-interleaved audio
//		MYFLT * csout = csound->GetSpout();
//		for (int i=0; i<ksmps; i++) {
//			sample& out1 = out_p1[i+offset];
//			sample& out2 = out_p2[i+offset];
//			const sample amp1 = amp_p1[i+offset];
//
//			out1 += csout[    i*nchnls] * inv_scale * amp1;
//			out2 += csout[1 + i*nchnls] * inv_scale * amp1;
//		}
}