LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   A problem with vim and vimís macros (https://www.linuxquestions.org/questions/linux-software-2/a-problem-with-vim-and-vim%92s-macros-769034/)

w1k0 11-13-2009 10:35 PM

A problem with vim and vimís macros
 
In the past I converted from WAV to MP3 a lot of music albums stored previously in ACE/CUE files. To decode and split ACE files I used mac and bchunk. Unfortunately bchunk splits joined WAV file in an invalid mode. It doesn’t remove an original RIFF header from the first WAV file so in result that file has doubled header. In music players it sounds like a short loud snap. I wrote about it here.

In order to remove that snaps I tried to use audacity but I stated it’s uncomfortable. I tried also mcedit in hexadecimal edit mode but when I need overwrite over 3500 characters I have to keep 0 key for a few minutes and it's tiresome. So I decided to remove them using vim in a binary mode.

In the case of WAV file made by bchunk from joined WAV file is enough to skip first 44 bytes (first RIFF header) and overwrite with null characters consecutive 44 bytes (second RIFF header).

I recorded my first macro using that sequence of strokes:

Code:

qpgg44lRCtrl-vCtrl-Shift-2Esc44.q
(I don't show here the actual macro stored in ~/.viminfo file because it's impossible to reproduce properly on a web page special characters used by vim to represent Ctrl-v Ctrl-Shift-2 sequence and Esc keystroke.)

To remove additional RIFF header from the WAV file prepared by bchunk is enough to run vim -b track.wav command and then press that sequence of characters:

Code:

@pZZ
The resulting file has the same length as the original one but doesn’t play the mentioned above snap.

The above macro I wrote only for testing purposes because now I don’t use original buggy bchunk but the modified version of it or shntool so I receive correct WAV files.

My main problem now is how to remove unwanted data from MP3 files. In that case it’s necessary to decode MP3 file using lame with --decode option, skip first 44 bytes of resulting WAV file and replace about 3552 bytes of garbage with the null characters (44 bytes of garbage in original WAV file after encoding it to MP3 and decoding back to WAV increases to near 3552 bytes of garbage).

So I prepared similar macro as before:

Code:

qogg44lRCtrl-vCtrl-Shift-2Esc3552.q
Unfortunately it doesn’t work. When I run that macro it skips first 44 bytes of data and overwrites a bunch of characters with 00 characters (null) as far as it encounters the first 0A character (newline) but instead of overwrite the newline it inserts the rest of the null characters before it. In result modified WAV file is longer than the original one and some garbage still remains. The resulting track sometimes has a silent snap at the beginning and sometimes doesn't play any sound at all.

***

My questions are:

1. Is it possible to overwrite 0A characters (newlines) with vim?

2. Is there any binary editor for Linux allowing to overwrite newlines (as mcedit) as well as to record and run macros (as vim)?

w1k0 11-14-2009 12:13 PM

I found the resolution of the above problem. It works though it isn’t very comfortable.

1. I open a WAV file using vim -b track.wav command. It’s important to use a binary mode because in regular mode vim adds one character at the end of the file (A0 – newline).

2. I run the external filter to convert to hexadecimal mode:

Code:

:%!xxd
3. The filtered file looks like:

Code:

0000000: 5249 4646 44d4 e702 5741 5645 666d 7420  RIFFD...WAVEfmt
0000010: 1000 0000 0100 0200 44ac 0000 10b1 0200  ........D.......
0000020: 0400 1000 6461 7461 20d4 e702 a456 c137  ....data ....V.7
0000030: 6666 8432 8460 3a3b 9c50 1f25 a417 34fd  ff.2.`:;.P.%..4.
0000040: dde3 05fd 01b8 0306 2db6 daf8 36fd c20f  ........-...6...

It’s a dumb matrix. You have to edit only hexadecimal values. It’s possible to edit addresses but it produces invalid results after saving of the file.

RIFF header starts from the beginning of the file and stops four characters after “data” sequence. The garbage starts with these codes: “a456 c137”.

3a. Staying in xxd mode I defined first macro. To do it I put the cursor at the beginning of 0000030 line – at the character “66”. I assigned that macro to “z” key:

Code:

qzR0000→0000→0000→0000→0000→0000→0000→0000Esc38hjq
Arrows symbolize arrow keys. The above macro replaces characters in the current line with the null characters and jumps to the beginning of the next line.

3b. Staying in xxd mode I defined second macro. I assigned it to “a” key:

Code:

qagg9ljj30lR0000→0000Esc38hj222@zq
That macro skips the RIFF header, overwrites four last bytes in 0000020 line with null characters, jumps to the beginning of the next line and runs above “z” macro 222 times.

4. Then I exited xxd mode:

Code:

:%!xxd -r
It’s important to use -r switch to return from that mode. Alone :%!xxd command runs xxd mode inside xxd mode producing a huge file full of garbage.

5. Finally I saved modified file:

Code:

ZZ
Now to use these macros is enough to open WAV file in a binary mode (vim -b track.wav), switch to xxd mode (:%!xxd), run “a” macro (@a), exit xxd mode (%!xxd -r) and save file (ZZ).

***

To completely automate the work I defined one more macro:

Code:

qq:%!xxdEnter@a:%!xxd -rEnterq
After leaving vim I added in ~/.viminfo file at the end of the definition of “q” macro the sequence “ZZ”.

In result to overwrite garbage in the WAV file is enough to open it (vim -b track.wav) and run “q” macro (@q). Of course it’s possible to merge “q” and “a” macros into one big macro.

***

Vim’s xxd mode is really dumb. I don’t recommend it but in some cases it’s the only way to perform desired tasks.


All times are GMT -5. The time now is 06:34 AM.