Unity

사운드 감지하기 2

psb08 2025. 2. 20. 10:48
728x90

- Update 부분

private void Update()
{
    if (micClip == null) return;

마이크가 제대로 시작되지 않았으면 return.

 

    int micPosition = Microphone.GetPosition(micDevice) - sampleSize;
    if (micPosition < 0) return;

현재 마이크의 샘플 위치를 가져오고, sampleSize만큼 빼서 오디오 데이터를 가져올 위치를 설정.

 

micPosition이 0보다 작으면 유효하지 않으므로 return.

 

    float volumeDb = GetMicVolumeDb();
    volumeDb = Mathf.Clamp(volumeDb + 80f, 0f, 120f);

GetMicVolumeDb()를 호출해 현재 볼륨(dB) 가져옴.

 

데시벨 값이 음수일 수도 있으므로 +80f를 해서 0~120dB 범위로 조정.

 

    smoothedDb = Mathf.Lerp(smoothedDb, volumeDb, updateSpeed);

보간 함수(Lerp)를 사용해 데시벨 값을 부드럽게 조정.

 

    if (smoothedDb > 80f)
    {
        Debug.Log($"[경고] 높은 소리 감지: {smoothedDb:F2} dB");
    }

80dB 이상이면 Unity 콘솔에 경고 메시지 출력.

(70으로 수정)

 

    if (Time.time - lastUpdateTime >= updateInterval)
    {
        volumeText.text = $"소리 크기: <color=red>{smoothedDb:F2}</color> dB";
        lastUpdateTime = Time.time;
    }

일정 시간마다 UI 텍스트를 업데이트하여 현재 볼륨 표시.

 

    micClip.GetData(samples, micPosition);
    SmoothWaveform();
    DrawWaveform();
}

오디오 데이터를 samples 배열에 저장.

 

부드러운 파형 처리를 위한 SmoothWaveform() 호출.

 

파형을 그리기 위한 DrawWaveform() 호출.

 

 

- GetMicVolumeDb() 부분

private float GetMicVolumeDb()
{
    float[] samples = new float[sampleSize];
    int micPosition = Microphone.GetPosition(micDevice) - sampleSize;
    if (micPosition < 0) return 0f;

마이크 데이터 샘플을 저장할 배열 생성.

 

micPosition을 가져와 데이터가 유효한지 확인.

 

 

    micClip.GetData(samples, micPosition);
    float sum = 0f;
    for (int i = 0; i < sampleSize; i++)
    {
        sum += samples[i] * samples[i];
    }

micClip.GetData()를 사용해 샘플 데이터를 가져옴.

 

sum 변수에 샘플의 제곱값을 더함

(루트 평균 제곱, RMS 계산을 위해).

 

    float rms = Mathf.Sqrt(sum / sampleSize);
    float db = 20 * Mathf.Log10(rms);
    return db;
}

RMS(root mean square) 값을 계산.

 

RMS를 데시벨(dB) 단위로 변환 후 반환.

 

 

- SmoothWaveform() 부분

private void SmoothWaveform()
{
    for (int i = 0; i < sampleSize; i++)
    {
        smoothSamples[i] = Mathf.Lerp(smoothSamples[i], samples[i], updateSpeed);
    }
}

Lerp를 사용해 기존 smoothSamples 값과 현재 samples 값을 부드럽게 변화.

 

 

- DrawWaveform() 부분

private void DrawWaveform()
{
    float scaleX = waveformWidth / sampleSize;

X축을 waveformWidth에 맞게 샘플 수만큼 나눠서 스케일 조정.

 

    for (int i = 0; i < sampleSize; i++)
    {
        float x = i * scaleX - (waveformWidth / 2);
        float y = smoothSamples[i] * waveformHeight;
        lineRenderer.SetPosition(i, new Vector3(x, y, 0));
    }
}

LineRenderer를 사용해 오디오 데이터를 기반으로 파형을 그림.


솔직히 이번 글이 더 길었던 것 같지만 그냥 끝까지 작성하기로 했습니다.

 

테스트 영상입니다. 70 DB 이상일 시 Debug가 찍히는 모습을 볼 수 있습니다.

728x90