2016-10-06 3 views
0

저는 python 서버에 pcm 데이터를 보내는 응용 프로그램을 개발하려고합니다.안드로이드에서 파이썬 서버까지 시간 길이에 프레임 패킷 어떻게?

AudioRecord 라이브러리를 사용하여 실시간 오디오 신호를 얻었습니다.

그리고 이것은 소스 코드입니다.

/*------ setting audio recording ------*/ 

private static final int SAMPLE_RATE = 44100; 
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO; 
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 

private boolean isRecording = true; 
private AudioRecord recorder = null; 
private Thread recordingThread; 
private AudioTrack player; 
//byte[] TotalByteMessage; 

/*------ about socket communication ------*/ 
public DatagramSocket socket; 
private int port = 7979; 
String IP = "192.168.0.4"; 



/*------ Recording, Playing and Sending packets method ------*/ 

private void startStreaming() { 

    recordingThread = new Thread(new Runnable() { 
     @Override 
     public void run() { 

      android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); 

      try { 
       /*------about socket------*/ 
       socket = new DatagramSocket(); 
       Log.d(LOG_NW, "Socket Created!"); 
       DatagramPacket packet; 

       InetAddress destination = InetAddress.getByName(IP); 
       Log.d(LOG_NW, "Address retrieved!"); 


       /*------setting recording && playing------*/ 
       //get MinBufferSize for audio recording 
       int Buffer_Size = AudioRecord.getMinBufferSize(SAMPLE_RATE, 
         RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING); 
       Log.d(LOG_Audio, "Min buffer size is " + Buffer_Size); 

       if (Buffer_Size == AudioRecord.ERROR || Buffer_Size == AudioRecord.ERROR_BAD_VALUE) { 
        Buffer_Size = SAMPLE_RATE * 2; 
       } 


       recorder = new AudioRecord(MediaRecorder.AudioSource.VOICE_RECOGNITION, 
         SAMPLE_RATE, RECORDER_CHANNELS, 
         RECORDER_AUDIO_ENCODING, Buffer_Size); 

       if (recorder.getState() != AudioRecord.STATE_INITIALIZED) { 
        Log.d(LOG_Audio, "Audio Record can't initialize!"); 
        return; 
       } 


       player = new AudioTrack(AudioManager.STREAM_MUSIC, 
         SAMPLE_RATE, AudioFormat.CHANNEL_OUT_MONO, 
         RECORDER_AUDIO_ENCODING, Buffer_Size, 
         AudioTrack.MODE_STREAM); 
       Log.d(LOG_Audio, "ready for playing music by using audiotrack"); 

       player.setPlaybackRate(SAMPLE_RATE); 

       byte[] audioBuffer = new byte[Buffer_Size]; 
       Log.d(LOG_Audio, "AudioBuffer created of size " + Buffer_Size); 

       recorder.startRecording(); 
       Log.d(LOG_Audio, "Start Recording!"); 

       player.play(); 
       Log.d(LOG_Audio, "Start Playing!"); 


       while (isRecording == true) { 
        //reading data from MIC into buffer 
        recorder.read(audioBuffer, 0, audioBuffer.length); 
        player.write(audioBuffer, 0, audioBuffer.length); 


        //putting buffer in the packet 
        packet = new DatagramPacket(audioBuffer, audioBuffer.length, destination, port); 

        socket.send(packet); 
        Log.d(LOG_NW, "packet sending to " + destination + " with port : " + port); 

       } 

      } catch (UnknownHostException e) { 
       Log.d(LOG_Audio, "UnknownHostException"); 
      } catch (IOException e) { 
       Log.d(LOG_Audio, "IOException"); 
      } 
     } 
    }); // end of recordingThread 

    recordingThread.start(); 
} 

는 이것은 파이썬 서버 코드입니다.

import socket  
import numpy as np 
import matplotlib.pyplot as plt 

IP = "192.168.0.4" 
server_address = (IP, 7979) 
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 
buffer_size = 3584 
server.bind(server_address) 

i = True 
while(i): 
    print "Listening...\n" 
    packet, client = server.recvfrom(buffer_size) 
    #Convert packet to numpy array 
    signal = np.fromstring(packet, dtype=np.int16)  
    i=False 
server.close() 

이 파이썬 코드로는 하나의 패킷 만 수신합니다.

하지만 나중에 여러 패킷을 수신하도록 목록을 작성합니다.

윈도우 화와 FFT (Fast Fourier Transform)를 위해 64ms (시간!)의 크기를 가진 프레임을 만들고 싶지만 패킷은 3584 바이트입니다.

그래서 저는 파이썬 서버에서 안드로이드의 바이트 패킷으로 윈도우 화와 fft를하는 법을 모릅니다.

시간 길이를 사용하여 프레임을 만들려면 어떻게해야합니까?

+0

패킷이 3584 바이트입니다. FFT가 왜 문제가됩니까? 패킷 길이를 2의 제곱으로할까요? 그리고 패딩과 테이퍼링을 통해이를 달성하기를 원하십니까? 그게 windowing에 관한 것입니까? 모든 질문에 대해 유감스럽게 생각하지만 정확히 어떤 문제인지 모르겠습니다. –

+0

의견을 보내 주셔서 감사합니다. 이제 패킷 하나만 받았습니다. 그러나 windowing 및 fft를 수행하는 데 더 많은 패킷을 수신하려고합니다. 문제는 내가 64ms 길이의 프레임이 있어야한다고 생각하지만, 나는 3584 바이트 길이의 패킷을 가지고있다. 그래서 나는 windowing을 수행하는 방법을 모른다. –

답변

0

당신은 i == True 이후, 다음 하나의 반복을 통해 이동하여 파이썬 코드

i = True 
while(i): 
    print "Listening...\n" 
    packet, client = server.recvfrom(buffer_size) 

    #Convert packet to numpy array 
    signal = np.fromstring(packet, dtype=np.int16)  

    i=False 
server.close() 

이 루프가됩니다에 while 루프에 문제가 있고, 첫 번째 반복의 끝에서 i = False을 설정하는 루프가 완료됩니다.

+0

예, 패킷을 받고 싶습니다. 내 코드를 수정 한 후 (목록에서 패킷을 계속 수신함), 64ms 동안 패킷을 어떻게 조각 낼 수 있습니까 ?? –