/*JSON{ "type":"constructor", "class": "Waveform",  "name": "Waveform", "ifndef" : "SAVE_ON_FLASH",
         "description" : [ "Create a waveform class. This allows high speed input and output of waveforms. It has an internal variable called `buffer` (as well as `buffer2` when double-buffered - see `options` below) which contains the data to input/output.",
                           "When double-buffered, a 'buffer' event will be emitted each time a buffer is finished with (the argument is that buffer). When the recording stops, a 'finish' event will be emitted (with the first argument as the buffer)." ],
         "generate" : "jswrap_waveform_constructor",
         "params" : [ [ "samples", "int32", "The number of samples" ],
                      [ "options", "JsVar", "Optional options struct `{doubleBuffer:bool, bits : 8/16}` where: `doubleBuffer` is whether to allocate two buffers or not (default false), and bits is the amount of bits to use (default 8)." ] ],
         "return" : [ "JsVar", "An Waveform object" ]

}*/
JsVar *jswrap_waveform_constructor(int samples, JsVar *options) {
  if (samples<=0) {
    jsExceptionHere(JSET_ERROR, "Samples must be greater than 0");
    return 0;
  }

  bool doubleBuffer = false;
  bool use16bit = false;
  if (jsvIsObject(options)) {
    doubleBuffer = jsvGetBoolAndUnLock(jsvObjectGetChild(options, "doubleBuffer", 0));

    int bits = (int)jsvGetIntegerAndUnLock(jsvObjectGetChild(options, "bits", 0));
    if (bits!=0 && bits!=8 && bits!=16) {
      jsExceptionHere(JSET_ERROR, "Invalid number of bits");
      return 0;
    } else if (bits==16) use16bit = true;

  } else if (!jsvIsUndefined(options)) {
    jsExceptionHere(JSET_ERROR, "Expecting options to be undefined or an Object, not %t", options);
  }

  JsVar *arrayLength = jsvNewFromInteger(samples);
  JsVarDataArrayBufferViewType bufferType = use16bit ? ARRAYBUFFERVIEW_UINT16 : ARRAYBUFFERVIEW_UINT8;
  JsVar *arrayBuffer = jswrap_typedarray_constructor(bufferType, arrayLength, 0, 0);
  JsVar *arrayBuffer2 = 0;
  if (doubleBuffer) arrayBuffer2 = jswrap_typedarray_constructor(bufferType, arrayLength, 0, 0);
  jsvUnLock(arrayLength);
  JsVar *waveform = jspNewObject(0, "Waveform");


  if (!waveform || !arrayBuffer || (doubleBuffer && !arrayBuffer2)) {
    jsvUnLock(waveform);
    jsvUnLock(arrayBuffer); // out of memory
    jsvUnLock(arrayBuffer2);
    return 0;
  }
  jsvUnLock(jsvObjectSetChild(waveform, "buffer", arrayBuffer));
  if (arrayBuffer2) jsvUnLock(jsvObjectSetChild(waveform, "buffer2", arrayBuffer2));

  return waveform;
}
Beispiel #2
0
/*JSON{
  "type" : "method",
  "class" : "ArrayBufferView",
  "name" : "map",
  "generate" : "jswrap_arraybufferview_map",
  "params" : [
    ["function","JsVar","Function used to map one item to another"],
    ["thisArg","JsVar","if specified, the function is called with 'this' set to thisArg (optional)"]
  ],
  "return" : ["JsVar","An array containing the results"],
  "return_object" : "ArrayBufferView"
}
Return an array which is made from the following: ```A.map(function) = [function(A[0]), function(A[1]), ...]```

**Note:** This returns an ArrayBuffer of the same type it was called on. To get an Array, use `Array.prototype.map`
*/
JsVar *jswrap_arraybufferview_map(JsVar *parent, JsVar *funcVar, JsVar *thisVar) {
  if (!jsvIsArrayBuffer(parent)) {
    jsExceptionHere(JSET_ERROR, "ArrayBufferView.map can only be called on an ArrayBufferView");
    return 0;
  }
  if (!jsvIsFunction(funcVar)) {
    jsExceptionHere(JSET_ERROR, "ArrayBufferView.map's first argument should be a function");
    return 0;
  }
  if (!jsvIsUndefined(thisVar) && !jsvIsObject(thisVar)) {
    jsExceptionHere(JSET_ERROR, "ArrayBufferView.map's second argument should be undefined, or an object");
    return 0;
  }

  // create ArrayBuffer result
  JsVarDataArrayBufferViewType arrayBufferType = parent->varData.arraybuffer.type;
  JsVar *arrayBufferLength = jsvNewFromInteger((JsVarInt)jsvGetArrayBufferLength(parent));
  JsVar *array = jswrap_typedarray_constructor(arrayBufferType, arrayBufferLength, 0, 0);
  jsvUnLock(arrayBufferLength);
  if (!array) return 0;

  // now iterate
  JsvIterator it; // TODO: if we really are limited to ArrayBuffers, this could be an ArrayBufferIterator.
  jsvIteratorNew(&it, parent);
  JsvArrayBufferIterator itdst;
  jsvArrayBufferIteratorNew(&itdst, array, 0);

  while (jsvIteratorHasElement(&it)) {
    JsVar *index = jsvIteratorGetKey(&it);
    if (jsvIsInt(index)) {
      JsVarInt idxValue = jsvGetInteger(index);

      JsVar *args[3], *mapped;
      args[0] = jsvIteratorGetValue(&it);
      args[1] = jsvNewFromInteger(idxValue); // child is a variable name, create a new variable for the index
      args[2] = parent;
      mapped = jspeFunctionCall(funcVar, 0, thisVar, false, 3, args);
      jsvUnLock(args[0]);
      jsvUnLock(args[1]);
      if (mapped) {
        jsvArrayBufferIteratorSetValue(&itdst, mapped);
        jsvUnLock(mapped);
      }
    }
    jsvUnLock(index);
    jsvIteratorNext(&it);
    jsvArrayBufferIteratorNext(&itdst);
  }
  jsvIteratorFree(&it);
  jsvArrayBufferIteratorFree(&itdst);

  return array;
}
void bytePortInit(JsVar *parent,JsBytePort *bp){
  int i,j,value;
  uint32_t mask;
  JsVar *buf = jswrap_typedarray_constructor(ARRAYBUFFERVIEW_UINT32, jsvNewFromInteger(256),0,0);
  uint32_t *maskPnt = (uint32_t *)jswrap_espruino_getAddressOf(buf,true);
  for(int i = 0; i < 256;i++){
    mask = 0;
	value = i;
    for(j = 0; j < jswrap_byteport_pins; j++){
	  if((value & 1)>0) mask += bp->data.mask[j];
      value = value>>1;
    }
    maskPnt[i] = mask;	
  }
  jsvObjectSetChild(parent,"PortMask",buf);
  jsvUnLock(buf);  
}