क्या लिनक्स "aplay" के बराबर एक विंडोज है जो एक बिटस्ट्रीम और आउटपुट ऑडियो को स्वीकार करेगा?


3

मैं कोड गोल्फ और चिपट्यून्स के बारे में एक कंप्यूटरफाइल वीडियो देख रहा था और प्रदान किए गए उदाहरण कोड को चलाने में रुचि रखता था , लेकिन यह निर्भर करता है aplay, ALSA साउंड कार्ड ड्राइवर के लिए लिनक्स उपयोगिता, और मैं विंडोज 7 पर इसे चलाना चाहता हूं। विंडोज 7+ पर एक समान कार्यक्रम या उपयोगिता (अधिमानतः लेकिन जरूरी नहीं कि ओएस प्रदान की गई) जो बाइट्स की एक धारा लेगा और इसे ऑडियो स्ट्रीम में बदल देगा?

जवाबों:


0

वही :)

मैंने पाया कि आप इसे बदलने के लिए ffmpeg का उपयोग कर सकते हैं

ffmpeg -f u8 -i music.raw music.wav

फिर आप इसे खेलना पसंद करें

अब, मैंने इसे सीधे पाइप करने की कोशिश की (vlc stdin पर इनपुट की अनुमति देता है, लेकिन यह कच्चा डेटा नहीं पढ़ेगा, कम से कम तर्कों के बिना नहीं, मुझे यकीन नहीं है कि यह कैसे देना है)

music.exe | ffmpeg ... -i pipe:1 | vlc.exe -

लेकिन ffmpeg ने कहा कि पाइप में पर्याप्त जगह नहीं थी (मैंने पाइप की कोशिश की: 0 और साथ ही साथ मैं 100% सुनिश्चित नहीं था कि यह खिड़कियों पर स्टड के लिए हो ...)

इसलिए मैंने एक छोटे समय के लिए Music.raw फ़ाइल में संगीत। रीडायरेक्ट को समाप्त कर दिया ( music.exe > music.raw) तब मैं इसे ffmpeg से vlc पर सीधे पाइप करने के लिए उपयोग कर सकता था

ffmpeg.exe -f u8 -i music.raw -f wav pipe:1 | vlc.exe -

यह किसी भी उत्तर के रूप में अच्छा है, इसलिए मैं इसे चिह्नित करूंगा। मुझे लगता है कि असली जवाब यह है कि विंडोज़ पर कोई अच्छा प्रत्यक्ष पाइप समाधान नहीं है
केन बेलोज़

मैं तुम्हारा पर इस टिप्पणी करना चाहते हैं, लेकिन मैं 50 प्रतिनिधि :) की जरूरत नहीं है unix.stackexchange.com/questions/205107/... इसलिए जब आदेश थोड़ा अधिक हो सकता है मैं एक गूगल खोज के साथ ऊपर पाए ./a | aplay, तो आप फ़ाइल को सहेजे बिना सैद्धांतिक रूप से ऐसा कर सकता था। फिर आप कमांड को
मेकफाइल

SoX से play.exe का उपयोग करने के साथ मुझे जो मुख्य समस्या मिली है, वह यह है कि इसमें विंडोज साउंड ड्राइवरों के साथ एक कठिन समय अंतराल है। शायद मैं सिर्फ SoX के बारे में पर्याप्त नहीं जानता, लेकिन मुझे अभी तक पता नहीं चला है कि कैसे play.exe पाने के लिए सिर्फ एक त्रुटि फेंकने के बिना काम करने के लिए
Ken Bellows

hm, मुझे जो डाउनलोड sox के लिए मिला वह वास्तव में play.exe नहीं था, लेकिन मैंने पाया कि आप फ़ाइल के बजाय "-t -waveaudio डिफ़ॉल्ट" का आउटपुट निर्दिष्ट कर सकते हैं। btw, अगर आप रुचि रखते हैं, तो मैंने इसे ड्रॉपबॉक्स पर फेंक दिया: dropbox.com/sh/ibb924waxkqga04/AAAa3yxp_lf7_awM2eY30bPqa?dl0
FreeER

1
मुझे अभी पता चला है कि यह वास्तव में ffmpeg के साथ काम करता है यदि आप एक पाइप नंबर निर्दिष्ट नहीं करते हैं। बस टाइप करें a.exe | ffmpeg.exe -ar 8000 -f u8 -i pipe: -f wav pipe: | vlc.exe -और आपको जाना अच्छा होना चाहिए। विकल्प -arनमूना दर 8000 हर्ट्ज पर सेट करता है। डिफ़ॉल्ट रूप से ffmpeg 44100 हर्ट्ज का उपयोग करता है।
maddin45

