Solved

How to split a Wave file

Posted on 2004-03-30
20
924 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
ID: 10721572
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
ID: 10724280
Yes, assume I want them to be equal.
0
 
LVL 6

Assisted Solution

by:___XXX_X_XXX___
___XXX_X_XXX___ earned 40 total points
ID: 10726787
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
ID: 10727069
1. Get Header
===========

How?
0
 
LVL 15

Author Comment

by:unknown_routine
ID: 10727106
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___
ID: 10728042
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
ID: 10730567
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
ID: 10730672
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
ID: 10730684
and sample rate
0
 
LVL 4

Expert Comment

by:sokolovsky
ID: 10730716
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Expert Comment

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

Expert Comment

by:winsupplychain
ID: 10731301
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
ID: 10731410
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
ID: 10731520
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
ID: 10732142
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
ID: 10737228
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
ID: 10737958
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
ID: 10738892
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
ID: 10740119
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
ID: 10743004
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The debugging module of the VB 6 IDE can be accessed by way of the Debug menu item. That menu item can normally be found in the IDE's main menu line as shown in this picture.   There is also a companion Debug Toolbar that looks like the followin…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
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…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

911 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

16 Experts available now in Live!

Get 1:1 Help Now