ABOUT ME

Contact.
Email:yj.anthonyjo@gmail.com
Introduce : CS Student.

Today
-
Yesterday
-
Total
-
  • Python : 모스코드를 소리로 나타내기
    프로그래밍/Python 2020. 9. 6. 16:16
    반응형

    번역된 모스부호(모스코드)를 소리로 나타내는 코드이다.

    행사를 준비하며 만들었던 코드이지만, 그 행사가 코로나19로 인해 무기한 연기되었다...

    역시 이 코드 또한 인터넷에 올라온 자료들이 많지 않기에, 글을 올린다.

    본인이 맡은 프로젝트를 빠르고 효율성있게 마무리할 수 있기를 바란다.

    (아무리 간단한 프로젝트여도 예상시간의 적어도 3배는 해야..)

    여담으로, 코드에 나와있는 예제 모스코드는, 2020 수능특강 영어 지문의 일부이다.

    https://stackoverflow.com/questions/33879523/python-how-can-i-generate-a-wav-file-with-beeps 해당 코드를 참고하였다.

    중요주석, docstring은 수정하지 않았다.

    import math
    import wave
    import struct
    import time
    
    # Audio will contain a long list of samples (i.e. floating point numbers describing the
    # waveform).  If you were working with a very long sound you'd want to stream this to
    # disk instead of buffering it all in memory list this.  But most sounds will fit in 
    # memory.
    
    audio = []
    sample_rate = 44100.0
    
    
    def append_silence(duration_milliseconds=500):
        """
        Adding silence is easy - we add zeros to the end of our array
        """
        num_samples = duration_milliseconds * (sample_rate / 1000.0)
    
        for x in range(int(num_samples)): 
            audio.append(0.0)
    
        return
    
    
    def append_sinewave(
            freq=440.0, 
            duration_milliseconds=500, 
            volume=1.0):
        """
        The sine wave generated here is the standard beep.  If you want something
        more aggresive you could try a square or saw tooth waveform.   Though there
        are some rather complicated issues with making high quality square and
        sawtooth waves... which we won't address here :) 
        """ 
    
        global audio
    
        num_samples = duration_milliseconds * (sample_rate / 1000.0)
    
        for x in range(int(num_samples)):
            audio.append(volume * math.sin(2 * math.pi * freq * ( x / sample_rate )))
    
        return
    
    
    def save_wav(file_name):
        print('in')
        # Open up a wav file
        wav_file=wave.open(file_name,"w")
    
        nchannels = 1
        sampwidth = 2
    
        # 44100 is the industry standard sample rate - CD quality.  If you need to
        # save on file size you can adjust it downwards. The stanard for low quality
        # is 8000 or 8kHz.
        nframes = len(audio)
        comptype = "NONE"
        compname = "not compressed"
        wav_file.setparams((nchannels, sampwidth, sample_rate, nframes, comptype, compname))
    
        # WAV files here are using short, 16 bit, signed integers for the 
        # sample size.  So we multiply the floating point data we have by 32767, the
        # maximum value for a short integer.  NOTE: It is theortically possible to
        # use the floating point -1.0 to 1.0 data directly in a WAV file but not
        # obvious how to do that using the wave module in python.
        k = len(audio)
        i = 0
        st = time.time()
        for sample in audio:
            i +=1
            if i % 100000 ==0:
                print( time.time()-st,"초" )
                st = time.time()
                print((i/k) *100 ,'%')
            wav_file.writeframes(struct.pack('h', int( sample * 32767.0 )))
    
        wav_file.close()
    
        return
    
    txt = "-... . -....- -.-. .- .-. . ..-. ..- .-.. .-.-.-"
    dic = {'-' : 0.2, '.' : 0.1}
    for morse in txt:
        if morse != ' ' :
            append_sinewave(duration_milliseconds = dic[morse] * 1000)
        else :
            append_silence(duration_milliseconds = 0.1)
        append_silence(duration_milliseconds = 100)
    
    save_wav("output1.wav")

    단, 시간이 매우 오래걸린다는 점은 참고하자. 

    이부분은 이후에 수정할 예정이다.

    반응형

    댓글

Designed by Tistory.