Writing binary mangles data

我们两清 提交于 2019-12-12 12:41:47

问题


In my application, I record audio data from an ASIO driver:

void newData(void *buffer, int length)

where buffer is the buffer pointer and length is the number of samples in that buffer. In my case, I know that the samples are 4-byte integers and the buffer contains 1024 samples every run.

Now, I save these samples in two ways: little-endian binary (to be later used as a WAV file) and a text file. The text file saving words good, I get the numbers and they correspond to the samples form the waveform. But the binary file will always contain a little good data and the rest is just mangled.

Original data (original sound and text saving):

Mangled data (binary saving):

The code (I use std::ofstream):

//binary saving
tempOut.write((char *)buffer, length * 4);

//text saving
int *intBuf = (int *)buffer;
for(int i = 0; i < length; i++){
    textOut << intBuf[i];
    textOut << '\n';
}

Note that the problem is not with synchronization, as I save the binary data first and the text data second.

How the data are mangled:

Original    binary (LE) binary (BE) binary to dec
206016      C0240300    000324C0    206016
815616      00720C00    000C7200    815616
1804032     00871B00    001B8700    1804032
3131392     00C82F00    002FC800    3131392
4741440     40594800    00485940    4741440
6567552     80366400    00643680    6567552
8531264     402D8200    00822D40    8531264
10545664    00EAA000    00A0EA00    10545664
12517632    0001BF00    00BF0100    12517632
14353920    0006DB00    00DB0600    14353920
15958976    C083F300    00F383C0    15958976
17241600    00160701    01071600    17241600
18119296    807A1401    01147A80    18119296
18514048    80801A01    011A8080    18514048
18365760    403D1801    01183D40    18365760
17622016    00E40C01    010CE400    17622016
16253632    C002F800    00F802C0    16253632
14246784    8063D900    00D96380    14246784
11605504    0016B100    00B11600    11605504
8355840     00807F00    007F8000    8355840
4541376     C04B4500    00454BC0    4541376
228096      007B0300    00037B00    228096
-4501376    8050BBFF    FFBB5080    4290465920
-9549312    004A6EFF    FF6E4A00    4285417984
-14798400   C0311EFF    FF1E31C0    4280168896
-20126080   80E6CCFE    FECCE680    4274841216
-25391232   808F7CFE    FE7C8F80    4269576064
-30458624   003D2FFE    FE2F3D00    4264508672
-35178624   8037E7FD    FDE73780    4259788672
-39413760   0098A6FD    FDA69800    4255553536
-43025024   807D6FFD    FD6F7D80    4251942272
-45883392   00E043FD    FD43E000    4249083904
-47872704   408525FD    FD258540    4247094592
-48899072   00DC15FD    FD15DC00    4246068224
-48881280   802116FD    FD162180    4246086016
-47759616   003F27FD    FD273F00    4247207680
-45503488   00AC49FD    FD49AC00    4249463808
-42107648   007D7DFD    FD7D7D00    4252859648
-37589760   006DC2FD    FDC26D00    4257377536
-32005120   00A417FE    FE17A400    4262962176
-25429184   40FB7BFE    FE7BFB40    4269538112
-17961216   00EFEDFE    FEEDEF00    4277006080
-9736576    806E6BFF    FF6B6E80    4285230720
-909568     001FF2FF    FFF21F00    4294057728
8349120     C0657F00    007F65C0    8349120
17843584    80451001    01104580    17843584
27378816    80C4A101    01A1C480    27378816
36731904    007C3002    02307C00    36731904
45697792    004BB902    02B94B00    45697792
54044800    80A83803    0338A880    54044800
61575360    C090AB03    03AB90C0    61575360
68087552    00EF0E04    040EEF00    68087552
73396096    80EF5F04    045FEF80    73396096
77338368    00179C04    049C1700    77338368
79784320    8069C104    04C16980    79784320
80611328    0008CE04    04CE0800    80611328
79763520    4018C104    04C11840    79763520
77187328    00C99904    0499C900    77187328
72884352    80205804    04582080    72884352
66885120    0096FC03    03FC9600    66885120
59262720    00478803    03884700    59262720
50139648    0012FD02    02FD1200    50139648
39658752    00255D02    025D2500    39658752
28000256    0040AB01    01AB4000    28000256
15379520    40ACEA00    00EAAC40    15379520
2044416     00321F00    001F3200    2044416
-11740544   80DA4CFF    FF4CDA80    4283226752
-25707264   00BD77FE    FE77BD00    4269260032
-39540864   80A7A4FD    FDA4A780    4255426432
-52953600   00FED7FC    FCD7FE00    4242013696
-65651712   003C16FC    FC163C00    4229315584
-77331456   000464FB    FB640400    4217635840
-87716800   408CC5FA    FAC58C40    4207250496
-96567040   00813EFA    FA3E8100    4198400256
-103632000  80B3D2F9    F9D2B380    4191335296
-108724992  00FD84F9    F984FD00    4186242304
-111678336  80EC57F9    F957EC80    4183288960
-112379904  00384DF9    F94D3800    4182587392
-110761792  C0E865F9    F965E8C0    4184205504
-106792960  0078A2F9    F9A27800    4188174336
-100491840  C09D02FA    FA029DC0    4194475456
-91944960   000885FA    FA850800    4203022336
-81278912   40C827FB    FB27C840    4213688384
-68651520   0076E8FB    FBE87600    4226315776
-54296640   C07FC3FC    FCC37FC0    4240670656
-38472960   00F3B4FD    FDB4F300    4256494336
-21475776   404EB8FE    FEB84E40    4273491520
-3638272    007CC8FF    FFC87C00    4291329024
14684288    8010E000    00E01080    14684288
33120000    005FF901    01F95F00    33120000
51280320    C0790E03    030E79C0    51280320
68789504    00A51904    0419A500    68789504
85244544    80BA1405    0514BA80    85244544
100304768   8087FA05    05FA8780    100304768
113604800   C078C506    06C578C0    113604800
124833792   00D07007    0770D000    124833792
133720320   0069F807    07F86900    133720320
140022400   80925808    08589280    140022400
143561088   80918E08    088E9180    143561088
144198400   004B9808    08984B00    144198400
141871872   00CB7408    0874CB00    141871872
136572288   80ED2308    0823ED80    136572288
128333056   0035A607    07A63500    128333056
117298688   00D6FD06    06FDD600    117298688
103608960   80F22C06    062CF280    103608960
87533952    80A93705    0537A980    87533952
69342848    80162204    04221680    69342848
49372416    005DF102    02F15D00    49372416
28008640    C060AB01    01AB60C0    28008640
5674240     00955600    00569500    5674240
-17177472   80E4F9FE    FEF9E480    4277789824
-40097792   00289CFD    FD9C2800    4254869504
-62600192   00CC44FC    FC44CC00    4232367104
-84225024   00D4FAFA    FAFAD400    4210742272
-104489920  409CC5F9    F9C59C40    4190477376
-122963712  00B9ABF8    F8ABB900    4172003584
-139224384  C09AB3F7    F7B39AC0    4155742912
-152897792  00F7E2F6    F6E2F700    4142069504
-163660224  40BE3EF6    F63EBE40    4131307072
-171233280  0030CBF5    F5CB3000    4123734016
-175417088  00598BF5    F58B5900    4119550208
-176054784  009E81F5    F5819E00    4118912512
-173089536  00DDAEF5    F5AEDD00    4121877760
-166513152  003613F6    F6133600    4128454144
-156400000  8086ADF6    F6AD8680    4138567296
-142918272  803D7BF7    F77B3D80    4152049024
-126284736  400C79F8    F8790C40    4168682560
-106782720  00A0A2F9    F9A2A000    4188184576
-84789120   8038F2FA    FAF23880    4210178176
-60711040   809F61FC    FC619F80    4234256256
-35003200   C0E4E9FD    FDE9E4C0    4259964096
-8186112    001783FF    FF831700    4286781184
19211584    40252501    01252540    19211584
46627712    807BC702    02C77B80    46627712
73500480    40876104    04618740    73500480
99269120    00BAEA05    05EABA00    99269120
123365760   80695A07    075A6980    123365760
145304064   002AA908    08A92A00    145304064
164576000   003BCF09    09CF3B00    164576000
Here the mangling occurs:
180750080   0007C60D    0DC60700    231081728
193447488   0A40C687    87C6400A    2277916682
202362496   0B80CE0F    0FCE800B    265191435
207247040   0CC0565A    5A56C00C    1515634700
207959040   0C003465    6534000C    1697906700
204410560   0CC00E2F    2F0EC00C    789495820
196625792   0C8045B8    B845800C    3091562508
184697856   0B004402    0244000B    38010891
168819456   0B00FB0F    0FFB000B    268107787
149276544   0D0A80C7    C7800A0D    3347057165
126403200   E50880C2    C28008E5    3263170789
100631232   8807C082    82C00788    2193622920
72473600    FF0500DC    DC0005FF    3690989055
42428736    51044069    69400451    1765803089
11137280    870200F1    F1000287    4043309703
-20792320   A90000BC    BC0000A9    3154116777
-52715520   C2FE00A0    A000FEC2    2684419778
-83981184   DBFC808C    8C80FCDB    2357263579
-113911680  FEFA80D8    D880FAFE    3632331518
-141894144  35F900DE    DE00F935    3724605749
-167331840  8AF700B8    B800F78A    3087071114
-189665728  06F640EE    EE40F606    3997234694
-208386432  B1F48046    4680F4B1    1182856369
-223077888  94F3001A    1A00F394    436269972
-233389056  B4F200C4    C400F2B4    3288396468
-239046720  16F2C06F    6FC0F216    1874915862
-239889920  C0F10092    9200F1C0    2449535424
-235830720  B3F14082    8240F1B3    2185294259
-226899456  F1F100CA    CA00F1F1    3389059569
-213204992  79F200C0    C000F279    3221287545
-195002240  4AF38080    8080F34A    2155934538
-172597824  60F4C05D    5DC0F460    1572926560
-146384384  B6F5005A    5A00F5B6    1510012342
-116876032  46F7009D    9D00F746    2634086214
-84644736   08F9806C    6C80F908    1820391688
-50310400   F4FA0053    5300FAF4    1392573172

