음악파일의 피치바꾸기(python)

산체스·2023년 4월 11일
post-thumbnail

친구가 파이썬으로 리듬게임을 만든단다.

허걱, 왜 파이썬이니? 그거슨 파이썬을 할 줄 알기 때미니....
암튼 하다보니 마우스로 움직여서 피치를 조정하는 마치 현악기 같은 로직을 만들어야 한다고 하는디, 도저히 방법을 모르겠다해서 나는 구글링이아닌 챗지피티를 켰다.

WOW 나름 괜찮은 방법으로 알려주는 것 같긴한데 실시간게임처럼 만들수 있을지는 의문이다.

처음에 키보드 입력을 받아서 하는걸로 알려주길래

ㄴㄴ 그거아님 마우스로 만드셈 했다. 것보다 코드리뷰 해주려고 깃허브에다가 푸쉬좀 하라니까 드럽게 안한다. 크흠...

User: Write a code to raise the note by one key in Python Answer in English.


ChatGPT: Sure, here’s an example code in Python that raises a musical note by one key:

pythonCopy codedef raise_note(note):    """Raises a musical note by one key."""    # Dictionary to map note names to their corresponding semitones    semitones = {"C": 0, "C#": 1, "D": 2, "D#": 3, "E": 4, "F": 5, "F#": 6, "G": 7, "G#": 8, "A": 9, "A#": 10, "B": 11}    # Extract the base note name and octave number from the input note    base_note = note[:-1]    octave = int(note[-1])    # Calculate the new semitone value by adding one and wrapping around at 12    new_semitone = (semitones[base_note] + 1) % 12    # Look up the new note name from the dictionary    new_base_note = list(semitones.keys())[list(semitones.values()).index(new_semitone)]    # If the new note name is C, increment the octave number    if new_base_note == "C":        new_octave = octave + 1    else:        new_octave = octave    # Combine the new note name and octave number into a single string and return it    return new_base_note + str(new_octave)

To use the raise_note function, simply pass in a string representing a musical note in the format “NoteNameOctave”, such as “C4” for middle C. The function will return a new string representing the note raised by one key. For example:

pythonCopy code>>> raise_note("C4")'C#4'>>> raise_note("F#2")'G2'

번역결과

물론, 다음은 하나의 키로 음표를 높이는 Python의 예제 코드입니다.

pythonCopy code
def raise_note(note):
    """Raises a musical note by one key."""
    # Dictionary to map note names to their corresponding semitones
    semitones = {"C": 0, "C#": 1, "D": 2, "D#": 3, "E": 4, "F": 5, "F#": 6, "G": 7, "G#": 8, "A": 9, "A#": 10, "B": 11}

    # Extract the base note name and octave number from the input note
    base_note = note[:-1]
    octave = int(note[-1])

    # Calculate the new semitone value by adding one and wrapping around at 12
    new_semitone = (semitones[base_note] + 1) % 12

    # Look up the new note name from the dictionary
    new_base_note = list(semitones.keys())[list(semitones.values()).index(new_semitone)]

    # If the new note name is C, increment the octave number
    if new_base_note == "C":
        new_octave = octave + 1
    else:
        new_octave = octave

    # Combine the new note name and octave number into a single string and return it
    return new_base_note + str(new_octave)

raise_note 함수를 사용하려면 “NoteNameOctave” 형식의 음표를 나타내는 문자열을 전달하기만 하면 됩니다(예: 중간 C의 경우 “C4”). 이 함수는 1만큼 올라간 음표를 나타내는 새 문자열을 반환합니다. 열쇠. 예를 들어:

pythonCopy code
>>> raise_note("C4")
'C#4'
>>> raise_note("F#2")
'G2'

ChatGPT:


ChatGPT: To raise the pitch of a musical audio file in the WAV format, we can use the Python library pydub. Here’s an example code:

pythonCopy codefrom pydub import AudioSegmentdef raise_pitch(input_path, output_path, semitones):    """Raises the pitch of a WAV audio file by the specified number of semitones."""    # Load the audio file into an AudioSegment object    audio = AudioSegment.from_wav(input_path)    # Calculate the pitch shift ratio from the semitones value    pitch_ratio = 2 ** (semitones / 12)    # Apply the pitch shift using the pydub API    shifted = audio._spawn(audio.raw_data, overrides={"frame_rate": int(audio.frame_rate * pitch_ratio)})    shifted = shifted.set_frame_rate(audio.frame_rate)    # Export the shifted audio to the output file    shifted.export(output_path, format="wav")

