Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

o Fix Flac header manually. Luckily the streamheader is a fixed

  position format.
   - if SNDFILE is writing it, add number of frames.
   - if we copy the header from the original, change the blocksizes
     to what sndfile is writing - otherwise the file is invalid.
  • Loading branch information...
commit a85bebb2d0ec732287b9b545926ab576a00b5086 1 parent 8f1db86
@hzeller authored
Showing with 37 additions and 10 deletions.
  1. +5 −0 conversion-buffer.cc
  2. +4 −0 conversion-buffer.h
  3. +28 −10 convolver.cc
View
5 conversion-buffer.cc
@@ -92,6 +92,11 @@ ssize_t ConversionBuffer::Append(const void *data, size_t count) {
return count;
}
+void ConversionBuffer::WriteCharAt(unsigned char c, off_t offset) {
+ if (tmpfile_ < 0) return;
+ if (pwrite(tmpfile_, &c, 1, offset) != 1) fprintf(stderr, "mmh");
+}
+
ssize_t ConversionBuffer::SndAppend(const void *data, size_t count) {
if (!snd_writing_enabled_) return count;
return Append(data, count);
View
4 conversion-buffer.h
@@ -58,6 +58,10 @@ class ConversionBuffer {
// but can be used to write raw data as well.
ssize_t Append(const void *data, size_t count);
+ // Write at a particular position. Writes a single character - this is
+ // used for chirurgical editing...
+ void WriteCharAt(unsigned char c, off_t offset);
+
// Enable writing through the SNDFILE.
// If set to 'false', writes via the SNDFILE are ignored.
// To be used to suppress writing of the header or
View
38 convolver.cc
@@ -196,14 +196,9 @@ class SndFileFilter :
out_info.format = SF_FORMAT_FLAC;
out_info.format |= SF_FORMAT_PCM_16;
}
- else if ((in_info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV
- && (in_info.format & SF_FORMAT_SUBMASK) != SF_FORMAT_PCM_16) {
- // WAV format seems to create garbage when we attempt to output PCM_24
- // Output float for now; still mplayer seems to trip about length.
- // Probably the header is incomplete. Investigate.
- out_info.format = SF_FORMAT_WAV;
- out_info.format |= SF_FORMAT_FLOAT;
- out_info.format |= SF_ENDIAN_CPU;
+ else if ((in_info.format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV) {
+ out_info.format = SF_FORMAT_FLAC; // recode as flac.
+ out_info.format |= SF_FORMAT_PCM_24;
}
else { // original format.
out_info.format = in_info.format;
@@ -233,9 +228,32 @@ class SndFileFilter :
// sure that the sndfile-header is flushed into the nirwana before we
// re-enable sndfile_writes.
sf_command(snd_out_, SFC_UPDATE_HEADER_NOW, NULL, 0);
- fprintf(stderr, "Header init done.\n");
+
+ // -- time for some hackery ...
+ // If we have copied the header over from the original, we need to
+ // redact the values for min/max blocksize and min/max framesize with
+ // what SNDFILE is going to use, otherwise programs will trip over this.
+ // http://flac.sourceforge.net/format.html
+ if (copy_flac_header_) {
+ out_buffer->WriteCharAt((1152 & 0xFF00) >> 8, 8);
+ out_buffer->WriteCharAt((1152 & 0x00FF) , 9);
+ out_buffer->WriteCharAt((1152 & 0xFF00) >> 8, 10);
+ out_buffer->WriteCharAt((1152 & 0x00FF) , 11);
+ for (int i = 12; i < 18; ++i) out_buffer->WriteCharAt(0, i);
+ } else {
+ // .. and if SNDFILE writes the header, it misses out in writing the
+ // number of samples to be expected. So let's fill that in.
+ // The MD5 sum starts at position strlen("fLaC") + 4 + 18 = 26
+ // The 32 bits before that are the samples (and another 4 bit before that,
+ // ignoring that for now).
+ out_buffer->WriteCharAt((total_frames_ & 0xFF000000) >> 24, 22);
+ out_buffer->WriteCharAt((total_frames_ & 0x00FF0000) >> 16, 23);
+ out_buffer->WriteCharAt((total_frames_ & 0x0000FF00) >> 8, 24);
+ out_buffer->WriteCharAt((total_frames_ & 0x000000FF), 25);
+ }
out_buffer->set_sndfile_writes_enabled(true); // ready for sound-stream.
+ fprintf(stderr, "Header init done.\n");
out_buffer->HeaderFinished();
}
@@ -357,7 +375,7 @@ class SndFileFilter :
const int filedes_;
SNDFILE *const snd_in_;
- const int total_frames_;
+ const unsigned int total_frames_;
const std::string config_path_;
struct stat file_stat_; // we dynamically report a changing size.
Please sign in to comment.
Something went wrong with that request. Please try again.