You can see how the wave is represented, positive and negative values alternate, until certain point. Then it becomes rubbish.


回答1:


You forgot to open the output file for binary data in binary mode. Therefore every time a byte 0x0A is sent to output the file receives (in a windows system) 0x0D 0x0A.




回答2:


If I'm interpreting your first line of information on the data correctly:

Original    binary (LE) binary (BE) binary to dec
206016      C0240300    000324C0    206016

Then the correct value is the big-endian data. If what you are seeing on disk is the 0xC0240300, then you are working on a little-endian machine (an Intel CPU), and you need to write the data in a big-endian format (and read it back in big-endian format too).

The way you're currently doing it is:

//binary saving
tempOut.write((char *)buffer, length * 4);

I assume 'buffer' is an array of 4-byte integers (in my work, it would most commonly be an array of char, but then the cast would be irrelevant).

I think that one way to do it 'better' might be:

enum { MAX_SAMPLES = 1024 };
char binbuff[4 * MAX_SAMPLES];

assert(length <= MAX_SAMPLES);
char *dst = binbuff;
for (int i = 0; i < length; i++)
{
     *dst++ = (buffer[i] >> 24) & 0xFF;
     *dst++ = (buffer[i] >> 16) & 0xFF;
     *dst++ = (buffer[i] >>  8) & 0xFF;
     *dst++ = (buffer[i] >>  0) & 0xFF;
}

tempOut.write(binbuff, 4 * length);

There are multiple more or less equivalent mechanisms available to achieve the same result.

Reading would be the inverse operation. You'd read the data into a character (byte) array, and then assemble each four bytes into a value:

int sample[MAX_SAMPLES];

char binbuff[4 * MAX_SAMPLES];
tempIn.read(binbuff, sizeof(binbuff));

char *src = binbuff;
for (int i = 0; i < MAX_SAMPLES; i++, src += 4)
{
     sample[i] = (src[0] & 0xFF) << 24 |
                 (src[1] & 0xFF) << 16 |
                 (src[2] & 0xFF) <<  8 |
                 (src[3] & 0xFF) <<  0;
}

The optimizer will remove the shifts by zero; they make the symmetry of the operations clear in the source code.



来源:https://stackoverflow.com/questions/10464824/writing-binary-mangles-data

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!