The raise_pitch function takes three arguments: input_path is the path to the input audio file in the WAV format, output_path is the desired path for the output audio file, and semitones is the number of semitones to raise the pitch by. For example, semitones=1 would raise the pitch by one key. To use the function, simply call it with the appropriate arguments. For example:

pythonCopy coderaise_pitch("input.wav", "output.wav", 1)

This will load the audio from input.wav, raise the pitch by one key, and export the resulting audio to output.wav. Note that the output file will be in the same format as the input file (WAV). 번역결과

WAV 형식의 음악 오디오 파일의 피치를 높이려면 Python 라이브러리 pydub를 사용할 수 있습니다. 다음은 예제 코드입니다.

pythonCopy code
from pydub import AudioSegment

def raise_pitch(input_path, output_path, semitones):
    """Raises the pitch of a WAV audio file by the specified number of semitones."""
    # Load the audio file into an AudioSegment object
    audio = AudioSegment.from_wav(input_path)

    # Calculate the pitch shift ratio from the semitones value
    pitch_ratio = 2 ** (semitones / 12)

    # Apply the pitch shift using the pydub API
    shifted = audio._spawn(audio.raw_data, overrides={"frame_rate": int(audio.frame_rate * pitch_ratio)})
    shifted = shifted.set_frame_rate(audio.frame_rate)

    # Export the shifted audio to the output file
    shifted.export(output_path, format="wav")

‘raise_pitch’ 함수는 세 가지 인수를 사용합니다. ’input_path’는 WAV 형식의 입력 오디오 파일에 대한 경로이고, ’output_path’는 출력 오디오 파일에 대해 원하는 경로이며, ’semitones’는 소리를 올릴 반음의 수입니다. 피치. 예를 들어 ’반음=1’은 피치를 한 키 올립니다.

함수를 사용하려면 적절한 인수를 사용하여 호출하기만 하면 됩니다. 예를 들어:

pythonCopy code
raise_pitch("input.wav", "output.wav", 1)

이것은 input.wav에서 오디오를 로드하고 키를 한 단계 높이고 결과 오디오를 output.wav로 내보냅니다. 출력 파일은 입력 파일(WAV)과 동일한 형식입니다.


ChatGPT:


ChatGPT: Sure, here’s an example code for adding pitch adjustment (banding) to a rhythm game in Python:

pythonCopy codeimport pygamefrom pydub import AudioSegmentpygame.init()# Load the audio file into an AudioSegment objectaudio = AudioSegment.from_file("music.wav", format="wav")# Define the pitch adjustment range in semitonesmin_semitones = -2max_semitones = 2# Define the amount of pitch adjustment per key press in semitonespitch_step = 1# Define the initial pitch adjustment valuepitch_adjustment = 0# Create a Pygame mixer channel and load the audio into itchannel = pygame.mixer.Channel(0)sound = pygame.sndarray.make_sound(audio.get_array_of_samples())channel.queue(sound)# Define the game loopwhile True:    # Handle Pygame events    for event in pygame.event.get():        if event.type == pygame.KEYDOWN:            # Adjust the pitch up or down based on the pressed key            if event.key == pygame.K_UP:                pitch_adjustment = min(pitch_adjustment + pitch_step, max_semitones)            elif event.key == pygame.K_DOWN:                pitch_adjustment = max(pitch_adjustment - pitch_step, min_semitones)    # Calculate the current pitch shift ratio from the pitch adjustment value    pitch_ratio = 2 ** (pitch_adjustment / 12)    # Apply the pitch shift using the pydub API    shifted = audio._spawn(audio.raw_data, overrides={"frame_rate": int(audio.frame_rate * pitch_ratio)})    shifted = shifted.set_frame_rate(audio.frame_rate)    # Convert the shifted audio to a Pygame sound object and play it    shifted_sound = pygame.sndarray.make_sound(shifted.get_array_of_samples())    channel.queue(shifted_sound)

This code uses Pygame to handle keyboard events and play audio, and pydub to adjust the pitch of the audio in real time. The pitch adjustment range and step size can be customized by changing the min_semitones, max_semitones, and pitch_step variables. The initial pitch adjustment value is set to 0 by default. In the game loop, the code listens for keyboard events and adjusts the pitch up or down based on the pressed key. The pitch adjustment value is clamped to the specified range to prevent it from going out of bounds. Then, the current pitch shift ratio is calculated from the pitch adjustment value, and the audio is shifted using pydub. Finally, the shifted audio is converted to a Pygame sound object and played on a mixer channel. 번역결과

물론입니다. 다음은 Python의 리듬 게임에 피치 조정(밴딩)을 추가하는 예제 코드입니다.

pythonCopy code
import pygame
from pydub import AudioSegment

pygame.init()

