from machine import I2S, Pin
import network
import socket
import time

# Network Configuration
SSID = 'waoo2111280'
PASSWORD = 'waoo2111280'
SERVER_IP = '192.168.22.198'
SERVER_PORT = 12345

# I2S Configuration
SCK_PIN = 23  # Serial clock output
WS_PIN = 22   # Word clock output
SD_PIN = 21   # Serial data output

# Audio Configuration
SAMPLE_RATE = 16000
SAMPLE_BITS = 16     # Changed to 16-bit for better compatibility
CHANNELS = 1         # Mono channel
BUFFER_LENGTH = 2048 # Increased buffer size for better performance

def connect_wifi():
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    if not wlan.isconnected():
        print('Connecting to WiFi...')
        wlan.connect(SSID, PASSWORD)
        while not wlan.isconnected():
            time.sleep(1)
    print('WiFi Connected')
    print('IP Address:', wlan.ifconfig()[0])

def init_audio():
    audio_in = I2S(
        0,                      
        sck=Pin(SCK_PIN),
        ws=Pin(WS_PIN), 
        sd=Pin(SD_PIN),
        mode=I2S.RX,           
        bits=SAMPLE_BITS,      
        format=I2S.MONO,       # Changed to mono for simplicity
        rate=SAMPLE_RATE,      
        ibuf=BUFFER_LENGTH * 2 # Double buffer size
    )
    return audio_in

def main():
    connect_wifi()
    audio = init_audio()
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    audio_buf = bytearray(BUFFER_LENGTH)
    
    print('Starting audio capture and transmission...')
    
    try:
        while True:
            # Read audio data
            num_read = audio.readinto(audio_buf)
            if num_read > 0:
                # Send data in smaller chunks to prevent packet loss
                chunk_size = 1024
                for i in range(0, num_read, chunk_size):
                    chunk = audio_buf[i:min(i + chunk_size, num_read)]
                    sock.sendto(chunk, (SERVER_IP, SERVER_PORT))
            time.sleep_ms(1)
                
    except Exception as e:
        print('Error:', e)
    finally:
        audio.deinit()
        sock.close()

if __name__ == '__main__':
    main()
