min[c] = (d[k + c] < min[c]) ? d[k + c] : min[c]; } bool ok = ng_gl2_set(section, B + ((NGRenderer*)renderer)->mmidx_max[mm_level] + ((int)TEX_BORDER_HI) + i, short_to_char(max[c])); if(!ok) gerr("max b=%i i=%i p=%i %i size=%i", _b, i, p, B + ((NGRenderer*)renderer)->mmidx_max[mm_level] + i, section->buffer_size); g_return_if_fail(ok); ok = ng_gl2_set(section, B + ((NGRenderer*)renderer)->mmidx_min[mm_level] + ((int)TEX_BORDER_HI) + i, short_to_char(-min[c])); if(!ok) gerr("min b=%i i=%i p=%i %i size=%i mm=%i", _b, i, p, b * block_size + ((NGRenderer*)renderer)->mmidx_min[mm_level] + i, section->buffer_size, ((NGRenderer*)renderer)->mmidx_min[mm_level]); g_return_if_fail(ok); } other_lods(renderer, section, B); } } int n_chans = waveform_get_n_channels(waveform); HiResNGWaveform** data = (HiResNGWaveform**)&w->render_data[renderer->mode]; #ifdef NG_HASHTABLE #if WF_DEBUG { HiResNGWaveform* data1 = g_hash_table_lookup(((NGRenderer*)renderer)->ng_data, waveform); if((*data) != data1) gwarn("%i: wav=%p hash=%p %s", b, *data, data1, modes[renderer->mode].name); g_return_if_fail((*data) == data1); } #endif #endif if(!*data){ int n_sections = waveform_get_n_audio_blocks(waveform) / MAX_BLOCKS_PER_TEXTURE + (waveform_get_n_audio_blocks(waveform) % MAX_BLOCKS_PER_TEXTURE ? 1 : 0); *(*data = g_malloc0(sizeof(HiResNGWaveform) + sizeof(Section) * n_sections)) = (HiResNGWaveform){
/* * Load a single audio block for the case where the audio is on a local filesystem. * For thread-safety, the Waveform is not modified. */ gboolean waveform_load_audio_block(Waveform* waveform, WfBuf16* buf16, int block_num) { //TODO handle split stereo files g_return_val_if_fail(waveform, false); // which parts of the audio file are present? // tier 1: 0, 128 // tier 2: 0, 64, 128, 196 // tier 3: 0, 32, 64, 96, 128, ... 196 // tier 4: 0, 16, ... // tier 5: 0, 8, ... // tier 6: 0, 4, ... // tier 7: 0, 2, ... // tier 8: 0, 1, ... //guint n_peaks = ((n_frames * 1 ) / WF_PEAK_RATIO) << audio->n_tiers_present; //int spacing = WF_PEAK_RATIO >> (audio->n_tiers_present - 1); uint64_t start_pos = block_num * (WF_PEAK_BLOCK_SIZE - 2.0 * TEX_BORDER * 256.0); uint64_t end_pos = start_pos + WF_PEAK_BLOCK_SIZE; int n_chans = waveform_get_n_channels(waveform); g_return_val_if_fail(n_chans, false); SF_INFO sfinfo; SNDFILE* sffile; sfinfo.format = 0; if(!(sffile = sf_open(waveform->filename, SFM_READ, &sfinfo))){ gwarn ("not able to open input file %s.", waveform->filename); puts(sf_strerror(NULL)); return false; } if(start_pos > sfinfo.frames){ gerr("startpos too high. %Li > %Li block=%i", start_pos, sfinfo.frames, block_num); return false; } if(end_pos > sfinfo.frames){ dbg(1, "*** last block: end_pos=%Lu max=%Lu", end_pos, sfinfo.frames); end_pos = sfinfo.frames; } sf_seek(sffile, start_pos, SEEK_SET); dbg(1, "block=%s%i%s (%i/%i) start=%Li end=%Li", wf_bold, block_num, wf_white, block_num+1, waveform_get_n_audio_blocks(waveform), start_pos, end_pos); sf_count_t n_frames = MIN(buf16->size, end_pos - start_pos); //1st of these isnt needed? g_return_val_if_fail(buf16 && buf16->buf[WF_LEFT], false); #ifdef WF_DEBUG buf16->start_frame = start_pos; #endif gboolean sf_read_float_to_short(SNDFILE* sffile, WfBuf16* buf, int ch, sf_count_t n_frames) { float readbuf[buf->size]; sf_count_t readcount; if((readcount = sf_readf_float(sffile, readbuf, n_frames)) < n_frames){ gwarn("unexpected EOF: %s", waveform->filename); gwarn(" start_frame=%Li n_frames=%Lu/%Lu read=%Li", start_pos, n_frames, sfinfo.frames, readcount); return false; } //convert to short int j; for(j=0;j<readcount;j++){ buf->buf[ch][j] = readbuf[j] * (1 << 15); } return true; }