3

मैंने ठीक उसी वीडियो को देखा और बहुत निराश था कि मुझे इस उदाहरण में aplay की तरह व्यवहार करने वाली खिड़कियों के लिए कोई प्रोग्राम नहीं मिला।

अंत में, मैंने खुद को C ++ और OpenAL का उपयोग करके लिखा । मैं नीचे दिए गए कोड को पोस्ट करूंगा। निष्पादन योग्य बनाने के लिए आपको OpenAL लाइब्रेरी से लिंक करना होगा। लाइब्रेरी ओपन कोर एसडीके का हिस्सा है जिसे आप उनकी वेबसाइट से डाउनलोड कर सकते हैं।

यदि आप केवल निष्पादन योग्य चाहते हैं, तो आप इसे यहां डाउनलोड कर सकते हैं । के लिए देखो yalpa.exe

वाक्य - विन्यास

मान लीजिए कि आप मेरे निष्पादन योग्य का उपयोग करते हैं yalpa.exe। तब आप अपने कच्चे ऑडियो डेटा को यल्पा में पाइप करके संसाधित कर सकते हैं:

a.exe | yalpa.exe

वैकल्पिक रूप से आप पहले ऑडियो डेटा को एक फाइल में लिख सकते हैं और उस फाइल को याल्पा के स्टड पर पास कर सकते हैं:

yalpa.exe < my_audio.raw

नोट: yalpa cmd में काम करता है, लेकिन PowerShell में नहीं। पाइप्स को वहां अलग तरह से संभाला जाने लगता है (देखें इससे संबंधित SO प्रश्न )।

कोड:

अस्वीकरण: मैं गारंटी नहीं दे सकता कि यह कोड 100% बग-मुक्त है, लेकिन मैंने इसे क्रमशः विंडोज 7 और विंडोज 10 के साथ दो अलग-अलग मशीनों पर परीक्षण किया। यह विजुअल स्टूडियो 2013 कंपाइलर का उपयोग करके संकलित और जुड़ा हुआ था। मैं इसे Cygwin पर g ++ का उपयोग करके भी संकलित करने में सक्षम था, लेकिन पल्सीडियो के साथ समस्याओं के कारण OpenAL रनटाइम में विफल रहा।

मेरे कोड को संपादित करने और उसका उपयोग करने के लिए स्वतंत्र महसूस करें।

#include <iostream>
#include <cstdio>
#include <cstdint>
#include <thread>
#include <chrono>

#if defined _WIN32
#include <al.h>
#include <alc.h>
#include <io.h>
#include <fcntl.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif

#if 0 || defined _DEBUG
#define AL_CHECK_ERROR(msg) (checkALError(msg))
#else
#define AL_CHECK_ERROR(msg)
#endif

const uint8_t numBuf = 3;
const ALsizei bufSize = 1000;
const ALenum format = AL_FORMAT_MONO8;
const ALsizei freq = 8000;
char readBuf[bufSize]; 

void checkALError(const char * msg)
{
    while (ALuint err = alGetError() != AL_NO_ERROR)
        std::cerr << "Caught AL Error at " << msg << ": " << err << "\n";
}

ALsizei fillBufferFromStdin(ALuint buf)
{
    // read
    const ALsizei bytesRead = (ALsizei) fread(readBuf, sizeof(uint8_t), bufSize, stdin);
    // copy to OpenAL buffer
    alBufferData(buf, format, (void *) readBuf, bytesRead, freq);
    AL_CHECK_ERROR("buffer data");
    return bytesRead;
}

void updateBuffers(ALuint src, ALuint bufs[numBuf])
{
    ALint srcState;
    do
    {
        // wait until a buffer is free
        ALint val = 0;
        do 
        {
            alGetSourcei(src, AL_BUFFERS_PROCESSED, &val);
            AL_CHECK_ERROR("get num processed");
            if (val > 0) break;
            // sleep for a quarter of the duration a buffer plays
            std::this_thread::sleep_for(std::chrono::milliseconds((bufSize / freq) * 1000 / 4));
        } while (true);
        while (val--)
        {
            // remove oldest buffer from queue and get its id
            ALuint buf;
            alSourceUnqueueBuffers(src, 1, &buf);
            AL_CHECK_ERROR("unqueue buffer");
            // fill buffer
            const ALsizei bytesRead = fillBufferFromStdin(buf);
            // add buffer to queue
            alSourceQueueBuffers(src, 1, &buf);
            AL_CHECK_ERROR("queue buffer");
            // if end of stdin was reached, return
            if (bytesRead < bufSize) return;
        }
        // check if source is still playing
        alGetSourcei(src, AL_SOURCE_STATE, &srcState);
    } while (AL_PLAYING == srcState);
}

