Solved

How to split a Wave file

Posted on 2004-03-30
20
919 Views
Last Modified: 2012-05-04

I Want to split a Wave file into 2 Wave files.

I preferably want to do this through VB, but any  FREEWARE (not shareware or commerical)

Utility is also fine.



Thanks!

 
0
Comment
Question by:unknown_routine
  • 7
  • 6
  • 5
  • +1
20 Comments
 
LVL 4

Expert Comment

by:sokolovsky
Comment Utility
How do you want to split? You want to recieve two wave files of equal length?
Source.Wav - 50 seconds
to
Result1.Wav - 25 seconds
Result2.Wav - 25 seconds
?
0
 
LVL 15

Author Comment

by:unknown_routine
Comment Utility
Yes, assume I want them to be equal.
0
 
LVL 6

Assisted Solution

by:___XXX_X_XXX___
___XXX_X_XXX___ earned 40 total points
Comment Utility
unknown_routine:
Extract header information from source wav file (search for it size on the net).
Then split the rest of the wav file, add header to each half and save it to file.
Something like this:

Source.wav:
Header
SoundData

1. Get Header
2. Split bytes from sound data in byteSound1 and byteSound2 byte arrays
3. Add Header in front of byteSound1 -> FirstWave.wav=Header+byteSound1
4. Add Header in front of byteSound2 -> SecondWave.wav=Header+byteSound2


I have a program that do opposite - Wave Merger - It works like this:
Extract header from first wave files (assume that sampling rate are identical).
Remove headers from two files. Merge two files data. Add header to file.
Results are very good. If you want I can provide with source of my Wave Merger program.

I think, that split of wave file will works when you done the above steps backward.
0
 
LVL 15

Author Comment

by:unknown_routine
Comment Utility
1. Get Header
===========

How?
0
 
LVL 15

Author Comment

by:unknown_routine
Comment Utility
If you want I can provide with source of my Wave Merger program.
============================================
Yes maybe would be helpful.
0
 
LVL 6

Expert Comment

