bool WaveTrack::InitBlock(WaveBlock * b) { wxASSERT(b); BlockFile *f = b->f; if (!f->OpenWriting()) return false; f->Write(headerTag, headerTagLen); /* * This code shouldn't be needed because UpdateSummaries * always writes exactly what's needed. sampleCount slen = summary64KLen + summary256Len; sampleType *tempSamples = new sampleType[slen]; for(int i=0; i<slen; i++) tempSamples[i] = 0; f->Write((void *)tempSamples, sizeof(sampleType) * slen); delete[] tempSamples; */ f->Close(); return true; }
void WaveTrack::CopyWrite(sampleType * buffer, WaveBlock * b, sampleCount start, sampleCount len) { // Usually we don't write to an existing block; to support Undo, // we copy the old block entirely into memory, dereference it, // make the change, and then write the new block to disk. wxASSERT(b); wxASSERT(b->len <= maxSamples); wxASSERT(start + len <= b->len); dirty++; // forces redraw sampleType *newBuffer = 0; newBuffer = new sampleType[maxSamples]; wxASSERT(newBuffer); Read(newBuffer, b, 0, b->len); for (int i = 0; i < len; i++) newBuffer[start + i] = buffer[i]; BlockFile *oldBlockFile = b->f; b->f = dirManager->NewBlockFile(); bool inited = InitBlock(b); wxASSERT(inited); buffer = newBuffer; start = 0; len = b->len; dirManager->Deref(oldBlockFile); // Write the block BlockFile *f = b->f; wxASSERT(f); bool opened = f->OpenWriting(); wxASSERT(opened); f->SeekTo(totalHeaderLen + (start * sizeof(sampleType))); f->Write((void *) buffer, len * sizeof(sampleType)); UpdateSummaries(buffer, b, len); if (newBuffer) delete[]newBuffer; f->Close(); }
void WaveTrack::FirstWrite(sampleType * buffer, WaveBlock * b, sampleCount len) { wxASSERT(b); wxASSERT(b->len <= maxSamples); dirty++; // forces redraw BlockFile *f = b->f; wxASSERT(f); bool opened = f->OpenWriting(); wxASSERT(opened); f->SeekTo(totalHeaderLen); f->Write((void *) buffer, len * sizeof(sampleType)); UpdateSummaries(buffer, b, len); f->Close(); }
void WaveTrack::UpdateSummaries(sampleType * buffer, WaveBlock * b, sampleCount len) { // This method assumes that b->f is already opened BlockFile *f = b->f; sampleType *summary64K = new sampleType[summary64KLen]; sampleType *summary256 = new sampleType[summary256Len]; sampleCount sumLen; sampleCount i, j, jcount; sampleType min, max; // Recalc 256 summaries sumLen = (len + 255) / 256; for (i = 0; i < sumLen; i++) { min = buffer[i * 256]; max = buffer[i * 256]; jcount = 256; if (i * 256 + jcount > len) jcount = len - i * 256; for (j = 1; j < jcount; j++) { if (buffer[i * 256 + j] < min) min = buffer[i * 256 + j]; else if (buffer[i * 256 + j] > max) max = buffer[i * 256 + j]; } summary256[i * 2] = min; summary256[i * 2 + 1] = max; } for (i = sumLen; i < summary256Len / 2; i++) { summary256[i * 2] = 0; summary256[i * 2 + 1] = 0; } // Recalc 64K summaries sumLen = (len + 65535) / 65536; for (i = 0; i < sumLen; i++) { min = summary256[2 * i * 256]; max = summary256[2 * i * 256 + 1]; for (j = 1; j < 256; j++) { if (summary256[2 * (i * 256 + j)] < min) min = summary256[2 * (i * 256 + j)]; if (summary256[2 * (i * 256 + j) + 1] > max) max = summary256[2 * (i * 256 + j) + 1]; } summary64K[i * 2] = min; summary64K[i * 2 + 1] = max; } for (i = sumLen; i < summary64KLen / 2; i++) { summary256[i * 2] = 0; summary256[i * 2 + 1] = 0; } // Recalc block-level summary min = summary64K[0]; max = summary64K[1]; for (i = 1; i < sumLen; i++) { if (summary64K[2*i] < min) min = summary64K[2*i]; else if (summary64K[2*i+1] > max) max = summary64K[2*i+1]; } b->min = min; b->max = max; // Write 256 and 64K summaries to disk f->SeekTo(headerTagLen); f->Write((void *) summary64K, summary64KLen * sizeof(sampleType)); f->Write((void *) summary256, summary256Len * sizeof(sampleType)); delete[]summary64K; delete[]summary256; }