bugGNU Octave - Bugs: bug #56889, Incorrect encoding results from...

 
 

bug #56889: Incorrect encoding results from uint8 vector to wav file

Submitter:  None
Submitted:  Sat 14 Sep 2019 11:42:37 AM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Incorrect Result
Status:  Fixed Assigned to:  None
Originator Name:  imad Originator Email:  -email is unavailable-
Open/Closed:  * Closed Release:  * 5.1.0
Operating System:  * Any Fixed Release:  None
Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Mon 16 Sep 2019 06:04:55 PM UTC, comment #14: 

This turned out to be quite the project.  There were multiple problems in the way data was prepared for writing (audiowrite), in the way Octave was interacting with the external SNDFILE library, and with the way data read from a file was scaled back to "native" range (audioread).  I applied a changeset which fixes all issues and adds BIST tests to the stable branch here: https://hg.savannah.gnu.org/hgweb/octave/rev/5283c505f92b.

This will be a part of the next bug fix release of Octave.  Closing report.

Rik <rik5>
Group administrator
Sun 15 Sep 2019 10:16:51 PM UTC, comment #13: 

@Rik: here is the file you request:
(all credits to Anas. H)

(file #47522)

imad imadero <imad007>
Sun 15 Sep 2019 05:58:35 PM UTC, comment #12: 

This continues to get more complicated.  I can get the written output file to contain 0xFF if I change the bias and scale arguments to be 127.5.  However, I experimented with writing -1.0 using libsndfile API and the result is 0x01 rather than 0x00.  Maybe this is something about how WAV files are written, or maybe there is an additional bug in libsndfile.

@Imad:  Could you run this test in Matlab and upload the file.  That will really help clarify what the expected behavior is.


audiowrite ('tst.matlab.uint8.wav', uint8 ([0, 1, 2, 253, 254, 255]), 8000, 'BitsPerSample', 8)



Rik <rik5>
Group administrator
Sun 15 Sep 2019 03:20:31 PM UTC, comment #11: 

sorry I do upload the file test.octave.wav twice
here is the test.matlab.wav file:


(file #47520)

imad imadero <imad007>
Sun 15 Sep 2019 03:12:31 PM UTC, comment #10: 

In audiowrite, the translation from [0, 255] to the range [-1.0, +1.0] for passing to libsndfile is compressing the range.

First this code,


  if (args(1).is_uint8_type ())
    bias = scale = std::pow (2.0, 7);


which sets bias and scale at 128.  And then


for (int i = 0; i < audio.rows (); i++)
  {
    for (int j = 0; j < audio.columns (); j++)
      {
        double elem = (audio.xelem (i, j) - bias) / scale;
        data[idx++] = std::min (std::max (elem, -1.0), 1.0);
      }
  }


The value 255 is translated to (255 - 128) / 128 = 127/128 which is not 1.0.


Rik <rik5>
Group administrator
Sun 15 Sep 2019 02:56:06 PM UTC, comment #9: 

Could you re-upload test.matlab.wav?  It is identical to test.octave.wav and does not show the characteristic "FF FF FF" that is captured in your screen shot of the binary editor.

Also, could you run this test in Matlab and upload the file?


audiowrite ('tst.matlab.uint8.wav', uint8 ([0, 1, 2, 253, 254, 255]), 8000, 'BitsPerSample', 8)


When I try this with Octave and look at the resulting binary I see [1, 2, 3, 252, 253, 254].  In other words, audiowrite() seems to be compressing the range [0, 255] in to the range [1,254].  I verified that if I write 0:255 to a wav file I get 256 elements, but the range is [1, 254] and there are duplicate values.

There is also a problem with audioread.  I directly modified the binary test file used above to have values [0x00 0x01 0x02 0xFD 0xFE 0xFF].  When this is read with audioread the result is [0, 1, 2, 251, 252, 253].

The C++ source file for both functions is in libinterp/dldfcn/audioread.cc.


Rik <rik5>
Group administrator
Sun 15 Sep 2019 09:50:43 AM UTC, comment #8: 

P.S:
the audio file generated by matlab is file #47518
the audio file generated by octave is file #47519

imad imadero <imad007>
Sun 15 Sep 2019 09:44:46 AM UTC, comment #7: 

Hi everyone,
details about the issue are depicted as follow:

the main code:

Fs=8000;
filename='test.wav'
y=ones(1,32)*256;
for k=1:32
y(k)=258-k;% some overflowing values to make sure uint8 parses all values
end
audiowrite(filename,uint8(y),Fs,'BitsPerSample',8);
yi= audioread(filename,'native');


1) we exucute this code using matlab, the file generated is named as test.matlab.wav, it's content is showed in the hexfile editor under the name test.matlab.wav
2) we execute the same code under Octave, the file generated is named as test.octav.wav wich is different from the one generated by Matlab, to see the difference looking at the byte index "44" from which the difference emerges.
3) we read the file test.matlab.wav using octave;; wrong results from audioread as well !! the same problem ( values 0,253,254,255 are parsed to 255 and 0). audioread under matlab read the file correctly.
the output of audioread funtion using octave to read the file test.matlab.wav:

