mirror of
https://github.com/go-gst/go-gst.git
synced 2025-10-12 03:10:13 +08:00
142 lines
8.6 KiB
Go
142 lines
8.6 KiB
Go
package audio
|
||
|
||
/*
|
||
#include "gst.go.h"
|
||
*/
|
||
import "C"
|
||
import (
|
||
"math"
|
||
"strings"
|
||
"unsafe"
|
||
)
|
||
|
||
// GetFallbackChannelMask gets the fallback channel-mask for the given number of channels.
|
||
func GetFallbackChannelMask(channels int) uint64 {
|
||
return uint64(C.gst_audio_channel_get_fallback_mask(C.gint(channels)))
|
||
}
|
||
|
||
// ChannelPositionsFromMask converts the channels present in mask to a position array (which
|
||
// should have at least channels entries ensured by caller). If mask is set to 0, it is considered
|
||
// as 'not present' for purpose of conversion. A partially valid mask with less bits set than the
|
||
// number of channels is considered valid. This function returns nil if the arguments are invalid.
|
||
func ChannelPositionsFromMask(channels int, mask uint64) []ChannelPosition {
|
||
var out C.GstAudioChannelPosition
|
||
ret := C.gst_audio_channel_positions_from_mask(C.gint(channels), C.guint64(mask), &out)
|
||
if !gobool(ret) {
|
||
return nil
|
||
}
|
||
outsl := make([]ChannelPosition, channels)
|
||
tmp := (*[(math.MaxInt32 - 1) / unsafe.Sizeof(C.GST_AUDIO_CHANNEL_POSITION_NONE)]C.GstAudioChannelPosition)(unsafe.Pointer(&out))[:channels:channels]
|
||
for i, s := range tmp {
|
||
outsl[i] = ChannelPosition(s)
|
||
}
|
||
return outsl
|
||
}
|
||
|
||
// ChannelPositionsToMask converts the given channel positions to a bitmask. If forceOrder is true
|
||
// it additionally checks the channels in the order required by GStreamer.
|
||
func ChannelPositionsToMask(positions []ChannelPosition, forceOrder bool) (mask uint64, ok bool) {
|
||
var out C.guint64
|
||
ok = gobool(C.gst_audio_channel_positions_to_mask(
|
||
(*C.GstAudioChannelPosition)(unsafe.Pointer(&positions[0])),
|
||
C.gint(len(positions)),
|
||
gboolean(forceOrder),
|
||
&out,
|
||
))
|
||
if ok {
|
||
mask = uint64(out)
|
||
}
|
||
return
|
||
}
|
||
|
||
// ChannelPositionsToString converts the given positions into a human-readable string.
|
||
func ChannelPositionsToString(positions []ChannelPosition) string {
|
||
ret := C.gst_audio_channel_positions_to_string(
|
||
(*C.GstAudioChannelPosition)(unsafe.Pointer(&positions[0])),
|
||
C.gint(len(positions)),
|
||
)
|
||
defer C.g_free((C.gpointer)(unsafe.Pointer(ret)))
|
||
return C.GoString(ret)
|
||
}
|
||
|
||
// ChannelPositionsToValidOrder reorders the given positions from any order to the GStreamer order.
|
||
func ChannelPositionsToValidOrder(positions []ChannelPosition) (ok bool) {
|
||
ok = gobool(C.gst_audio_channel_positions_to_valid_order(
|
||
(*C.GstAudioChannelPosition)(unsafe.Pointer(&positions[0])),
|
||
C.gint(len(positions)),
|
||
))
|
||
return
|
||
}
|
||
|
||
// AreValidChannelPositions checks if the positions are all valid. If forceOrder is true, it also checks
|
||
// if they are in the order required by GStreamer.
|
||
func AreValidChannelPositions(positions []ChannelPosition, forceOrder bool) bool {
|
||
return gobool(C.gst_audio_check_valid_channel_positions(
|
||
(*C.GstAudioChannelPosition)(unsafe.Pointer(&positions[0])),
|
||
C.gint(len(positions)),
|
||
gboolean(forceOrder),
|
||
))
|
||
}
|
||
|
||
// ChannelPosition represents audio channel positions.
|
||
//
|
||
// These are the channels defined in SMPTE 2036-2-2008 Table 1 for 22.2 audio systems with the
|
||
// Surround and Wide channels from DTS Coherent Acoustics (v.1.3.1) and 10.2 and 7.1 layouts.
|
||
// In the caps the actual channel layout is expressed with a channel count and a channel mask,
|
||
// which describes the existing channels. The positions in the bit mask correspond to the enum
|
||
// values. For negotiation it is allowed to have more bits set in the channel mask than the
|
||
// number of channels to specify the allowed channel positions but this is not allowed in negotiated
|
||
// caps. It is not allowed in any situation other than the one mentioned below to have less
|
||
// bits set in the channel mask than the number of channels.
|
||
//
|
||
// ChannelPositionMono can only be used with a single mono channel that has no direction information
|
||
// and would be mixed into all directional channels. This is expressed in caps by having a single
|
||
// channel and no channel mask.
|
||
//
|
||
// ChannelPositionNone can only be used if all channels have this position. This is expressed in caps
|
||
// by having a channel mask with no bits set.
|
||
//
|
||
// As another special case it is allowed to have two channels without a channel mask. This implicitly
|
||
// means that this is a stereo stream with a front left and front right channel.
|
||
type ChannelPosition int
|
||
|
||
// ChannelPosition castings
|
||
const (
|
||
ChannelPositionNone ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_NONE // (-3) – used for position-less channels, e.g. from a sound card that records 1024 channels; mutually exclusive with any other channel position
|
||
ChannelPositionMono ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_MONO // (-2) – Mono without direction; can only be used with 1 channel
|
||
ChannelPositionInvalid ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_INVALID // (-1) – invalid position
|
||
ChannelPositionFrontLeft ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT // (0) – Front left
|
||
ChannelPositionFrontRight ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT // (1) – Front right
|
||
ChannelPositionFrontCenter ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER // (2) – Front center
|
||
ChannelPositionLFE1 ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_LFE1 // (3) – Low-frequency effects 1 (subwoofer)
|
||
ChannelPositionRearLeft ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_REAR_LEFT // (4) – Rear left
|
||
ChannelPositionRearRight ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT // (5) – Rear right
|
||
ChannelPositionFrontLeftOfCenter ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER // (6) – Front left of center
|
||
ChannelPositionFrontRightOfCenter ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER // (7) – Front right of center
|
||
ChannelPositionRearCenter ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_REAR_CENTER // (8) – Rear center
|
||
ChannelPositionLFE2 ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_LFE2 // (9) – Low-frequency effects 2 (subwoofer)
|
||
ChannelPositionSideLeft ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT // (10) – Side left
|
||
ChannelPositionSideRight ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT // (11) – Side right
|
||
ChannelPositionTopFrontLeft ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT // (12) – Top front left
|
||
ChannelPositionTopFrontRight ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT // (13) – Top front right
|
||
ChannelPositionTopFrontCenter ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER // (14) – Top front center
|
||
ChannelPositionTopCenter ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_TOP_CENTER // (15) – Top center
|
||
ChannelPositionTopRearLeft ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT // (16) – Top rear left
|
||
ChannelPositionTopRearRight ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT // (17) – Top rear right
|
||
ChannelPositionTopSideLeft ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_LEFT // (18) – Top side right
|
||
ChannelPositionTopSideRight ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_TOP_SIDE_RIGHT // (19) – Top rear right
|
||
ChannelPositionTopRearCenter ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER // (20) – Top rear center
|
||
ChannelPositionBottomFrontCenter ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_CENTER // (21) – Bottom front center
|
||
ChannelPositionBottomFrontLeft ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_LEFT // (22) – Bottom front left
|
||
ChannelPositionBottomFrontRight ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_BOTTOM_FRONT_RIGHT // (23) – Bottom front right
|
||
ChannelPositionWideLeft ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_WIDE_LEFT // (24) – Wide left (between front left and side left)
|
||
ChannelPositionWideRight ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_WIDE_RIGHT // (25) – Wide right (between front right and side right)
|
||
ChannelPositionSurroundLeft ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT // (26) – Surround left (between rear left and side left)
|
||
ChannelPositionSurroundRight ChannelPosition = C.GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT // (27) – Surround right (between rear right and side right)
|
||
)
|
||
|
||
func (c ChannelPosition) String() string {
|
||
// ugly hack
|
||
return strings.TrimSuffix(strings.TrimPrefix(ChannelPositionsToString([]ChannelPosition{c}), "[ "), " ]")
|
||
}
|