Fix handling of stereo data

Stereo data was being incorrectly copied to the frame buffer. Fix
that and at the same time move the whole copy loop to C which should
hopefully improve performance.
This commit is contained in:
Will Newton 2015-03-09 10:52:19 +00:00
parent 32bd283d4c
commit 3cab89e91d
4 changed files with 60 additions and 11 deletions

View file

@ -58,10 +58,14 @@ get_decoder_rate(FLAC__StreamMetadata *metadata)
return metadata->data.stream_info.sample_rate;
}
extern int
get_audio_sample(const FLAC__int32 **buffer, int off, int ch)
extern void
get_audio_samples(int32_t *output, const FLAC__int32 **input,
unsigned int blocksize, unsigned int channels)
{
return buffer[ch][off];
unsigned int i, j, samples = blocksize * channels;
for (i = 0; i < blocksize; i++)
for (j = 0; j < channels; j++)
output[i * channels + j] = input[j][i];
}
*/

BIN
data/sine16-12.flac Normal file

Binary file not shown.

View file

@ -60,8 +60,9 @@ get_decoder_depth(FLAC__StreamMetadata *metadata);
extern int
get_decoder_rate(FLAC__StreamMetadata *metadata);
extern int
get_audio_sample(const FLAC__int32 **buffer, int off, int ch);
extern void
get_audio_samples(int32_t *output, const FLAC__int32 **input,
unsigned int blocksize, unsigned int channels);
*/
import "C"
@ -119,12 +120,8 @@ func decoderWriteCallback(d *C.FLAC__StreamDecoder, frame *C.FLAC__Frame, buffer
f.Channels = decoder.Channels
f.Depth = decoder.Depth
f.Rate = decoder.Rate
f.Buffer = make([]int32, blocksize)
for i := 0; i < blocksize; i++ {
for ch := 0; ch < decoder.Channels; ch++ {
f.Buffer[i + ch] = int32(C.get_audio_sample(buffer, C.int(i), C.int(ch)))
}
}
f.Buffer = make([]int32, blocksize * decoder.Channels)
C.get_audio_samples((*C.int32_t)(&f.Buffer[0]), buffer, C.uint(blocksize), C.uint(decoder.Channels))
return C.FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
}

View file

@ -134,3 +134,51 @@ func TestRoundTrip(t *testing.T) {
os.Remove(outputFile)
}
func TestRoundTripStereo(t *testing.T) {
a := assert.New(t)
inputFile := "data/sine16-12.flac"
outputFile := "data/test.flac"
d, err := NewDecoder(inputFile)
a.Equal(err, nil, "err is nil")
e, err := NewEncoder(outputFile, d.Channels, d.Depth, d.Rate)
samples := 0
for {
f, err := d.ReadFrame()
if (err == nil || err == io.EOF) {
if (f != nil) {
_ = e.WriteFrame(*f)
samples = samples + len(f.Buffer)
}
} else {
a.Equal(err, nil, "error reported")
break
}
if (err == io.EOF) {
break
}
}
a.Equal(samples, 400000, "all samples read")
d.Close()
e.Close()
inFile, err := os.Open(inputFile)
a.Equal(err, nil, "err is nil")
outFile, err := os.Open(outputFile)
a.Equal(err, nil, "err is nil")
inData, _ := ioutil.ReadAll(inFile)
outData, _ := ioutil.ReadAll(outFile)
a.Equal(md5.Sum(inData), md5.Sum(outData), "files md5sum the same")
os.Remove(outputFile)
}