y_matlab =

  252
  252
  252
  251
  250
  249
  248
  247
  246
  245
  244
  243
  242
  241
  240
  239
  238
  237
  236
  235
  234
  233
  232
  231
  230
  229
  228
  227
  226
  225
  224
  223

thanks every one


file #47518, file #47519)

imad imadero <imad007>
Sun 15 Sep 2019 12:37:07 AM UTC, comment #6: 

Could you upload the Matlab-generated file?  That would help with testing.

Simple code to reproduce:


audiowrite ('tst_uint8.wav', uint8 (255:-1:224), 8000, 'BitsPerSample', 8)
y = audioread ('tst_uint8.wav', 'native')


The resulting vector is


y =

  252
  251
  250
  249
  248
  247
  246
  245
  244
  243
  242
  241
  240
  239
  238
  237
  236
  235
  234
  233
  232
  231
  230
  229
  228
  227
  226
  225
  224
  223
  222
  221


No samples are lost, but they are all shifted down by 3.

Marking as confirmed and changing the Operating System to "Any" since I can reproduce this on Linux.

Rik <rik5>
Group administrator
Sat 14 Sep 2019 10:35:57 PM UTC, comment #5: 

95% the error is in fwrite function ..
I will figure that out and gives feedback.

imad imadero <imad007>
Sat 14 Sep 2019 10:14:43 PM UTC, comment #4: 

The file is written incorrectly. (it parses values 253,254,255 to 252. and parse 0 to 1).
the main problem maybe in audiowrite function.

imad imadero <imad007>
Sat 14 Sep 2019 10:07:29 PM UTC, comment #3: 

Since you have access to Matlab, can you compare the files written between Matlab and Octave? For example, please try reading the file written by Octave into Matlab, and vice versa. Is the audio written incorrectly by Octave, or is it only read incorrectly?

Mike Miller <mtmiller>
Group Member
Sat 14 Sep 2019 09:03:54 PM UTC, comment #2: 

the problem with audiowrite function is that it do not encode 0,253,254,255 values as uint8() to the wav file.
to verify this I propose the following code:

% test audiowrite function for uint8 vector
Fs=8000;
f="test.wav";
y=[];
for k=1:32
  y(k)=256-k; %%%%% last 32 bytes in the field 2^8.
endfor
audiowrite(f,uint8(y),Fs,'BitsPerSample',8);% values 255,254,253 could not be writen into the file !!!!
audioread(f,'native') %% check results written to the file


note: the code above works well on Matlab thus encoding all uint8 valuse including 0,253,254 and 255.

imad imadero <imad007>
Sat 14 Sep 2019 06:00:31 PM UTC, comment #1: 

There doesn't seem to be any message attached.  Could you post details on the problem, and ideally some example data and code to reproduce the issue.

Rik <rik5>
Group administrator
Sat 14 Sep 2019 11:42:37 AM UTC, original submission:  


%%
% test audio write function for uint8 vector
Fs=8000;
f="test.wav";
y=[];
for k=1:32
  y(k)=256-k;
endfor
audiowrite(f,uint8(y),Fs,'BitsPerSample',8);
audioread(f,'native')
-verbatom-


the original vector y is transformed to uint8 data type then encoded in wav file.
the encoded results do not match
Note:
 The same code works as expected in MATLAB.

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #47522:  tst.matlab.uint8.wav added by imad007 (50B - audio/wav)
file #47520:  test.matlab.wav added by imad007 (76B - audio/wav)
file #47516:  hex.matlab.png added by imad007 (14KiB - image/png)
file #47517:  hex.octave.png added by imad007 (14KiB - image/png)
file #47518:  test.matlab.wav added by imad007 (76B - audio/wav)
file #47519:  test.octave.wav added by imad007 (76B - audio/wav)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by imad007 (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by None (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 11 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2019-09-16 rik5 StatusConfirmed Fixed
        Open/ClosedOpen Closed
    2019-09-15 imad007 Attached File- Added tst.matlab.uint8.wav, #47522
    2019-09-15 imad007 Attached File- Added test.matlab.wav, #47520
    2019-09-15 imad007 Attached File- Added hex.matlab.png, #47516
        Attached File- Added hex.octave.png, #47517
        Attached File- Added test.matlab.wav, #47518
        Attached File- Added test.octave.wav, #47519
    2019-09-15 rik5 StatusNeed Info Confirmed
        Operating SystemMicrosoft Windows Any
    2019-09-14 rik5 StatusNone Need Info

    Back to the top

    Powered by Savane 3.13-d3ae.
    Corresponding source code