/*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; }
/*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); }