int main(int argc, char * argv[])
{
    std::cout << "OpenAL test project\n";
    // set stdin to binary mode
#ifdef _WIN32
    _setmode(_fileno(stdin), _O_BINARY);
#else
    freopen(nullptr, "rb", stdin);
#endif

    // initialization: open default device
    ALCdevice * dev = alcOpenDevice(nullptr);
    // reset error state
    AL_CHECK_ERROR("open device");
    // create a context
    ALCcontext * context = alcCreateContext(dev, nullptr);
    AL_CHECK_ERROR("create context");
    alcMakeContextCurrent(context);
    AL_CHECK_ERROR("activate context");
    // create buffers for audio streaming
    ALuint bufs[numBuf];
    alGenBuffers(numBuf, bufs);
    AL_CHECK_ERROR("create buffer");
    // create source to play buffer
    ALuint src;
    alGenSources(1, &src);
    AL_CHECK_ERROR("create source");

    // initially fill buffers
    for (uint8_t i = 0; i < numBuf; ++i) fillBufferFromStdin(bufs[i]);
    alSourceQueueBuffers(src, numBuf, bufs);
    AL_CHECK_ERROR("queue buffer");
    // play source
    alSourcePlay(src);
    AL_CHECK_ERROR("play");
    // fill buffers in loop
    updateBuffers(src, bufs);
    // when stream is read completely, wait until source stops playing
    ALint srcState;
    do
    {
        alGetSourcei(src, AL_SOURCE_STATE, &srcState);
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    } while (AL_PLAYING == srcState);


    // delete source
    alDeleteSources(1, &src);
    AL_CHECK_ERROR("delete source");
    // delete buffers
    alDeleteBuffers(numBuf, bufs);
    AL_CHECK_ERROR("delete buffer");
    // destroy context
    alcDestroyContext(context);
    AL_CHECK_ERROR("destroy context");
    // close device
    alcCloseDevice(dev);
    AL_CHECK_ERROR("close device");

    std::cout << "Exiting\n";
    return 0;
}

1

Vlc और कुछ कमांड-लाइन तर्कों का उपयोग करके मैं इंटरनेट से कॉपी-पेस्ट करता हूँ जो आप विंडोज़ पर aplay की कार्यक्षमता को फिर से बनाने में सक्षम हैं।

audio.exe | vlc --demux=rawaud --rawaud-channels 2 --rawaud-samplerate 8000 -

क्रेडिट को इस पोस्ट और फ़्रीयर के उत्तर पर जाना चाहिए ।


बिटस्ट्रीम स्रोत पैरामीटर कहाँ है?
nicolay.anykienko

0

पोस्टरिटी के लिए: ऐसा लगता है कि वास्तव में एक अच्छा समाधान नहीं है, लेकिन एक और अनुमानित-पर्याप्त है जो मुझे मिला। एक .wav फ़ाइल बनाने के लिए निम्नलिखित विकल्पों के साथ SoX का उपयोग करना था :

./a.exe | sox -t raw -b 16 -e signed -r 8000 - test.wav

यह बहुत जल्दी एक बहुत बड़ी फ़ाइल बनाता है, इसलिए इसे बहुत लंबे समय तक न चलने दें। मेरी मशीन पर लगभग 10 सेकंड (Intel i7 3.4GHz प्रोसेसर) ने लगभग 2hrs का ऑडियो (~ 125KB) उत्पन्न किया।


Sox को जाने बिना, आप इसे आउटपुट पर बता सकते हैं कि आउटपुट को कई बाइट्स तक सीमित stdoutकरने के head -c <bytes>लिए इसे पाइप करें । samples/second × bytes/channel/sample × channels × seconds = bytes। आप शीर्ष लेख के कारण कुछ नमूने खो देंगे, लेकिन यह एक त्वरित और गंदा तरीका है। अन्यथा, soxएक कमांड है जो आपको एक इनपुट ट्रिम sox <options> - test.wav trim 0 60करने देगा : मतलब यह 0 सेकंड को छोड़ देगा और इनपुट से 60 सेकंड लेगा।
13-13 को 13
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.