by:___XXX_X_XXX___
Comment Utility
Ok, but tomorrow (must search code that is somewhere in my 20 CD's)
0
 
LVL 4

Assisted Solution

by:sokolovsky
sokolovsky earned 440 total points
Comment Utility
use this to split 8 or 16 bit, mono or stereo wave files:

Option Explicit
Dim HOLDER$
Dim InData As Long
Dim strCurFile As String
Dim yDiv
Dim LenData As Long
Dim LenTemp
Dim Nbits As Integer, StMo As String, SampF
Private Sub Form_Click()
    Call SplitWavFile("c:\1.wav")
End Sub
Sub SplitWavFile(ByVal strFile As String)
    strCurFile = strFile
    Call LoadFileData(strFile)
    Dim FTemp As String
    Dim InDataSel As Long
    Dim LenDataSel As Long, SampFreq As Long, BytInic, SampIni
    Dim mInData As Long

'Save 1'st part
    If InStrRev(strFile, ".wav") <> 0 Then
        FTemp = Mid$(strFile, 1, InStrRev(strFile, ".wav") - 1) & "_Part1.wav"
    Else
        FTemp = strFile & "_1.wav"
    End If
    mInData = InData
    SampIni = 0 ' Selection Begins
    'yDiv = yDiv ' FileSize in Bytes
    BytInic = SampIni * yDiv ' Location in the Wav of the Visible Selection
    InDataSel = InData + BytInic
    LenDataSel = LenData \ 2 'Selection Length in Samples
    SampFreq = SampF ' Sampling Frequency
    Open strCurFile For Binary Access Read As #1
        Call SaveWave(FTemp, InDataSel, LenDataSel, SampFreq, Nbits, StMo)
    Close #1

'Save 2 part
    If InStrRev(strFile, ".wav") <> 0 Then
        FTemp = Mid$(strFile, 1, InStrRev(strFile, ".wav") - 1) & "_Part2.wav"
    Else
        FTemp = strFile & "_2.wav"
    End If
    mInData = InData
    SampIni = LenData \ 2 ' Selection Begins
    'yDiv = yDiv ' FileSize in Bytes
    BytInic = SampIni * yDiv ' Location in the Wav of the Visible Selection
    InDataSel = InData + BytInic
    LenDataSel = LenData \ 2 'Selection Length in Samples
    SampFreq = SampF ' Sampling Frequency
    Open strCurFile For Binary Access Read As #1
        Call SaveWave(FTemp, InDataSel, LenDataSel, SampFreq, Nbits, StMo)
    Close #1

End Sub
Private Sub LoadFileData(FName As String)
    Dim yLec As Long, ydate As Date, ysg As Single
    Dim yint As Integer, ybt As Byte
    Dim Temp, Extemp, FimPlay
    Dim n As Long, X$, Y$, Z$
    Me.Caption = "WaveFile - " & "(" & FName & ")"
   
    Open FName For Binary Access Read As #1
    For n = 1 To 100
        X$ = Input(4, #1)
        If n = 2 Then HOLDER$ = X$ ' Hold This for Saving a New Wav
        If X$ = "fmt " Then Exit For 'Ignore everything else till this
    Next n
    'Get the Wave File Header Info
    Get #1, , yLec ' 16
    Get #1, , yint 'Compression Type (1=PCM)
    Get #1, , yint 'is Channels, 1 if mono and 2 if stereo
    If yint = 2 Then
        StMo = "Stereo"
      ElseIf yint = 1 Then
        StMo = "Mono"
      Else
        '"Error!"
        GoTo Errhandler
    End If
    Get #1, , yLec 'is the Sampling frequency of the file
    SampF = yLec
    Get #1, , yLec 'is a multiple of the sample frequency
    Get #1, , yint 'is the divisor of the number of bytes of
          'data which gives the number of Samples in the .wav
    yDiv = yint
    Get #1, , yint 'is the number of bits (8 or 16)
    If yint = 8 Or yint = 16 Then
        Nbits = yint
        '8 or 16
      Else
        '"Error"
        GoTo Errhandler
    End If
GotTheData:
    For n = 1 To 100
        Y$ = Input(1, #1)
        If Y$ = "d" Then Exit For ' Seek for start of Wav Data
    Next n
    Z$ = Input(3, #1)
    If Z$ <> "ata" Then 'Wav Data Starts here
        If n > 90 Then GoTo Errhandler
        Temp = Seek(1)
        Seek #1, Temp - 3
        GoTo GotTheData
    End If
    Get #1, , yLec '= num of bytes of data, start reading data here.
    LenData = yLec / yDiv 'Number of Samples
   
    LenTemp = LenData / (SampF)
    Extemp = (Int(LenTemp * 1000)) / 1000
    If LenTemp - Extemp >= 0.0005 Then
        Extemp = Extemp + 0.001
    End If
    '"Length: " & Extemp & " seconds"
    FimPlay = Int(LenTemp * 1000)
    InData = Seek(1) 'Loc(1) + 1 is the number of the first sound data byte of the file.
    Close #1
    Exit Sub
Errhandler:
    MsgBox "Error!!", vbOKOnly
    Close #1
    Exit Sub
End Sub
Private Sub WriteHeader(Chan As Integer, SampFreq As Long, Nbits As Integer, LenData As Long)
    Dim TmpR As Long
    Put #2, , "RIFF" ' RIFF Header Layer
    Put #2, 5, HOLDER$
    Put #2, 9, "WAVE" ' WAVE Header Layer
    Put #2, 13, "fmt "
    Put #2, 17, 16 '16
    Put #2, 21, 1 ' Compression (None=1(PCM))
    Put #2, 23, Chan ' Channels 1 or 2
    Put #2, 25, SampFreq ' Sampling Rate
    TmpR = SampFreq * (Chan * (Nbits / 8))
    Put #2, 29, TmpR '  Calculation
    TmpR = (Nbits / 8) * Chan
    Put #2, 33, TmpR 'Calculation
    Put #2, 35, Nbits ' Sampling bits
             ' End of WAVE Header Layer
    Put #2, 37, "data" ' Sound Data Layer
    Put #2, , LenData * TmpR ' Number of Samples in Wav
    'Starts a Binary Copy from the Selected Area in the Wav File
            'to the Newly created Untitled Wav File.
End Sub
Public Sub SaveWave(FName As String, InData As Long, LenData As Long, SampFreq As Long, Nbits As Integer, StMo As String)
    Dim ChanOut As Integer
    Dim yByte As Byte
    Dim yint As Integer
    Dim n As Long
    Open FName For Binary Access Write As #2
    ' Create or Overwrite a File Named Untitled(FormInstance).wav
    If StMo = "Stereo" Then
        ChanOut = 2
      Else
        ChanOut = 1
    End If
    WriteHeader ChanOut, SampFreq, Nbits, LenData ' Write Header Info
    If ChanOut = 2 Then GoTo Stereo8
    If Nbits = 16 Then GoTo Mono16
Mono8:
    Get #1, InData, yByte ' Points to First Block of Selection in source wav
    Put #2, , yByte ' Writes to Next Block in New File
        For n = 1 To LenData - 1
            Get #1, , yByte ' Points to Next Block of Selection in source wav
            Put #2, , yByte ' Writes to Next Block in New File
        Next n
    GoTo Done
Mono16:
    Get #1, InData, yint ' Points to First Block of Selection in source wav
    Put #2, , yint ' Writes to Next Block in New File
        For n = 1 To LenData - 1
            Get #1, , yint ' Points to Next Block of Selection in source wav
            Put #2, , yint ' Writes to Next Block in New File
        Next n
    GoTo Done
Stereo8:
    If Nbits = 16 Then GoTo Stereo16
    Get #1, InData, yByte 'left Channel
    Put #2, , yByte ' Writes to Next Block in New File
    Get #1, , yByte 'right Channel
    Put #2, , yByte ' Writes to Next Block in New File
        For n = 1 To LenData - 1
            Get #1, , yByte 'left Channel
            Put #2, , yByte ' Writes to Next Block in New File
            Get #1, , yByte 'right Channel
            Put #2, , yByte ' Writes to Next Block in New File
        Next n
    GoTo Done
Stereo16:
    Get #1, InData, yint 'left Channel
    Put #2, , yint ' Writes to Next Block in New File
    Get #1, , yint 'right Channel
    Put #2, , yint ' Writes to Next Block in New File
        For n = 1 To LenData - 1
            Get #1, , yint 'left Channel
            Put #2, , yint ' Writes to Next Block in New File
            Get #1, , yint 'right Channel
            Put #2, , yint ' Writes to Next Block in New File
        Next n
Done:
    Close #2
End Sub
'Sorry, code is not pretty, but working!
0
 

Expert Comment

by:winsupplychain
Comment Utility
What is the concept of this, does simply chopping the bytes, chops the file.  

Do you have a 'Hello World' Example which includes:
bits
channels (mono,2ch,4ch,6ch)

0
 

Expert Comment

by:winsupplychain
Comment Utility
and sample rate
0
 
LVL 4

Expert Comment

by:sokolovsky
Comment Utility
Hmm, winsupplychain, i do not understand this:
>What is the concept of this, does simply chopping the bytes, chops the file.  
>Do you have a 'Hello World' Example which includes:
>bits channels (mono,2ch,4ch,6ch) and sample rate
What do you want?
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Expert Comment

by:winsupplychain
Comment Utility
Is there a few lines of Code that quickly shows the concepts?
0
 

Expert Comment

by:winsupplychain
Comment Utility
Or can you explain the Input and the Output req'd.  I will post more points as another question.

One Input is the FileName
0
 
LVL 4

Expert Comment

by:sokolovsky
Comment Utility
Ok.
Public Sub SaveWave(FName As String, InData As Long, LenData As Long, SampFreq As Long, Nbits As Integer, StMo As String)
FName is a new file name.
InData is is the number of the first sound data byte of the file that i split
LenData is a number of samples in wav
SampFreq is a Sampling Rate
Nbits is a Sampling bits
StMo is "mono" or "stereo"

The main concepts is simple:
1) Read the source file, extract info from it (like Sampling Rate, "mono or "stereo", length...). You'd better read about wave (RIFF) format.
2) Write New WaveFile_1 with parameters like source file, but from 1 to length/2 data bytes.
3) Write New WaveFile_2 with parameters like source file, but from length/2 to lengthdata bytes.

P.S. Read http://ccrma-www.stanford.edu/courses/422/projects/WaveFormat/
0
 

Accepted Solution

by:
winsupplychain earned 20 total points
Comment Utility
That good
post example on below link, so it can be easily followed and I will add 500 pts. (i.e 44100hz 8 bit 2 channel).

By the way how does wave handle the channels in terms of storaging them, it is still sorta unclear.  I will be back I have to take a nap it is 0448 here.

http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/Q_20939933.html
0
 
LVL 4

Expert Comment

by:sokolovsky
Comment Utility
Visit this:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=31558&lngWId=1

Using my code, try to split file c:\windows\media\tada.wav
You'll find, that:
it is 2 channel (it is stereo)
Sampling Freq is 22050
Number of bits is 16
Number of Samples is 42752

Data is stored like this:
http://ccrma-www.stanford.edu/courses/422/projects/WaveFormat/wave-bytes.gif

Also visit this:
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=26377&lngWId=1

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=35852&lngWId=1
0
 
LVL 15

Author Comment

by:unknown_routine
Comment Utility
sokolovsky:

The sample works fine for 8 or 16 bit,

does  a major change is needed to make it work for 32 bit?

At this time i have very real time to research this myself, so if there is a simple change , please mention it.


Thanks.

0
 

Expert Comment

by:winsupplychain
Comment Utility
I will also look this over and try to refine it as well.  This was an excellent question!  


Thanks
0
 
LVL 4

Expert Comment

by:sokolovsky
Comment Utility
To unknown_routine:
Look at NBits variable.
It's sample size. So, it can be 8, 16, and you can make it 32.
This mean that every sample will have 32 bit length, and if chanels=2, then two chunks of 32 bits will appear.

Do not forgert to change

    Get #1, , yint 'is the number of bits (8 or 16)
    If yint = 8 Or yint = 16 Then
        Nbits = yint
        '8 or 16
      Else
        '"Error"
        GoTo Errhandler
    End If

to

    Get #1, , yint 'is the number of bits (8 or 16 or 32)
    If yint = 8 Or yint = 16 Or yint = 32 Then
        Nbits = yint
        '8 or 16 or 32
      Else
        '"Error"
        GoTo Errhandler
    End If
0
 
LVL 15

Author Comment

by:unknown_routine
Comment Utility
Just to future readers of this thread.

Accepeted answer is that given by  sokolovsky.So I gave him given 90% of points.

0
 

Expert Comment

by:winsupplychain
Comment Utility
I wasn't aware that I provided any assisited answer at all, but thanks for the points.  I guess I helped refine it.  Check back, I will try to post a condensed version (~20 or less) that works for all wav files (or most away).  Gave me a week or 2.

Thank You JP
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now