# Load the audio file into an AudioSegment object
audio = AudioSegment.from_file("music.wav", format="wav")

# Define the pitch adjustment range in semitones
min_semitones = -2
max_semitones = 2

# Define the amount of pitch adjustment per key press in semitones
pitch_step = 1

# Define the initial pitch adjustment value
pitch_adjustment = 0

# Create a Pygame mixer channel and load the audio into it
channel = pygame.mixer.Channel(0)
sound = pygame.sndarray.make_sound(audio.get_array_of_samples())
channel.queue(sound)

# Define the game loop
while True:
    # Handle Pygame events
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            # Adjust the pitch up or down based on the pressed key
            if event.key == pygame.K_UP:
                pitch_adjustment = min(pitch_adjustment + pitch_step, max_semitones)
            elif event.key == pygame.K_DOWN:
                pitch_adjustment = max(pitch_adjustment - pitch_step, min_semitones)

    # Calculate the current pitch shift ratio from the pitch adjustment value
    pitch_ratio = 2 ** (pitch_adjustment / 12)

    # Apply the pitch shift using the pydub API
    shifted = audio._spawn(audio.raw_data, overrides={"frame_rate": int(audio.frame_rate * pitch_ratio)})
    shifted = shifted.set_frame_rate(audio.frame_rate)

    # Convert the shifted audio to a Pygame sound object and play it
    shifted_sound = pygame.sndarray.make_sound(shifted.get_array_of_samples())
    channel.queue(shifted_sound)

이 코드는 Pygame을 사용하여 키보드 이벤트를 처리하고 오디오를 재생하고 pydub를 사용하여 실시간으로 오디오 피치를 조정합니다. 피치 조정 범위와 단계 크기는 min_semitones, max_semitonespitch_step 변수를 변경하여 사용자 정의할 수 있습니다. 초기 피치 조정 값은 기본적으로 0으로 설정되어 있습니다.

게임 루프에서 코드는 키보드 이벤트를 수신하고 누른 키에 따라 피치를 위 또는 아래로 조정합니다. 피치 조정 값은 범위를 벗어나지 않도록 지정된 범위로 고정됩니다. 그런 다음 피치 조정 값에서 현재 피치 이동 비율을 계산하고 ’pydub’를 사용하여 오디오를 이동합니다. 마지막으로 이동된 오디오는 파이게임 사운드 객체로 변환되어 믹서 채널에서 재생됩니다.


ChatGPT:


ChatGPT: Yes, we can modify the previous code to allow more precise pitch adjustment when moving the mouse. Here’s an example code:

pythonCopy codeimport pygamefrom pydub import AudioSegmentpygame.init()# Load the audio file into an AudioSegment objectaudio = AudioSegment.from_file("music.wav", format="wav")# Define the pitch adjustment range in semitonesmin_semitones = -2max_semitones = 2# Define the amount of pitch adjustment per pixel movement of the mousepitch_step = 0.1# Define the initial pitch adjustment valuepitch_adjustment = 0# Create a Pygame mixer channel and load the audio into itchannel = pygame.mixer.Channel(0)sound = pygame.sndarray.make_sound(audio.get_array_of_samples())channel.queue(sound)# Define a function to calculate the pitch adjustment value from the mouse positiondef get_pitch_adjustment(mouse_pos):    # Calculate the distance between the mouse position and the center of the screen    center_x, center_y = pygame.display.get_surface().get_rect().center    dx = mouse_pos[0] - center_x    # Convert the distance to a pitch adjustment value using the pitch step size    pitch_adjustment = dx * pitch_step    # Clamp the pitch adjustment value to the specified range    pitch_adjustment = min(max(pitch_adjustment, min_semitones), max_semitones)    return pitch_adjustment# Define the game loopwhile True:    # Handle Pygame events    for event in pygame.event.get():        if event.type == pygame.QUIT:            pygame.quit()            exit()        elif event.type == pygame.MOUSEMOTION:            # Update the pitch adjustment value based on the mouse position            pitch_adjustment = get_pitch_adjustment(event.pos)        elif event.type == pygame.KEYDOWN:            # Adjust the pitch up or down based on the pressed key            if event.key == pygame.K_UP:                pitch_adjustment = min(pitch_adjustment + pitch_step, max_semitones)            elif event.key == pygame.K_DOWN:                pitch_adjustment = max(pitch_adjustment - pitch_step, min_semitones)    # Calculate the current pitch shift ratio from the pitch adjustment value    pitch_ratio = 2 ** (pitch_adjustment / 12)    # Apply the pitch shift using the pydub API    shifted = audio._spawn(audio.raw_data, overrides={"frame_rate": int(audio.frame_rate * pitch_ratio)})    shifted = shifted.set_frame_rate(audio.frame_rate)    # Convert the shifted audio to a Pygame sound object and play it    shifted_sound = pygame.sndarray.make_sound(shifted.get_array_of_samples())    channel.queue(shifted_sound)

