void SDIF_FillGlobalHeader(SDIF_GlobalHeader *h) { assert(h != NULL); SDIF_Copy4Bytes(h->SDIF, "SDIF"); h->size = 8; h->SDIFversion = SDIF_SPEC_VERSION; h->SDIFStandardTypesVersion = SDIF_LIBRARY_VERSION; }
static int resolveBufferAndMatrixType(SDIFranges *x, t_symbol *matrixTypeSym, char *matrixType) { int i; if (x->t_bufferSym == 0) { object_post((t_object *)x, "SDIFranges: no SDIF buffer name specified"); return 0; } LookupMyBuffer(x); if (x->t_buffer == 0) { object_post((t_object *)x, "¥ SDIFranges: \"%s\" is not an SDIF buffer.", x->t_bufferSym->s_name); return 0; } if (matrixTypeSym->s_name[0] == '\0') { // Use "main matrix": the one whose type is the same as the frame type SDIFmem_Frame f; if((f = SDIFbuf_GetFirstFrame(x->t_buf)) == NULL) { object_post((t_object *)x, NAME ": SDIF-buffer %s is empty", x->t_bufferSym->s_name); return 0; } else { SDIF_Copy4Bytes(matrixType, f->header.frameType); } } else { // Look at user-supplied matrix type for (i = 1; i < 4; ++i) { if (matrixTypeSym->s_name[i] == '\0') { error(NAME ": error: maxcolumns' matrix type argument \"%s\" is less than 4 characters.", matrixTypeSym->s_name); return 0; } } SDIF_Copy4Bytes(matrixType, matrixTypeSym->s_name); if (matrixTypeSym->s_name[4] != '\0') { post("¥ " NAME ": warning: truncating maxcolumns' matrix type argument to \"%c%c%c%c\".", matrixType[0], matrixType[1], matrixType[2], matrixType[3]); } } return 1; }
static void SDIFlistpoke_matrixtype(SDIFlistpoke *x, t_symbol *matrixType) { if (matrixType == ps_emptysymbol) { x->t_mainMatrix = 1; } else { /* Here's where I could implement user matrix names that aren't just the 4 bytes. */ if (strlen(matrixType->s_name) != 4) { object_post((t_object *)x, "¥ SDIF-tuples: matrix %s is not 4 letters!", matrixType->s_name); return; } x->t_mainMatrix = 0; SDIF_Copy4Bytes(x->t_matrixType, matrixType->s_name); } }
SDIFmem_Matrix SDIFmem_CreateEmptyMatrix(void) { SDIFmem_Matrix result; result = (*my_malloc)(sizeof(*result)); if (result == NULL) { return NULL; } SDIF_Copy4Bytes(result->header.matrixType, "\0\0\0\0"); result->header.matrixDataType = SDIF_NO_TYPE; result->header.rowCount = result->header.columnCount = 0; result->data = 0; return result; }
static void SDIFlistpoke_listpoke(SDIFlistpoke *x, t_symbol *dummy, short argc, t_atom *argv) { int i; SDIFmem_Frame f; SDIFmem_Matrix m; float *mdata; char myFrameType[4]; char myMatrixType[4]; SDIFresult r; // post("* SDIFlistpoke_listpoke: x %p, argc %ld, argv %p", x, argc, argv); /* Check that arguments are all numbers */ for (i = 0; i < argc; ++i) { if (argv[i].a_type != A_FLOAT && argv[i].a_type != A_LONG) { object_post((t_object *)x, "¥ SDIF-listpoke: only numbers allowed in list."); return; } } /* Check that the number of arguments is a multiple of x->t_num_columns */ if (argc % x->t_num_columns != 0) { post("¥ SDIF-listpoke: %d element list doesn't go into %ld columns. Ignoring.", argc, x->t_num_columns); return; } /* Get the frame */ LookupMyBuffer(x); if (x->t_buffer == 0) { object_post((t_object *)x, "¥ SDIF-listpoke: no buffer!"); return; } // decide the frame type if(f = SDIFbuf_GetFirstFrame(x->t_buf)) SDIF_Copy4Bytes(myFrameType, f->header.frameType); else // we are about to create first frame in the buffer // (give it the same type as the matrix we are adding) SDIF_Copy4Bytes(myFrameType, x->t_matrixType); // decide the matrix type if (x->t_mainMatrix) { SDIF_Copy4Bytes(myMatrixType, myFrameType); } else { SDIF_Copy4Bytes(myMatrixType, x->t_matrixType); } /* post("** myMatrixType: %c%c%c%c", myMatrixType[0], myMatrixType[1], myMatrixType[2], myMatrixType[3]); */ f = (*(x->t_buffer->FrameLookup))(x->t_buffer, x->t_time, 0); if (f == 0) { /* There was no frame at the given time */ // post("** There was no frame at that time"); f = SDIFmem_CreateEmptyFrame(); if (f == 0) { object_post((t_object *)x, "¥ SDIF-listpoke: out of memory for new frame in SDIF-buffer!"); return; } SDIF_Copy4Bytes(f->header.frameType, myFrameType); f->header.time = x->t_time; f->header.streamID = x->t_buffer->streamID; i = (*(x->t_buffer->FrameInsert))(f, x->t_buffer); if (i) { object_post((t_object *)x, "¥ SDIF-listpoke: FrameInsert returned %d", i); } } else { /* There was already a frame at the given time */ for (m = f->matrices; m != 0; m = m->next) { if (SDIF_Char4Eq(myMatrixType, m->header.matrixType)) { post("SDIF-listpoke: deleting old matrix %c%c%c%c at time %f", m->header.matrixType[0], m->header.matrixType[1], m->header.matrixType[2], m->header.matrixType[3], x->t_time); r = SDIFmem_RemoveMatrix(f, m); if (r != ESDIF_SUCCESS) { object_post((t_object *)x, "¥ SDIF-listpoke: Problem removing matrix: %s", SDIF_GetErrorString(r)); } } } } /* Now we know f is a frame in x->t_buffer, at the right time, with no matrix of the type we want to write into, and that we have to call SDIFmem_RepairFrameHeader(f) */ m = SDIFmem_CreateEmptyMatrix(); if (m == 0) { object_post((t_object *)x, "¥ SDIF-listpoke: out of memory for new matrix in SDIF-buffer!"); SDIFmem_FreeFrame(f); return; } SDIF_Copy4Bytes(m->header.matrixType, myMatrixType); m->header.matrixDataType = SDIF_FLOAT32; m->header.columnCount = x->t_num_columns; m->header.rowCount = argc / x->t_num_columns; // We checked above that it divides evenly // post("** about to getbytes() for the matrix data"); m->data = getbytes(argc * sizeof(float)); if (m->data == 0) { object_post((t_object *)x, "¥ SDIF-listpoke: out of memory for matrix data in SDIF-buffer!"); SDIFmem_RemoveMatrix(f, m); SDIFmem_FreeMatrix(m); SDIFmem_RepairFrameHeader(f); return; } mdata = m->data; for (i = 0; i < argc; ++i) { mdata[i] = asfloat(argv[i]); } /* { SDIFmem_Matrix p; for (p = f->matrices; p != NULL; p = p->next) { post("Matrix: %p, type %c%c%c%c", p, p->header.matrixType[0], p->header.matrixType[1], p->header.matrixType[2], p->header.matrixType[3]); } } */ // post("** about to SDIFmem_AddMatrix"); SDIFmem_AddMatrix(f, m); // post("** about to SDIFmem_RepairFrameHeader"); SDIFmem_RepairFrameHeader(f); }
static void SDIFlistpoke_newmatrix(SDIFlistpoke *x, t_symbol *s, short argc, t_atom *argv) { sdif_float64 time, oldtime; int numrows, numcols, oldnumcols, oldmainmatrix; char oldmatrixtype[4]; char *type; if (argc < 5) { badargs: object_post((t_object *)x, "¥ SDIF-listpoke: newmatrix args: frametime, matrixtype, #rows, #cols, data..."); return; } if (argv[0].a_type == A_SYM) { object_post((t_object *)x, "¥ SDIF-listpoke: newmatrix: frame time must be a number"); return; } time = asfloat(argv[0]); if (argv[1].a_type != A_SYM ) { object_post((t_object *)x, "¥ SDIF-listpoke: newmatrix: matrix type must be a symbol"); return; } type = argv[1].a_w.w_sym->s_name; if (type[0] == '\0' || type[1] == '\0' || type[2] == '\0' || type[3] == '\0' || type[4] != '\0') { object_post((t_object *)x, "¥ SDIF-listpoke: newmatrix: illegal type \"%s\" is not 4 characters.", type); return; } if (argv[2].a_type != A_LONG) { object_post((t_object *)x, "¥ SDIF-listpoke: newmatrix: #rows must be an int."); return; } numrows = argv[2].a_w.w_long; if (numrows <= 0) { object_post((t_object *)x, "¥ SDIF-listpoke: newmatrix: #rows must be >= 1"); return; } if (argv[3].a_type != A_LONG) { object_post((t_object *)x, "¥ SDIF-listpoke: newmatrix: #columns must be an int."); return; } numcols = argv[3].a_w.w_long; if (numcols <= 0) { object_post((t_object *)x, "¥ SDIF-listpoke: newmatrix: #columns must be >= 1"); return; } if (numrows*numcols != argc-4) { post("¥ SDIF-listpoke: newmatrix: %ld rows times %ld columns is %ld,", numrows, numcols, numrows*numcols); object_post((t_object *)x, " but there are %ld elements of matrix data. Dropping.", argc-4); return; } /* Store old instance variables */ oldtime = x->t_time; oldnumcols = x->t_num_columns; oldmainmatrix = x->t_mainMatrix; SDIF_Copy4Bytes(oldmatrixtype, x->t_matrixType); /*temporarily overwrite them */ x->t_time = time; x->t_num_columns = numcols; x->t_mainMatrix = 0; SDIF_Copy4Bytes(x->t_matrixType, type); /* Store the new matrix via listpoke */ SDIFlistpoke_listpoke(x, s, argc-4, argv+4); /* Restore instance variables */ x->t_time = oldtime; x->t_num_columns = oldnumcols; x->t_mainMatrix = oldmainmatrix; SDIF_Copy4Bytes(x->t_matrixType, oldmatrixtype); }
void do_scan(t_sdif_fileinfo *x, FILE *f, char *name) { SDIFresult r; SDIF_FrameHeader fh; int result, i, sawStreamAlready, needToSkip; char frameTypeBuffer[5]; x->x_ns = 0; while ((r = SDIF_ReadFrameHeader(&fh, f)) == ESDIF_SUCCESS) { /* post("** Read frame header: ID %d, time %g, type %c%c%c%c", fh.streamID, fh.time, fh.frameType[0], fh.frameType[1], fh.frameType[2], fh.frameType[3]); */ needToSkip = 1; if (x->print_NVT_matrices) { if (SDIF_Char4Eq(fh.frameType, "1NVT")) { needToSkip = 0; // Will read the matrices in this frame rather than skipping it if (Read1NVTFrame(x, f, name, &fh) == 0) return; } } sawStreamAlready = 0; for (i = 0; i < x->x_ns; ++i) { if (x->x_streamID[i] == fh.streamID) { sawStreamAlready = 1; // Already saw this stream, so just make sure type is OK if (!SDIF_Char4Eq(fh.frameType, x->x_frameType[i])) { object_post((t_object *)x, "¥ streamlist: Warning: First frame for stream %ld", fh.streamID); post("¥ had type %c%c%c%c, but frame at time %g has type %c%c%c%c", x->x_frameType[i][0], x->x_frameType[i][1], x->x_frameType[i][2], x->x_frameType[i][3], fh.time, fh.frameType[0], fh.frameType[1], fh.frameType[2], fh.frameType[3]); } break; } } if (!sawStreamAlready) { if (x->x_ns >= MAX_STREAMS) { object_error((t_object *)x, NAME ": SDIF file has more than %ld streams!", MAX_STREAMS); return; } ++(x->x_ns); x->x_streamID[i] = fh.streamID; SDIF_Copy4Bytes(x->x_frameType[i], fh.frameType); SDIF_Copy4Bytes(frameTypeBuffer, fh.frameType); frameTypeBuffer[4] = '\0'; x->x_frameTypeSymbol[i] = gensym(frameTypeBuffer); x->x_starttime[i] = fh.time; x->x_numframes[i] = 0; } x->x_endtime[i] = fh.time; ++(x->x_numframes[i]); if (needToSkip) { if (r = SDIF_SkipFrame(&fh, f)) { object_post((t_object *)x, NAME ": error skipping frame in SDIF file %s:", name); object_post((t_object *)x, " %s", SDIF_GetErrorString(r)); return; } } } if (r != ESDIF_END_OF_DATA) { object_post((t_object *)x, NAME ": error reading SDIF file %s:", name); object_post((t_object *)x, "%s", SDIF_GetErrorString(r)); } outlet_bang(x->outlet2); return; }