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::Read64K(sampleType * buffer, WaveBlock * b, sampleCount start, sampleCount len) { wxASSERT(b); wxASSERT(start >= 0); wxASSERT(start + len <= ((b->len + 65535) / 65536)); start *= 2; len *= 2; BlockFile *f = b->f; bool opened = f->OpenReadHeader(); wxASSERT(opened); f->SeekTo(headerTagLen + start * sizeof(sampleType)); int result = f->Read((void *) buffer, (int) (len * sizeof(sampleType))); wxASSERT(result == (int) (len * sizeof(sampleType))); 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::Read(sampleType * buffer, WaveBlock * b, sampleCount start, sampleCount len) { wxASSERT(b); wxASSERT(start >= 0); wxASSERT(start + len <= b->len); BlockFile *f = b->f; bool opened = f->OpenReadData(); wxASSERT(opened); f->SeekTo(totalHeaderLen + (start * sizeof(sampleType))); int result = f->Read((void *) buffer, (int) (len * sizeof(sampleType))); if (result != (int) (len * sizeof(sampleType))) { printf("Expected to read %d bytes, got %d bytes.\n", len * sizeof(sampleType), result); } wxASSERT(result == (int) (len * sizeof(sampleType))); 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; }