-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathwavesplit.py
More file actions
executable file
·139 lines (113 loc) · 4.06 KB
/
Copy pathwavesplit.py
File metadata and controls
executable file
·139 lines (113 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# Wavesplit
# For Python 3
# By Zoe Blade
# Splits up a big .wav file into several smaller .wav files, one per sound
import glob # For command line wildcards
import os # For optionally deleting the input files
import struct # For converting the (two's complement?) binary data to integers
import sys # For command line arguments
import wave # For .wav input and output
# Set sensible defaults
threshold = 1024 # This has to be a number between 1 and 32767
duration = 11025 # Measured in single samples
delete = False
inputFilenames = []
# Override the defaults
for argument in sys.argv:
# Override the filename
if (argument[-4:].lower() == '.wav'):
filenames = glob.glob(argument)
for filename in filenames:
inputFilenames.append(filename)
continue
# Override the threshold
if (argument[:12] == '--threshold='):
argument = int(argument[12:])
if (argument > 0 and argument < 32768):
threshold = argument
continue
else:
print('The threshold must be an integer between 1 and 32767')
exit()
# Override the duration
if (argument[:11] == '--duration='):
argument = int(argument[11:])
if (argument > 0):
duration = argument
continue
else:
print('The duration must be a positive integer')
exit()
# Replace original files
elif (argument == '-d'):
delete = True
if (len(inputFilenames) == 0):
print("""\
Usage:
python3 wavesplit.py [option...] input.wav
Options: (may appear before or after arguments)
--threshold=foo
set the cutoff point between signal and noise (default is 1024, any number between 1 and 32767 is valid)
--duration=foo
require this many consecutive samples below the cutoff point in order to close the output file (default is 11025, a quarter of a second at CD quality)
-d
delete original files
""")
exit()
# Cycle through files
for inputFilename in inputFilenames:
outputFilenamePrefix = inputFilename[:-4]
outputFilenameNumber = 0
try:
inputFile = wave.open(inputFilename, 'r')
except:
print(inputFilename, "doesn't look like a valid .wav file. Skipping.")
continue
framerate = inputFile.getframerate()
numberOfChannels = inputFile.getnchannels()
sampleWidth = inputFile.getsampwidth()
currentlyWriting = False
allChannelsBeneathThreshold = 0
for iteration in range(0, inputFile.getnframes()):
allChannelsAsBinary = inputFile.readframes(1)
allChannelsCurrentlyBeneathThreshold = True
for channelNumber in range (numberOfChannels):
channelNumber = channelNumber + 1
channelStart = (channelNumber - 1) * sampleWidth
channelEnd = channelNumber * sampleWidth
channelAsInteger = struct.unpack('<h', allChannelsAsBinary[channelStart:channelEnd])
channelAsInteger = channelAsInteger[0]
if (channelAsInteger < 0):
channelAsInteger = 0 - channelAsInteger # Make readout unipolar
if (channelAsInteger >= threshold):
allChannelsCurrentlyBeneathThreshold = False
if (currentlyWriting == True):
# We are currently writing
outputFile.writeframes(allChannelsAsBinary)
if (allChannelsCurrentlyBeneathThreshold == True):
allChannelsBeneathThresholdDuration = allChannelsBeneathThresholdDuration + 1
if (allChannelsBeneathThresholdDuration >= duration):
currentlyWriting = False
outputFile.close()
else:
allChannelsBeneathThresholdDuration = 0
else:
# We're not currently writing
if (allChannelsCurrentlyBeneathThreshold == False):
currentlyWriting = True
allChannelsBeneathThresholdDuration = 0
outputFilenameNumber = outputFilenameNumber + 1
outputFilename = str(outputFilenameNumber)
outputFilename = outputFilename.zfill(2) # Pad to 2 digits
outputFilename = outputFilenamePrefix + '-' + outputFilename + '.wav'
print('Writing to', outputFilename)
outputFile = wave.open(outputFilename, 'w')
outputFile.setnchannels(inputFile.getnchannels())
outputFile.setsampwidth(inputFile.getsampwidth())
outputFile.setframerate(inputFile.getframerate())
if (currentlyWriting == True):
outputFile.close()
if (delete == True):
print('Deleting', inputFilename)
os.unlink(inputFilename)
print(inputFilename, "finished splitting")