void test_push_mode_forever(FILE *g, char *filename) { int p,q, len, error, used; uint8 *data = stb_file(filename, &len); stb_vorbis *v; if (!data) stb_fatal("Couldn't open {%s}", filename); p = 0; q = 1; retry: v = stb_vorbis_open_pushdata(data, q, &used, &error, NULL); if (v == NULL) { if (error == VORBIS_need_more_data) { q += 1; goto retry; } printf("Error %d\n", error); exit(1); } p += used; show_info(v); for(;;) { int k=0; int n; float *left, *right; float **outputs; int num_c; q = 32; retry3: if (q > len-p) q = len-p; used = stb_vorbis_decode_frame_pushdata(v, data+p, q, &num_c, &outputs, &n); if (used == 0) { if (p+q == len) { // seek randomly when at end... this makes sense when listening to it, but dumb when writing to file p = stb_rand(); if (p < 0) p = -p; p %= (len - 8000); stb_vorbis_flush_pushdata(v); q = 128; goto retry3; } if (q < 128) q = 128; q *= 2; goto retry3; } p += used; if (n == 0) continue; left = outputs[0]; right = num_c > 1 ? outputs[1] : outputs[0]; write_floats(g, n, left, right); } stb_vorbis_close(v); }
// in push mode, you can load your data any way you want, then // feed it a little bit at a time. this is the preferred way to // handle reading from a packed file or some custom stream format; // instead of putting callbacks inside stb_vorbis, you just keep // a little buffer (it needs to be big enough for one packet of // audio, except at the beginning where you need to buffer up the // entire header). // // for this test, I just load all the data and just lie to stb_vorbis // and claim I only have a little of it void test_decode_frame_pushdata(FILE *g, char *filename) { int p,q, len, error, used; stb_vorbis *v; uint8 *data = stb_file(filename, &len); if (!data) stb_fatal("Couldn't open {%s}", filename); p = 0; q = 1; retry: v = stb_vorbis_open_pushdata(data, q, &used, &error, NULL); if (v == NULL) { if (error == VORBIS_need_more_data) { q += 1; goto retry; } fprintf(stderr, "Error %d\n", error); exit(1); } p += used; show_info(v); for(;;) { int k=0; int n; float *left, *right; uint32 next_t=0; float **outputs; int num_c; q = 32; retry3: if (q > len-p) q = len-p; used = stb_vorbis_decode_frame_pushdata(v, data+p, q, &num_c, &outputs, &n); if (used == 0) { if (p+q == len) break; // no more data, stop if (q < 128) q = 128; q *= 2; goto retry3; } p += used; if (n == 0) continue; // seek/error recovery left = outputs[0]; right = num_c > 1 ? outputs[1] : outputs[0]; write_floats(g, n, left, right); } stb_vorbis_close(v); }
void begin(void) { int i; FloatBuffer fb1, fb2, fb3, fb4; LPFData lpf_data; EqualizerData eq_data; fb1.rpos = fb1.rlen = 0; fb2.rpos = fb2.rlen = 0; fb3.rpos = fb3.rlen = 0; fb4.rpos = fb4.rlen = 0; init_lpf_data(&lpf_data, CUTOFF_FREQUENCY, NUM_TAPS, DECIMATION); init_equalizer(&eq_data); /* Startup: */ get_floats(&fb1); /* LPF needs at least NUM_TAPS+1 inputs; get_floats is fine. */ run_lpf(&fb1, &fb2, &lpf_data); /* run_demod needs 1 input, OK here. */ /* run_equalizer needs 51 inputs (same reason as for LPF). This means * running the pipeline up to demod 50 times in advance: */ for (i = 0; i < 64; i++) { if (fb1.rlen - fb1.rpos < NUM_TAPS + 1) get_floats(&fb1); run_lpf(&fb1, &fb2, &lpf_data); run_demod(&fb2, &fb3); } /* Main loop: */ while (numiters == -1 || numiters-- > 0) { /* The low-pass filter will need NUM_TAPS+1 items; read them if we * need to. */ if (fb1.rlen - fb1.rpos < NUM_TAPS + 1) get_floats(&fb1); run_lpf(&fb1, &fb2, &lpf_data); run_demod(&fb2, &fb3); run_equalizer(&fb3, &fb4, &eq_data); write_floats(&fb4); } }
void test_get_frame_float(FILE *g, char *filename) { int error; stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL); if (!v) stb_fatal("Couldn't open {%s}", filename); show_info(v); for(;;) { int n; float *left, *right; float **outputs; int num_c; n = stb_vorbis_get_frame_float(v, &num_c, &outputs); if (n == 0) break; left = outputs[0]; right = outputs[num_c > 1]; write_floats(g, n, left, right); } stb_vorbis_close(v); }
int main (int argc, char *argv[]) { int i, n, ib, nb, nz, nv, celldim, phydim; int nn, type, *elems = 0, idata[5]; cgsize_t ne; char *p, basename[33], title[65]; float value, *var; SOLUTION *sol; FILE *fp; if (argc < 2) print_usage (usgmsg, NULL); ib = 0; basename[0] = 0; while ((n = getargs (argc, argv, options)) > 0) { switch (n) { case 'a': ascii = 1; break; case 'b': ib = atoi (argarg); break; case 'B': strncpy (basename, argarg, 32); basename[32] = 0; break; case 'w': weighting = 1; break; case 'S': usesol = atoi (argarg); break; } } if (argind > argc - 2) print_usage (usgmsg, "CGNSfile and/or Tecplotfile not given"); if (!file_exists (argv[argind])) FATAL (NULL, "CGNSfile does not exist or is not a file"); /* open CGNS file */ printf ("reading CGNS file from %s\n", argv[argind]); nb = open_cgns (argv[argind], 1); if (!nb) FATAL (NULL, "no bases found in CGNS file"); if (*basename && 0 == (ib = find_base (basename))) FATAL (NULL, "specified base not found"); if (ib > nb) FATAL (NULL, "base index out of range"); cgnsbase = ib ? ib : 1; if (cg_base_read (cgnsfn, cgnsbase, basename, &celldim, &phydim)) FATAL (NULL, NULL); if (celldim != 3 || phydim != 3) FATAL (NULL, "cell and physical dimension must be 3"); printf (" using base %d - %s\n", cgnsbase, basename); if (NULL == (p = strrchr (argv[argind], '/')) && NULL == (p = strrchr (argv[argind], '\\'))) strncpy (title, argv[argind], sizeof(title)); else strncpy (title, ++p, sizeof(title)); title[sizeof(title)-1] = 0; if ((p = strrchr (title, '.')) != NULL) *p = 0; read_zones (); if (!nZones) FATAL (NULL, "no zones in the CGNS file"); /* verify dimensions fit in an integer */ for (nz = 0; nz < nZones; nz++) { if (Zones[nz].nverts > CG_MAX_INT32) FATAL(NULL, "zone size too large to write with integers"); if (Zones[nz].type == CGNS_ENUMV(Unstructured)) { count_elements (nz, &ne, &type); if (ne > CG_MAX_INT32) FATAL(NULL, "too many elements to write with integers"); } } nv = 3 + check_solution (); /* open Tecplot file */ printf ("writing %s Tecplot data to <%s>\n", ascii ? "ASCII" : "binary", argv[++argind]); if (NULL == (fp = fopen (argv[argind], ascii ? "w+" : "w+b"))) FATAL (NULL, "couldn't open Tecplot output file"); /* write file header */ if (ascii) fprintf (fp, "TITLE = \"%s\"\n", title); else { fwrite ("#!TDV75 ", 1, 8, fp); i = 1; write_ints (fp, 1, &i); write_string (fp, title); } /* write variables */ if (ascii) { fprintf (fp, "VARIABLES = \"X\", \"Y\", \"Z\""); if (usesol) { sol = Zones->sols; for (n = 0; n < sol->nflds; n++) fprintf (fp, ",\n\"%s\"", sol->flds[n].name); } } else { write_ints (fp, 1, &nv); write_string (fp, "X"); write_string (fp, "Y"); write_string (fp, "Z"); if (usesol) { sol = Zones->sols; for (n = 0; n < sol->nflds; n++) write_string (fp, sol->flds[n].name); } } /* write zones */ if (!ascii) { for (nz = 0; nz < nZones; nz++) { if (Zones[nz].type == CGNS_ENUMV(Structured)) { idata[0] = 0; /* BLOCK */ idata[1] = -1; /* color not specified */ idata[2] = (int)Zones[nz].dim[0]; idata[3] = (int)Zones[nz].dim[1]; idata[4] = (int)Zones[nz].dim[2]; } else { count_elements (nz, &ne, &type); idata[0] = 2; /* FEBLOCK */ idata[1] = -1; /* color not specified */ idata[2] = (int)Zones[nz].dim[0]; idata[3] = (int)ne; idata[4] = type; } value = 299.0; write_floats (fp, 1, &value); write_string (fp, Zones[nz].name); write_ints (fp, 5, idata); } value = 357.0; write_floats (fp, 1, &value); } for (nz = 0; nz < nZones; nz++) { printf (" zone %d...", nz+1); fflush (stdout); read_zone_grid (nz+1); ne = 0; type = 2; nn = (int)Zones[nz].nverts; var = (float *) malloc (nn * sizeof(float)); if (NULL == var) FATAL (NULL, "malloc failed for temp float array"); if (Zones[nz].type == CGNS_ENUMV(Unstructured)) elems = volume_elements (nz, &ne, &type); if (ascii) { if (Zones[nz].type == CGNS_ENUMV(Structured)) fprintf (fp, "\nZONE T=\"%s\", I=%d, J=%d, K=%d, F=BLOCK\n", Zones[nz].name, (int)Zones[nz].dim[0], (int)Zones[nz].dim[1], (int)Zones[nz].dim[2]); else fprintf (fp, "\nZONE T=\"%s\", N=%d, E=%d, F=FEBLOCK, ET=%s\n", Zones[nz].name, nn, (int)ne, type == 2 ? "TETRAHEDRON" : "BRICK"); } else { value = 299.0; write_floats (fp, 1, &value); i = 0; write_ints (fp, 1, &i); i = 1; for (n = 0; n < nv; n++) write_ints (fp, 1, &i); } for (n = 0; n < nn; n++) var[n] = (float)Zones[nz].verts[n].x; write_floats (fp, nn, var); for (n = 0; n < nn; n++) var[n] = (float)Zones[nz].verts[n].y; write_floats (fp, nn, var); for (n = 0; n < nn; n++) var[n] = (float)Zones[nz].verts[n].z; write_floats (fp, nn, var); if (usesol) { read_solution_field (nz+1, usesol, 0); sol = &Zones[nz].sols[usesol-1]; if (sol->location != CGNS_ENUMV(Vertex)) cell_vertex_solution (nz+1, usesol, weighting); for (nv = 0; nv < sol->nflds; nv++) { for (n = 0; n < nn; n++) var[n] = (float)sol->flds[nv].data[n]; write_floats (fp, nn, var); } } free (var); if (Zones[nz].type == CGNS_ENUMV(Unstructured)) { if (!ascii) { i = 0; write_ints (fp, 1, &i); } nn = 1 << type; for (i = 0, n = 0; n < ne; n++, i += nn) write_ints (fp, nn, &elems[i]); free (elems); } puts ("done"); } fclose (fp); cg_close (cgnsfn); return 0; }