0

Using the script in this answer, silence at the beginning of the recording is not clipped.

I'm using python3.

As I've actually slightly tweaked the script, here's my copy: https://wtools.io/paste-code/b2tk

from sys import byteorder
from array import array
from struct import pack
 
import pyaudio
import wave
 
THRESHOLD = 500
CHUNK_SIZE = 1024
FORMAT = pyaudio.paInt16
RATE = 44100
 
def is_silent(snd_data):
    "Returns 'True' if below the 'silent' threshold"
    return max(snd_data) < THRESHOLD
 
def normalize(snd_data):
    "Average the volume out"
    MAXIMUM = 16384
    times = float(MAXIMUM)/max(abs(i) for i in snd_data)
 
    r = array('h')
    for i in snd_data:
        r.append(int(i*times))
    return r
 
def trim(snd_data):
    "Trim the blank spots at the start and end"
    def _trim(snd_data):
        snd_started = False
        r = array('h')
 
        for i in snd_data:
            if not snd_started and abs(i) > THRESHOLD:
                snd_started = True
                r.append(i)
 
            elif snd_started:
                r.append(i)
        return r
 
    # Trim to the left
    snd_data = _trim(snd_data)
 
    # Trim to the right
    snd_data.reverse()
    snd_data = _trim(snd_data)
    snd_data.reverse()
    return snd_data
 
def add_silence(snd_data, seconds):
    "Add silence to the start and end of 'snd_data' of length 'seconds' (float)"
    silence = [0] * int(seconds * RATE)
    r = array('h', silence)
    r.extend(snd_data)
    r.extend(silence)
    return r
 
def record():
    """
    Record a word or words from the microphone and 
    return the data as an array of signed shorts.
 
    Normalizes the audio, trims silence from the 
    start and end, and pads with 0.5 seconds of 
    blank sound to make sure VLC et al can play 
    it without getting chopped off.
    """
    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT, channels=1, rate=RATE,
        input=True, output=True,
        frames_per_buffer=CHUNK_SIZE)
 
    num_silent = 0
    snd_started = False
 
    r = array('h')
 
    while 1: 
        # little endian, signed short
        snd_data = array('h', stream.read(CHUNK_SIZE))
        if byteorder == 'big':
            snd_data.byteswap()
        r.extend(snd_data)
 
        silent = is_silent(snd_data)
 
        if silent and snd_started:
            num_silent += 1
        elif not silent and not snd_started:
            snd_started = True
 
        if snd_started and num_silent > 300:
            break
 
    sample_width = p.get_sample_size(FORMAT)
    stream.stop_stream()
    stream.close()
    p.terminate()
 
    r = normalize(r)
    r = trim(r)
    r = add_silence(r, 0.5)
    return sample_width, r
 
def record_to_file(path):
    "Records from the microphone and outputs the resulting data to 'path'"
    sample_width, data = record()
    data = pack('<' + ('h'*len(data)), *data)
 
    wf = wave.open(path, 'wb')
    wf.setnchannels(1)
    wf.setsampwidth(sample_width)
    wf.setframerate(RATE)
    wf.writeframes(data)
    wf.close()
 
if __name__ == '__main__':
    print("please speak a word into the microphone")
    record_to_file('demo.wav')
    print("done - result written to demo.wav")

How can I adjust this script to clip the silence from the beginning of it?

Josiah Yoder
  • 3,321
  • 4
  • 40
  • 58
  • Maybe I'm wrong, but this seems to me like it would belong better if you asked this in a comment on the answer you linked. Or can you maybe try to ask it in a more generally useful way that is less tied to fixing a specific script? – E. T. Oct 22 '20 at 22:38
  • 1
    agreed. but this site wont let me comment on it. :( – Antioch Technologies Oct 22 '20 at 22:59
  • Ah, yeah, might be due to this "reputation" concept StackOverflow uses. I forwarded your remark in a comment for you, maybe someone will see it and respond to it. – E. T. Oct 23 '20 at 13:39
  • it appears the mic makes a slight click when it's activated, tripping up the beginning silence trim. now i'm just trying to figure out how to dump the opening moments of audio so the trim works correctly... – Antioch Technologies Nov 21 '20 at 16:45

1 Answers1

1

The issue was due to a quick, inaudible flash of sound when the mic was started. Adding del r[0:8000] before r = normalize(r) eliminated the first moments of audio containing the inaudible sound data, solving my issue.

Josiah Yoder
  • 3,321
  • 4
  • 40
  • 58
  • Welcome to StackOverflow. Those first years before you earn the right to comment are always difficult. Here's hoping you get there a bit sooner. – Josiah Yoder Aug 23 '22 at 19:32
  • One word of advice: always capitalize the beginning of each sentence. Having conventional professional English style will significantly improve the chance of your answers being accepted and upvoted. I'm happy to copy-edit your next post. Put a link to it here and @mention me. – Josiah Yoder Aug 23 '22 at 19:33
  • @JosiahYoder your offer is a kind one, but im not seduced by gamification and long ago gave up trying to contribute here due to the obstacles it introduces. some time later i had forgotten this while attempting to provide the proper answer to a question that had only dangerous answers, only to have my answer promptly deleted. not only is it doubtful ill forget again, but after willfully promoting dangerous info, i no longer consider info found here with the authority that i once did. – Antioch Technologies Aug 26 '22 at 18:33
  • I'm sorry to hear about your unsatisfying experiences with Stack Overflow. But I do wish you would use capitalization in your text. You would be surprised how much better it looks to me that way -- and I suspect, to many who delete content here. – Josiah Yoder Aug 29 '22 at 15:16
  • And notably, you lack only three points to be able to comment. So despite your frustrations with gamification, you are very close to one capability that you very much desire on this site. It took me years to get to the fifty-point level on Stack Overflow, and I agree that that time period can be very frustrating. – Josiah Yoder Aug 29 '22 at 15:19
  • Gamification is an alternative to the model used by Wikipedia, where anyone can edit, and yet, in some sense, no one can. – Josiah Yoder Aug 29 '22 at 15:20
  • @JosiahYoder anyone who would delete valuable content due to a lack of capitalization disrespects its contributor and shoots themselves in the foot simultaneously. and after having my efforts so casually disrespected so that dangerous misinformation was effectively promoted by the mods, i desire nothing more from this site and view it in an entirely different light now. perhaps if that hadnt happened, i wouldve accidentally stumbled my way into a spot where this site eventually became more usable. – Antioch Technologies Aug 29 '22 at 16:50
  • Refusing to follow the stylistic conventions (which of course don't matter) of a site feels awfully extreme to me.... why risk good content being rejected just to promote disunity of style? – Josiah Yoder Aug 29 '22 at 16:57
  • to be clear, youre suggesting that telling folks to store their js secrets insecurely is preferable to the proper answer thats capitalized incorrectly? because that seems "awfully extreme" to me. but thats ok, its their show, and that seemed to be the consensus, last i saw the meta. so message received is all im saying. :-/ – Antioch Technologies Aug 29 '22 at 21:50
  • That is not at all what I was saying. – Josiah Yoder Aug 30 '22 at 14:16
  • no, i understood what you were saying and appreciate your comments. what im rhetorically asking is why would i bother to contribute to a project that values those contributions so little that it would discard them for something so trivial as using all lowercase on the internet, especially given the stakes? – Antioch Technologies Aug 30 '22 at 16:57