In this code, we define a new get_pitch_adjustment function that calculates the pitch adjustment value based on the current mouse position. The function takes the mouse position as an argument and returns the pitch adjustment value. The distance between the mouse position and the center of the screen is calculated, and then converted to a pitch adjustment value using the pitch_step variable. The resulting pitch adjustment value is clamped to the specified range using min and max. In the game loop, we handle MOUSEMOTION events in addition to KEYDOWN events. When a MOUSEMOTION event occurs, we update the pitch adjustment value using the get_pitch_adjustment function and the mouse position from the event. When a KEYDOWN event occurs, we adjust the pitch as before. By combining keyboard and mouse input, we can provide more precise pitch adjustment control to the user 번역결과

예, 마우스를 움직일 때 더 정확한 피치 조정을 허용하도록 이전 코드를 수정할 수 있습니다. 다음은 예제 코드입니다.

pythonCopy code
import pygame
from pydub import AudioSegment

pygame.init()

# Load the audio file into an AudioSegment object
audio = AudioSegment.from_file("music.wav", format="wav")

# Define the pitch adjustment range in semitones
min_semitones = -2
max_semitones = 2

# Define the amount of pitch adjustment per pixel movement of the mouse
pitch_step = 0.1

# Define the initial pitch adjustment value
pitch_adjustment = 0

# Create a Pygame mixer channel and load the audio into it
channel = pygame.mixer.Channel(0)
sound = pygame.sndarray.make_sound(audio.get_array_of_samples())
channel.queue(sound)

# Define a function to calculate the pitch adjustment value from the mouse position
def get_pitch_adjustment(mouse_pos):
    # Calculate the distance between the mouse position and the center of the screen
    center_x, center_y = pygame.display.get_surface().get_rect().center
    dx = mouse_pos[0] - center_x

    # Convert the distance to a pitch adjustment value using the pitch step size
    pitch_adjustment = dx * pitch_step

    # Clamp the pitch adjustment value to the specified range
    pitch_adjustment = min(max(pitch_adjustment, min_semitones), max_semitones)

    return pitch_adjustment

# Define the game loop
while True:
    # Handle Pygame events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()
        elif event.type == pygame.MOUSEMOTION:
            # Update the pitch adjustment value based on the mouse position
            pitch_adjustment = get_pitch_adjustment(event.pos)
        elif event.type == pygame.KEYDOWN:
            # Adjust the pitch up or down based on the pressed key
            if event.key == pygame.K_UP:
                pitch_adjustment = min(pitch_adjustment + pitch_step, max_semitones)
            elif event.key == pygame.K_DOWN:
                pitch_adjustment = max(pitch_adjustment - pitch_step, min_semitones)

    # Calculate the current pitch shift ratio from the pitch adjustment value
    pitch_ratio = 2 ** (pitch_adjustment / 12)

    # Apply the pitch shift using the pydub API
    shifted = audio._spawn(audio.raw_data, overrides={"frame_rate": int(audio.frame_rate * pitch_ratio)})
    shifted = shifted.set_frame_rate(audio.frame_rate)

    # Convert the shifted audio to a Pygame sound object and play it
    shifted_sound = pygame.sndarray.make_sound(shifted.get_array_of_samples())
    channel.queue(shifted_sound)

이 코드에서는 현재 마우스 위치를 기준으로 피치 조정 값을 계산하는 새로운 get_pitch_adjustment 함수를 정의합니다. 이 함수는 마우스 위치를 인수로 받아 피치 조정 값을 반환합니다. 마우스 위치와 화면 중앙 사이의 거리를 계산한 후 pitch_step 변수를 사용하여 피치 조정 값으로 변환합니다. 결과 피치 조정 값은 ‘min’ 및 ’max’를 사용하여 지정된 범위로 고정됩니다.

게임 루프에서 KEYDOWN 이벤트 외에도 MOUSEMOTION 이벤트를 처리합니다. MOUSEMOTION 이벤트가 발생하면 get_pitch_adjustment 함수를 사용하여 피치 조정 값과 이벤트에서 마우스 위치를 업데이트합니다. KEYDOWN 이벤트가 발생하면 이전과 같이 피치를 조정합니다.

키보드와 마우스 입력을 결합하여 사용자에게 보다 정밀한 피치 조정 컨트롤을 제공할 수 있습니다.

profile
Entrepreneur FE 산체스입니다.

0개의 댓글